Blame src/applet-device-broadband.c

Packit Service 639700
// SPDX-License-Identifier: GPL-2.0+
Packit fabffb
/* NetworkManager Applet -- allow user control over networking
Packit fabffb
 *
Packit fabffb
 * (C) Copyright 2012 Aleksander Morgado <aleksander@gnu.org>
Packit fabffb
 */
Packit fabffb
Packit fabffb
#include "nm-default.h"
Packit fabffb
Packit fabffb
#include <ctype.h>
Packit fabffb
Packit fabffb
#include <NetworkManager.h>
Packit fabffb
Packit fabffb
#include "applet.h"
Packit fabffb
#include "applet-device-broadband.h"
Packit fabffb
#include "applet-dialogs.h"
Packit fabffb
#include "mobile-helpers.h"
Packit fabffb
#include "mb-menu-item.h"
Packit fabffb
Packit fabffb
#define BROADBAND_INFO_TAG "devinfo"
Packit fabffb
Packit fabffb
typedef struct {
Packit fabffb
	NMApplet *applet;
Packit fabffb
	NMDevice *device;
Packit fabffb
Packit fabffb
	MMObject     *mm_object;
Packit fabffb
	MMModem      *mm_modem;
Packit fabffb
	MMModem3gpp  *mm_modem_3gpp;
Packit fabffb
	MMModemCdma  *mm_modem_cdma;
Packit fabffb
	MMSim        *mm_sim;
Packit fabffb
Packit fabffb
	/* Operator info */
Packit fabffb
	gchar *operator_name;
Packit fabffb
	guint operator_name_update_id;
Packit fabffb
	guint operator_code_update_id;
Packit fabffb
	guint sid_update_id;
Packit fabffb
	NMAMobileProvidersDatabase *mpd;
Packit fabffb
Packit fabffb
	/* Unlock dialog stuff */
Packit fabffb
	GtkWidget *dialog;
Packit fabffb
	GCancellable *cancellable;
Packit fabffb
} BroadbandDeviceInfo;
Packit fabffb
Packit fabffb
/********************************************************************/
Packit fabffb
Packit fabffb
static gboolean
Packit fabffb
new_auto_connection (NMDevice *device,
Packit fabffb
                     gpointer dclass_data,
Packit fabffb
                     AppletNewAutoConnectionCallback callback,
Packit fabffb
                     gpointer callback_data)
Packit fabffb
{
Packit fabffb
	return mobile_helper_wizard (nm_device_modem_get_current_capabilities (NM_DEVICE_MODEM (device)),
Packit fabffb
	                             callback,
Packit fabffb
	                             callback_data);
Packit fabffb
}
Packit fabffb
Packit fabffb
/********************************************************************/
Packit fabffb
Packit fabffb
typedef struct {
Packit fabffb
	NMApplet *applet;
Packit fabffb
	NMDevice *device;
Packit fabffb
} ConnectNetworkInfo;
Packit fabffb
Packit fabffb
static void
Packit fabffb
add_and_activate_connection_done (GObject *client,
Packit fabffb
                                  GAsyncResult *result,
Packit fabffb
                                  gpointer user_data)
Packit fabffb
{
Packit fabffb
	GError *error = NULL;
Packit fabffb
Packit fabffb
	if (!nm_client_add_and_activate_connection_finish (NM_CLIENT (client), result, &error)) {
Packit fabffb
		g_warning ("Failed to add/activate connection: (%d) %s", error->code, error->message);
Packit fabffb
		g_error_free (error);
Packit fabffb
	}
Packit fabffb
}
Packit fabffb
Packit fabffb
static void
Packit fabffb
wizard_done (NMConnection *connection,
Packit fabffb
             gboolean auto_created,
Packit fabffb
             gboolean canceled,
Packit fabffb
             gpointer user_data)
Packit fabffb
{
Packit fabffb
	ConnectNetworkInfo *info = user_data;
Packit fabffb
Packit fabffb
	if (canceled == FALSE) {
Packit fabffb
		g_return_if_fail (connection != NULL);
Packit fabffb
Packit fabffb
		/* Ask NM to add the new connection and activate it; NM will fill in the
Packit fabffb
		 * missing details based on the specific object and the device.
Packit fabffb
		 */
Packit fabffb
		nm_client_add_and_activate_connection_async (info->applet->nm_client,
Packit fabffb
		                                             connection,
Packit fabffb
		                                             info->device,
Packit fabffb
		                                             "/",
Packit fabffb
		                                             NULL,
Packit fabffb
		                                             add_and_activate_connection_done,
Packit fabffb
		                                             info->applet);
Packit fabffb
	}
Packit fabffb
Packit fabffb
	g_object_unref (info->device);
Packit fabffb
	g_free (info);
Packit fabffb
}
Packit fabffb
Packit fabffb
void
Packit fabffb
applet_broadband_connect_network (NMApplet *applet,
Packit fabffb
                                  NMDevice *device)
Packit fabffb
{
Packit fabffb
	ConnectNetworkInfo *info;
Packit fabffb
Packit fabffb
	info = g_malloc0 (sizeof (*info));
Packit fabffb
	info->applet = applet;
Packit fabffb
	info->device = g_object_ref (device);
Packit fabffb
Packit fabffb
	if (!mobile_helper_wizard (nm_device_modem_get_current_capabilities (NM_DEVICE_MODEM (device)),
Packit fabffb
	                           wizard_done,
Packit fabffb
	                           info)) {
Packit fabffb
		g_warning ("Couldn't run mobile wizard for broadband device");
Packit fabffb
		g_object_unref (info->device);
Packit fabffb
		g_free (info);
Packit fabffb
	}
Packit fabffb
}
Packit fabffb
Packit fabffb
/********************************************************************/
Packit fabffb
Packit fabffb
static void unlock_dialog_new (NMDevice *device,
Packit fabffb
                               BroadbandDeviceInfo *info);
Packit fabffb
Packit fabffb
static void
Packit fabffb
unlock_dialog_destroy (BroadbandDeviceInfo *info)
Packit fabffb
{
Packit fabffb
	gtk_widget_destroy (info->dialog);
Packit fabffb
	info->dialog = NULL;
Packit fabffb
}
Packit fabffb
Packit fabffb
static void
Packit fabffb
dialog_sim_send_puk_ready (MMSim *sim,
Packit fabffb
                           GAsyncResult *res,
Packit fabffb
                           BroadbandDeviceInfo *info)
Packit fabffb
{
Packit fabffb
	GError *error = NULL;
Packit fabffb
Packit fabffb
	if (!mm_sim_send_puk_finish (sim, res, &error)) {
Packit fabffb
		const gchar *msg;
Packit fabffb
Packit fabffb
		if (g_error_matches (error,
Packit fabffb
		                     MM_MOBILE_EQUIPMENT_ERROR,
Packit fabffb
		                     MM_MOBILE_EQUIPMENT_ERROR_INCORRECT_PASSWORD))
Packit fabffb
			msg = _("Wrong PUK code; please contact your provider.");
Packit fabffb
		else {
Packit fabffb
			g_dbus_error_strip_remote_error (error);
Packit fabffb
			msg = error->message;
Packit fabffb
		}
Packit fabffb
Packit fabffb
		applet_mobile_pin_dialog_stop_spinner (info->dialog, msg);
Packit fabffb
Packit fabffb
		g_warning ("Failed to send PUK to devid: '%s' simid: '%s' : %s",
Packit fabffb
		           mm_modem_get_device_identifier (info->mm_modem),
Packit fabffb
		           mm_sim_get_identifier (info->mm_sim),
Packit fabffb
		           error->message);
Packit fabffb
Packit fabffb
		g_error_free (error);
Packit fabffb
		return;
Packit fabffb
	}
Packit fabffb
Packit fabffb
	/* Good */
Packit fabffb
	unlock_dialog_destroy (info);
Packit fabffb
}
Packit fabffb
Packit fabffb
static void
Packit fabffb
dialog_sim_send_pin_ready (MMSim *sim,
Packit fabffb
                           GAsyncResult *res,
Packit fabffb
                           BroadbandDeviceInfo *info)
Packit fabffb
{
Packit fabffb
	GError *error = NULL;
Packit fabffb
Packit fabffb
	if (!mm_sim_send_pin_finish (sim, res, &error)) {
Packit fabffb
		if (g_error_matches (error,
Packit fabffb
		                     MM_MOBILE_EQUIPMENT_ERROR,
Packit fabffb
		                     MM_MOBILE_EQUIPMENT_ERROR_SIM_PUK)) {
Packit fabffb
			/* Destroy previous dialog and launch a new one rebuilt to ask for PUK */
Packit fabffb
			unlock_dialog_destroy (info);
Packit fabffb
			unlock_dialog_new (info->device, info);
Packit fabffb
		} else {
Packit fabffb
			const gchar *msg = NULL;
Packit fabffb
Packit fabffb
			/* Report error and re-try PIN request */
Packit fabffb
			if (g_error_matches (error,
Packit fabffb
			                     MM_MOBILE_EQUIPMENT_ERROR,
Packit fabffb
			                     MM_MOBILE_EQUIPMENT_ERROR_INCORRECT_PASSWORD))
Packit fabffb
				msg = _("Wrong PIN code; please contact your provider.");
Packit fabffb
			else {
Packit fabffb
				g_dbus_error_strip_remote_error (error);
Packit fabffb
				msg = error->message;
Packit fabffb
			}
Packit fabffb
Packit fabffb
			applet_mobile_pin_dialog_stop_spinner (info->dialog, msg);
Packit fabffb
		}
Packit fabffb
Packit fabffb
		g_warning ("Failed to send PIN to devid: '%s' simid: '%s' : %s",
Packit fabffb
		           mm_modem_get_device_identifier (info->mm_modem),
Packit fabffb
		           mm_sim_get_identifier (info->mm_sim),
Packit fabffb
		           error->message);
Packit fabffb
Packit fabffb
		g_error_free (error);
Packit fabffb
		return;
Packit fabffb
	}
Packit fabffb
Packit fabffb
	/* Good */
Packit fabffb
Packit fabffb
	if (applet_mobile_pin_dialog_get_auto_unlock (info->dialog)) {
Packit fabffb
		const gchar *code1;
Packit fabffb
Packit fabffb
		code1 = applet_mobile_pin_dialog_get_entry1 (info->dialog);
Packit fabffb
		mobile_helper_save_pin_in_keyring (mm_modem_get_device_identifier (info->mm_modem),
Packit fabffb
		                                   mm_sim_get_identifier (info->mm_sim),
Packit fabffb
		                                   code1);
Packit fabffb
	} else
Packit fabffb
		mobile_helper_delete_pin_in_keyring (mm_modem_get_device_identifier (info->mm_modem));
Packit fabffb
Packit fabffb
	unlock_dialog_destroy (info);
Packit fabffb
}
Packit fabffb
Packit fabffb
static void
Packit fabffb
unlock_dialog_response (GtkDialog *dialog,
Packit fabffb
                        gint response,
Packit fabffb
                        gpointer user_data)
Packit fabffb
{
Packit fabffb
	BroadbandDeviceInfo *info = user_data;
Packit fabffb
	const char *code1, *code2;
Packit fabffb
	MMModemLock lock;
Packit fabffb
Packit fabffb
	if (response == GTK_RESPONSE_CANCEL || response == GTK_RESPONSE_DELETE_EVENT) {
Packit fabffb
		unlock_dialog_destroy (info);
Packit fabffb
		return;
Packit fabffb
	}
Packit fabffb
Packit fabffb
	lock = GPOINTER_TO_UINT (g_object_get_data (G_OBJECT (info->dialog), "unlock-code"));
Packit fabffb
	g_assert (lock == MM_MODEM_LOCK_SIM_PIN || lock == MM_MODEM_LOCK_SIM_PUK);
Packit fabffb
Packit fabffb
	/* Start the spinner to show the progress of the unlock */
Packit fabffb
	applet_mobile_pin_dialog_start_spinner (info->dialog, _("Sending unlock code…"));
Packit fabffb
Packit fabffb
	code1 = applet_mobile_pin_dialog_get_entry1 (info->dialog);
Packit fabffb
	if (!code1 || !strlen (code1)) {
Packit fabffb
		g_warn_if_reached ();
Packit fabffb
		unlock_dialog_destroy (info);
Packit fabffb
		return;
Packit fabffb
	}
Packit fabffb
Packit fabffb
	/* Send the code to ModemManager */
Packit fabffb
	if (lock == MM_MODEM_LOCK_SIM_PIN) {
Packit fabffb
		mm_sim_send_pin (info->mm_sim,
Packit fabffb
		                 code1,
Packit fabffb
		                 NULL, /* cancellable */
Packit fabffb
		                 (GAsyncReadyCallback)dialog_sim_send_pin_ready,
Packit fabffb
		                 info);
Packit fabffb
		return;
Packit fabffb
	}
Packit fabffb
Packit fabffb
	if (lock == MM_MODEM_LOCK_SIM_PUK) {
Packit fabffb
		code2 = applet_mobile_pin_dialog_get_entry2 (info->dialog);
Packit fabffb
		if (!code2) {
Packit fabffb
			g_warn_if_reached ();
Packit fabffb
			unlock_dialog_destroy (info);
Packit fabffb
			return;
Packit fabffb
		}
Packit fabffb
Packit fabffb
		mm_sim_send_puk (info->mm_sim,
Packit fabffb
		                 code1, /* puk */
Packit fabffb
		                 code2, /* new pin */
Packit fabffb
		                 NULL, /* cancellable */
Packit fabffb
		                 (GAsyncReadyCallback)dialog_sim_send_puk_ready,
Packit fabffb
		                 info);
Packit fabffb
		return;
Packit fabffb
	}
Packit fabffb
Packit fabffb
	g_assert_not_reached ();
Packit fabffb
}
Packit fabffb
Packit fabffb
static void
Packit fabffb
unlock_dialog_new (NMDevice *device,
Packit fabffb
                   BroadbandDeviceInfo *info)
Packit fabffb
{
Packit fabffb
	MMModemLock lock;
Packit fabffb
	const gchar *unlock_required;
Packit fabffb
Packit fabffb
	if (info->dialog)
Packit fabffb
		return;
Packit fabffb
Packit fabffb
	/* We can only unlock PIN or PUK here */
Packit fabffb
	lock = mm_modem_get_unlock_required (info->mm_modem);
Packit fabffb
	if (lock == MM_MODEM_LOCK_SIM_PIN)
Packit fabffb
		unlock_required = "sim-pin";
Packit fabffb
	else if (lock == MM_MODEM_LOCK_SIM_PUK)
Packit fabffb
		unlock_required = "sim-puk";
Packit fabffb
	else {
Packit fabffb
		g_warning ("Cannot unlock devid: '%s' simid: '%s' : unhandled lock code '%s'",
Packit fabffb
		           mm_modem_get_device_identifier (info->mm_modem),
Packit fabffb
		           mm_sim_get_identifier (info->mm_sim),
Packit fabffb
		           mm_modem_lock_get_string (lock));
Packit fabffb
		return;
Packit fabffb
	}
Packit fabffb
Packit fabffb
	info->dialog = applet_mobile_pin_dialog_new (unlock_required,
Packit fabffb
	                                             nm_device_get_description (device));
Packit fabffb
Packit fabffb
	g_object_set_data (G_OBJECT (info->dialog), "unlock-code", GUINT_TO_POINTER (lock));
Packit fabffb
	g_signal_connect (info->dialog, "response", G_CALLBACK (unlock_dialog_response), info);
Packit fabffb
Packit fabffb
	/* Need to resize the dialog after hiding widgets */
Packit fabffb
	gtk_window_resize (GTK_WINDOW (info->dialog), 400, 100);
Packit fabffb
Packit fabffb
	/* Show the dialog */
Packit fabffb
	gtk_widget_realize (info->dialog);
Packit fabffb
	gtk_window_present (GTK_WINDOW (info->dialog));
Packit fabffb
}
Packit fabffb
Packit fabffb
static void
Packit fabffb
autounlock_sim_send_pin_ready (MMSim *sim,
Packit fabffb
                               GAsyncResult *res,
Packit fabffb
                               BroadbandDeviceInfo *info)
Packit fabffb
{
Packit fabffb
	GError *error = NULL;
Packit fabffb
Packit fabffb
	if (!mm_sim_send_pin_finish (sim, res, &error)) {
Packit fabffb
		g_warning ("Failed to auto-unlock devid: '%s' simid: '%s' : %s",
Packit fabffb
		           mm_modem_get_device_identifier (info->mm_modem),
Packit fabffb
		           mm_sim_get_identifier (info->mm_sim),
Packit fabffb
		           error->message);
Packit fabffb
		g_error_free (error);
Packit fabffb
Packit fabffb
		/* Remove PIN from keyring right away */
Packit fabffb
		mobile_helper_delete_pin_in_keyring (mm_modem_get_device_identifier (info->mm_modem));
Packit fabffb
Packit fabffb
		/* Ask the user */
Packit fabffb
		unlock_dialog_new (info->device, info);
Packit fabffb
	}
Packit fabffb
}
Packit fabffb
Packit fabffb
static void
Packit fabffb
keyring_pin_check_cb (GObject *source,
Packit fabffb
                      GAsyncResult *result,
Packit fabffb
                      gpointer user_data)
Packit fabffb
{
Packit fabffb
	BroadbandDeviceInfo *info = user_data;
Packit fabffb
	GList *iter;
Packit fabffb
	GList *list;
Packit fabffb
	SecretItem *item;
Packit fabffb
	SecretValue *pin = NULL;
Packit fabffb
	GHashTable *attributes;
Packit fabffb
	GError *error = NULL;
Packit fabffb
	const char *simid;
Packit fabffb
Packit fabffb
	list = secret_service_search_finish (NULL, result, &error);
Packit fabffb
Packit fabffb
	if (error != NULL) {
Packit fabffb
		/* No saved PIN, just ask the user */
Packit fabffb
		unlock_dialog_new (info->device, info);
Packit fabffb
		g_error_free (error);
Packit fabffb
		return;
Packit fabffb
	}
Packit fabffb
Packit fabffb
	/* Look for a result with a matching "simid" attribute since that's
Packit fabffb
	 * better than just using a matching "devid".  The PIN is really tied
Packit fabffb
	 * to the SIM, not the modem itself.
Packit fabffb
	 */
Packit fabffb
	simid = mm_sim_get_identifier (info->mm_sim);
Packit fabffb
	if (simid) {
Packit fabffb
		for (iter = list;
Packit fabffb
		     (pin == NULL) && iter;
Packit fabffb
		     iter = g_list_next (iter)) {
Packit fabffb
			item = iter->data;
Packit fabffb
Packit fabffb
			/* Look for a matching "simid" attribute */
Packit fabffb
			attributes = secret_item_get_attributes (item);
Packit fabffb
			if (g_strcmp0 (simid, g_hash_table_lookup (attributes, "simid")))
Packit fabffb
				pin = secret_item_get_secret (item);
Packit fabffb
			else
Packit fabffb
				pin = NULL;
Packit fabffb
			g_hash_table_unref (attributes);
Packit fabffb
Packit fabffb
			if (pin != NULL)
Packit fabffb
				break;
Packit fabffb
		}
Packit fabffb
	}
Packit fabffb
Packit fabffb
	if (pin == NULL) {
Packit fabffb
		/* Fall back to the first result's PIN if we have one */
Packit fabffb
		if (list)
Packit fabffb
			pin = secret_item_get_secret (list->data);
Packit fabffb
		if (pin == NULL) {
Packit fabffb
			unlock_dialog_new (info->device, info);
Packit fabffb
			return;
Packit fabffb
		}
Packit fabffb
	}
Packit fabffb
Packit fabffb
	/* Send the PIN code to ModemManager */
Packit fabffb
	mm_sim_send_pin (info->mm_sim,
Packit fabffb
	                 secret_value_get (pin, NULL),
Packit fabffb
	                 NULL, /* cancellable */
Packit fabffb
	                 (GAsyncReadyCallback)autounlock_sim_send_pin_ready,
Packit fabffb
	                 info);
Packit fabffb
	secret_value_unref (pin);
Packit fabffb
}
Packit fabffb
Packit fabffb
static void
Packit fabffb
modem_get_sim_ready (MMModem *modem,
Packit fabffb
                     GAsyncResult *res,
Packit fabffb
                     BroadbandDeviceInfo *info)
Packit fabffb
{
Packit fabffb
	GHashTable *attrs;
Packit fabffb
Packit fabffb
	info->mm_sim = mm_modem_get_sim_finish (modem, res, NULL);
Packit fabffb
	if (!info->mm_sim)
Packit fabffb
		/* Ok, the modem may not need it actually */
Packit fabffb
		return;
Packit fabffb
Packit fabffb
	/* Do nothing if we're not locked */
Packit fabffb
	if (mm_modem_get_state (info->mm_modem) != MM_MODEM_STATE_LOCKED)
Packit fabffb
		return;
Packit fabffb
Packit fabffb
	/* If we have a device ID ask the keyring for any saved SIM-PIN codes */
Packit fabffb
	if (mm_modem_get_device_identifier (info->mm_modem) &&
Packit fabffb
	    mm_modem_get_unlock_required (info->mm_modem) == MM_MODEM_LOCK_SIM_PIN) {
Packit fabffb
		attrs = secret_attributes_build (&mobile_secret_schema, "devid",
Packit fabffb
		                                 mm_modem_get_device_identifier (info->mm_modem),
Packit fabffb
		                                 NULL);
Packit fabffb
		secret_service_search (NULL, &mobile_secret_schema, attrs,
Packit fabffb
		                       SECRET_SEARCH_UNLOCK | SECRET_SEARCH_LOAD_SECRETS,
Packit fabffb
		                       info->cancellable, keyring_pin_check_cb, info);
Packit fabffb
		g_hash_table_unref (attrs);
Packit fabffb
	} else {
Packit fabffb
		/* Couldn't get a device ID, but unlock required; present dialog */
Packit fabffb
		unlock_dialog_new (info->device, info);
Packit fabffb
	}
Packit fabffb
}
Packit fabffb
Packit fabffb
/********************************************************************/
Packit fabffb
Packit fabffb
static gboolean
Packit fabffb
get_secrets (SecretsRequest *req,
Packit fabffb
             GError **error)
Packit fabffb
{
Packit fabffb
	NMDevice *device;
Packit fabffb
	BroadbandDeviceInfo *devinfo;
Packit fabffb
Packit fabffb
	device = applet_get_device_for_connection (req->applet, req->connection);
Packit fabffb
	if (!device) {
Packit fabffb
		g_set_error (error,
Packit fabffb
		             NM_SECRET_AGENT_ERROR,
Packit fabffb
		             NM_SECRET_AGENT_ERROR_FAILED,
Packit fabffb
		             "%s.%d (%s): failed to find device for active connection.",
Packit fabffb
		             __FILE__, __LINE__, __func__);
Packit fabffb
		return FALSE;
Packit fabffb
	}
Packit fabffb
Packit fabffb
	if (!mobile_helper_get_secrets (nm_device_modem_get_current_capabilities (NM_DEVICE_MODEM (device)),
Packit fabffb
	                                req,
Packit fabffb
	                                error))
Packit fabffb
		return FALSE;
Packit fabffb
Packit fabffb
	devinfo = g_object_get_data (G_OBJECT (device), BROADBAND_INFO_TAG);
Packit fabffb
	if (!devinfo) {
Packit fabffb
		g_set_error (error,
Packit fabffb
		             NM_SECRET_AGENT_ERROR,
Packit fabffb
		             NM_SECRET_AGENT_ERROR_FAILED,
Packit fabffb
		             "%s.%d (%s): ModemManager is not available for modem at %s",
Packit fabffb
		             __FILE__, __LINE__, __func__,
Packit fabffb
		             nm_device_get_udi (device));
Packit fabffb
		return FALSE;
Packit fabffb
	}
Packit fabffb
Packit fabffb
	/* A GetSecrets PIN dialog overrides the initial unlock dialog */
Packit fabffb
	if (devinfo->dialog)
Packit fabffb
		unlock_dialog_destroy (devinfo);
Packit fabffb
Packit fabffb
	return TRUE;
Packit fabffb
}
Packit fabffb
Packit fabffb
/********************************************************************/
Packit fabffb
Packit fabffb
static guint32
Packit fabffb
broadband_state_to_mb_state (BroadbandDeviceInfo *info)
Packit fabffb
{
Packit fabffb
	MMModemState state;
Packit fabffb
Packit fabffb
	state = mm_modem_get_state (info->mm_modem);
Packit fabffb
Packit fabffb
	switch (state) {
Packit fabffb
	case MM_MODEM_STATE_FAILED:
Packit fabffb
	case MM_MODEM_STATE_UNKNOWN:
Packit fabffb
	case MM_MODEM_STATE_INITIALIZING:
Packit fabffb
	case MM_MODEM_STATE_LOCKED:
Packit fabffb
	case MM_MODEM_STATE_DISABLED:
Packit fabffb
	case MM_MODEM_STATE_DISABLING:
Packit fabffb
	case MM_MODEM_STATE_ENABLING:
Packit fabffb
		return MB_STATE_UNKNOWN;
Packit fabffb
Packit fabffb
	case MM_MODEM_STATE_ENABLED:
Packit fabffb
		return MB_STATE_IDLE;
Packit fabffb
Packit fabffb
	case MM_MODEM_STATE_SEARCHING:
Packit fabffb
		return MB_STATE_SEARCHING;
Packit fabffb
Packit fabffb
	case MM_MODEM_STATE_REGISTERED:
Packit fabffb
	case MM_MODEM_STATE_DISCONNECTING:
Packit fabffb
	case MM_MODEM_STATE_CONNECTING:
Packit fabffb
	case MM_MODEM_STATE_CONNECTED:
Packit fabffb
		break;
Packit fabffb
	default:
Packit fabffb
		g_warn_if_reached ();
Packit fabffb
		return MB_STATE_UNKNOWN;
Packit fabffb
	}
Packit fabffb
Packit fabffb
	/* home or roaming? */
Packit fabffb
Packit fabffb
	if (info->mm_modem_3gpp) {
Packit fabffb
		switch (mm_modem_3gpp_get_registration_state (info->mm_modem_3gpp)) {
Packit fabffb
		case MM_MODEM_3GPP_REGISTRATION_STATE_HOME:
Packit fabffb
			return MB_STATE_HOME;
Packit fabffb
		case MM_MODEM_3GPP_REGISTRATION_STATE_ROAMING:
Packit fabffb
			return MB_STATE_ROAMING;
Packit fabffb
		default:
Packit fabffb
			/* Skip, we may be registered in EVDO/CDMA1x instead... */
Packit fabffb
			break;
Packit fabffb
		}
Packit fabffb
	}
Packit fabffb
Packit fabffb
	if (info->mm_modem_cdma) {
Packit fabffb
		/* EVDO state overrides 1X state for now */
Packit fabffb
		switch (mm_modem_cdma_get_evdo_registration_state (info->mm_modem_cdma)) {
Packit fabffb
		case MM_MODEM_CDMA_REGISTRATION_STATE_HOME:
Packit fabffb
			return MB_STATE_HOME;
Packit fabffb
		case MM_MODEM_CDMA_REGISTRATION_STATE_ROAMING:
Packit fabffb
			return MB_STATE_ROAMING;
Packit fabffb
		case MM_MODEM_CDMA_REGISTRATION_STATE_REGISTERED:
Packit fabffb
			/* Assume home... */
Packit fabffb
			return MB_STATE_HOME;
Packit fabffb
		default:
Packit fabffb
			/* Skip, we may be registered in CDMA1x instead... */
Packit fabffb
			break;
Packit fabffb
		}
Packit fabffb
Packit fabffb
		switch (mm_modem_cdma_get_cdma1x_registration_state (info->mm_modem_cdma)) {
Packit fabffb
		case MM_MODEM_CDMA_REGISTRATION_STATE_HOME:
Packit fabffb
			return MB_STATE_HOME;
Packit fabffb
		case MM_MODEM_CDMA_REGISTRATION_STATE_ROAMING:
Packit fabffb
			return MB_STATE_ROAMING;
Packit fabffb
		case MM_MODEM_CDMA_REGISTRATION_STATE_REGISTERED:
Packit fabffb
			/* Assume home... */
Packit fabffb
			return MB_STATE_HOME;
Packit fabffb
		default:
Packit fabffb
			break;
Packit fabffb
		}
Packit fabffb
	}
Packit fabffb
Packit fabffb
	return MB_STATE_UNKNOWN;
Packit fabffb
}
Packit fabffb
Packit fabffb
static guint32
Packit fabffb
broadband_act_to_mb_act (BroadbandDeviceInfo *info)
Packit fabffb
{
Packit fabffb
	MMModemAccessTechnology act;
Packit fabffb
Packit fabffb
	act = mm_modem_get_access_technologies (info->mm_modem);
Packit fabffb
Packit fabffb
	g_return_val_if_fail (act != MM_MODEM_ACCESS_TECHNOLOGY_ANY, MB_TECH_UNKNOWN);
Packit fabffb
Packit fabffb
	/* We get a MASK of values, but we need to report only ONE.
Packit fabffb
	 * So just return the 'best' one found */
Packit fabffb
Packit fabffb
	/* Prefer 4G technologies over 3G and 2G */
Packit fabffb
	if (act & MM_MODEM_ACCESS_TECHNOLOGY_LTE)
Packit fabffb
		return MB_TECH_LTE;
Packit fabffb
Packit fabffb
	/* Prefer 3GPP 3G technologies over 3GPP 2G or 3GPP2 */
Packit fabffb
	if (act & MM_MODEM_ACCESS_TECHNOLOGY_HSPA_PLUS)
Packit fabffb
		return MB_TECH_HSPA_PLUS;
Packit fabffb
	if (act & MM_MODEM_ACCESS_TECHNOLOGY_HSPA)
Packit fabffb
		return MB_TECH_HSPA;
Packit fabffb
	if (act & MM_MODEM_ACCESS_TECHNOLOGY_HSUPA)
Packit fabffb
		return MB_TECH_HSUPA;
Packit fabffb
	if (act & MM_MODEM_ACCESS_TECHNOLOGY_HSDPA)
Packit fabffb
		return MB_TECH_HSDPA;
Packit fabffb
	if (act & MM_MODEM_ACCESS_TECHNOLOGY_UMTS)
Packit fabffb
		return MB_TECH_UMTS;
Packit fabffb
Packit fabffb
	/* Prefer 3GPP2 3G technologies over 2G */
Packit fabffb
	if (act & MM_MODEM_ACCESS_TECHNOLOGY_EVDO0 ||
Packit fabffb
	    act & MM_MODEM_ACCESS_TECHNOLOGY_EVDOA ||
Packit fabffb
	    act & MM_MODEM_ACCESS_TECHNOLOGY_EVDOB)
Packit fabffb
		return MB_TECH_EVDO;
Packit fabffb
Packit fabffb
	/* Prefer 3GPP 2G technologies over 3GPP2 2G */
Packit fabffb
	if (act & MM_MODEM_ACCESS_TECHNOLOGY_EDGE)
Packit fabffb
		return MB_TECH_EDGE;
Packit fabffb
	if (act & MM_MODEM_ACCESS_TECHNOLOGY_GPRS)
Packit fabffb
		return MB_TECH_GPRS;
Packit fabffb
	if (act & MM_MODEM_ACCESS_TECHNOLOGY_GSM ||
Packit fabffb
		act & MM_MODEM_ACCESS_TECHNOLOGY_GSM_COMPACT)
Packit fabffb
		return MB_TECH_GSM;
Packit fabffb
Packit fabffb
	/* Last, 3GPP2 2G */
Packit fabffb
	if (act & MM_MODEM_ACCESS_TECHNOLOGY_1XRTT)
Packit fabffb
		return MB_TECH_1XRTT;
Packit fabffb
Packit fabffb
	return MB_TECH_UNKNOWN;
Packit fabffb
}
Packit fabffb
Packit fabffb
static void
Packit fabffb
get_icon (NMDevice *device,
Packit fabffb
          NMDeviceState state,
Packit fabffb
          NMConnection *connection,
Packit fabffb
          GdkPixbuf **out_pixbuf,
Packit fabffb
          const char **out_icon_name,
Packit fabffb
          char **tip,
Packit fabffb
          NMApplet *applet)
Packit fabffb
{
Packit fabffb
	BroadbandDeviceInfo *info;
Packit fabffb
Packit fabffb
	g_return_if_fail (out_icon_name && !*out_icon_name);
Packit fabffb
	g_return_if_fail (tip && !*tip);
Packit fabffb
Packit fabffb
	if (!applet->mm1) {
Packit fabffb
		g_warning ("ModemManager is not available for modem at %s", nm_device_get_udi (device));
Packit fabffb
		return;
Packit fabffb
	}
Packit fabffb
Packit fabffb
	info = g_object_get_data (G_OBJECT (device), BROADBAND_INFO_TAG);
Packit fabffb
	if (!info) {
Packit fabffb
		g_warning ("ModemManager is not available for modem at %s",
Packit fabffb
		           nm_device_get_udi (device));
Packit fabffb
		return;
Packit fabffb
	}
Packit fabffb
Packit fabffb
	mobile_helper_get_icon (device,
Packit fabffb
	                        state,
Packit fabffb
	                        connection,
Packit fabffb
	                        out_pixbuf,
Packit fabffb
	                        out_icon_name,
Packit fabffb
	                        tip,
Packit fabffb
	                        applet,
Packit fabffb
	                        broadband_state_to_mb_state (info),
Packit fabffb
	                        broadband_act_to_mb_act (info),
Packit fabffb
	                        mm_modem_get_signal_quality (info->mm_modem, NULL),
Packit fabffb
	                        (mm_modem_get_state (info->mm_modem) >= MM_MODEM_STATE_ENABLED));
Packit fabffb
}
Packit fabffb
Packit fabffb
/********************************************************************/
Packit fabffb
Packit fabffb
typedef struct {
Packit fabffb
	NMApplet *applet;
Packit fabffb
	NMDevice *device;
Packit fabffb
	NMConnection *connection;
Packit fabffb
} BroadbandMenuItemInfo;
Packit fabffb
Packit fabffb
static void
Packit fabffb
menu_item_info_destroy (gpointer data, GClosure *closure)
Packit fabffb
{
Packit fabffb
	BroadbandMenuItemInfo *info = data;
Packit fabffb
Packit fabffb
	g_object_unref (G_OBJECT (info->device));
Packit fabffb
	if (info->connection)
Packit fabffb
		g_object_unref (info->connection);
Packit fabffb
	g_slice_free (BroadbandMenuItemInfo, info);
Packit fabffb
}
Packit fabffb
Packit fabffb
static void
Packit fabffb
menu_item_activate (GtkMenuItem *item,
Packit fabffb
                    BroadbandMenuItemInfo *info)
Packit fabffb
{
Packit fabffb
	applet_menu_item_activate_helper (info->device,
Packit fabffb
	                                  info->connection,
Packit fabffb
	                                  "/",
Packit fabffb
	                                  info->applet,
Packit fabffb
	                                  info);
Packit fabffb
}
Packit fabffb
Packit fabffb
static void
Packit fabffb
add_connection_item (NMDevice *device,
Packit fabffb
                     NMConnection *connection,
Packit fabffb
                     GtkWidget *item,
Packit fabffb
                     GtkWidget *menu,
Packit fabffb
                     NMApplet *applet)
Packit fabffb
{
Packit fabffb
	BroadbandMenuItemInfo *info;
Packit fabffb
Packit fabffb
	info = g_slice_new0 (BroadbandMenuItemInfo);
Packit fabffb
	info->applet = applet;
Packit fabffb
	info->device = g_object_ref (device);
Packit fabffb
	info->connection = connection ? g_object_ref (connection) : NULL;
Packit fabffb
Packit fabffb
	g_signal_connect_data (item, "activate",
Packit fabffb
	                       G_CALLBACK (menu_item_activate),
Packit fabffb
	                       info,
Packit fabffb
	                       (GClosureNotify) menu_item_info_destroy, 0);
Packit fabffb
Packit fabffb
	gtk_menu_shell_append (GTK_MENU_SHELL (menu), item);
Packit fabffb
	gtk_widget_show (item);
Packit fabffb
}
Packit fabffb
Packit fabffb
static void
Packit fabffb
add_menu_item (NMDevice *device,
Packit fabffb
               gboolean multiple_devices,
Packit fabffb
               const GPtrArray *connections,
Packit fabffb
               NMConnection *active,
Packit fabffb
               GtkWidget *menu,
Packit fabffb
               NMApplet *applet)
Packit fabffb
{
Packit fabffb
	BroadbandDeviceInfo *info;
Packit fabffb
	char *text;
Packit fabffb
	GtkWidget *item;
Packit fabffb
	int i;
Packit fabffb
Packit fabffb
	info = g_object_get_data (G_OBJECT (device), BROADBAND_INFO_TAG);
Packit fabffb
	if (!info) {
Packit fabffb
		g_warning ("ModemManager is not available for modem at %s",
Packit fabffb
		           nm_device_get_udi (device));
Packit fabffb
		return;
Packit fabffb
	}
Packit fabffb
Packit fabffb
	if (multiple_devices) {
Packit fabffb
		const char *desc;
Packit fabffb
Packit fabffb
		desc = nm_device_get_description (device);
Packit fabffb
		text = g_strdup_printf (_("Mobile Broadband (%s)"), desc);
Packit fabffb
	} else {
Packit fabffb
		text = g_strdup (_("Mobile Broadband"));
Packit fabffb
	}
Packit fabffb
Packit fabffb
	item = applet_menu_item_create_device_item_helper (device, applet, text);
Packit fabffb
	gtk_widget_set_sensitive (item, FALSE);
Packit fabffb
	gtk_menu_shell_append (GTK_MENU_SHELL (menu), item);
Packit fabffb
	gtk_widget_show (item);
Packit fabffb
	g_free (text);
Packit fabffb
Packit fabffb
	/* Add the active connection */
Packit fabffb
	if (active) {
Packit fabffb
		NMSettingConnection *s_con;
Packit fabffb
Packit fabffb
		s_con = nm_connection_get_setting_connection (active);
Packit fabffb
		g_assert (s_con);
Packit fabffb
Packit fabffb
		item = nm_mb_menu_item_new (nm_setting_connection_get_id (s_con),
Packit fabffb
		                            mm_modem_get_signal_quality (info->mm_modem, NULL),
Packit fabffb
		                            info->operator_name,
Packit fabffb
		                            TRUE,
Packit fabffb
		                            broadband_act_to_mb_act (info),
Packit fabffb
		                            broadband_state_to_mb_state (info),
Packit fabffb
		                            mm_modem_get_state (info->mm_modem) >= MM_MODEM_STATE_ENABLED,
Packit fabffb
		                            applet);
Packit fabffb
		gtk_widget_set_sensitive (GTK_WIDGET (item), TRUE);
Packit fabffb
		add_connection_item (device, active, item, menu, applet);
Packit fabffb
	}
Packit fabffb
Packit fabffb
	/* Notify user of unmanaged or unavailable device */
Packit fabffb
	if (nm_device_get_state (device) > NM_DEVICE_STATE_DISCONNECTED) {
Packit fabffb
		item = nma_menu_device_get_menu_item (device, applet, NULL);
Packit fabffb
		if (item) {
Packit fabffb
			gtk_menu_shell_append (GTK_MENU_SHELL (menu), item);
Packit fabffb
			gtk_widget_show (item);
Packit fabffb
		}
Packit fabffb
	} else {
Packit fabffb
		/* Otherwise show idle registration state or disabled */
Packit fabffb
		item = nm_mb_menu_item_new (NULL,
Packit fabffb
		                            mm_modem_get_signal_quality (info->mm_modem, NULL),
Packit fabffb
		                            info->operator_name,
Packit fabffb
		                            FALSE,
Packit fabffb
		                            broadband_act_to_mb_act (info),
Packit fabffb
		                            broadband_state_to_mb_state (info),
Packit fabffb
		                            mm_modem_get_state (info->mm_modem) >= MM_MODEM_STATE_ENABLED,
Packit fabffb
		                            applet);
Packit fabffb
		gtk_widget_set_sensitive (GTK_WIDGET (item), FALSE);
Packit fabffb
		gtk_menu_shell_append (GTK_MENU_SHELL (menu), item);
Packit fabffb
		gtk_widget_show (item);
Packit fabffb
	}
Packit fabffb
Packit fabffb
	/* Add the default / inactive connection items */
Packit fabffb
	if (!nma_menu_device_check_unusable (device)) {
Packit fabffb
		if ((!active && connections->len) || (active && connections->len > 1))
Packit fabffb
			applet_menu_item_add_complex_separator_helper (menu, applet, _("Available"));
Packit fabffb
Packit fabffb
		if (connections->len) {
Packit fabffb
			for (i = 0; i < connections->len; i++) {
Packit fabffb
				NMConnection *connection = NM_CONNECTION (connections->pdata[i]);
Packit fabffb
Packit fabffb
				if (connection != active) {
Packit fabffb
					item = applet_new_menu_item_helper (connection, NULL, FALSE);
Packit fabffb
					add_connection_item (device, connection, item, menu, applet);
Packit fabffb
				}
Packit fabffb
			}
Packit fabffb
		} else {
Packit fabffb
			/* Default connection item */
Packit fabffb
			item = gtk_check_menu_item_new_with_label (_("New Mobile Broadband connection…"));
Packit fabffb
			add_connection_item (device, NULL, item, menu, applet);
Packit fabffb
		}
Packit fabffb
	}
Packit fabffb
}
Packit fabffb
Packit fabffb
/********************************************************************/
Packit fabffb
Packit fabffb
static void
Packit fabffb
notify_connected (NMDevice *device,
Packit fabffb
                  const char *msg,
Packit fabffb
                  NMApplet *applet)
Packit fabffb
{
Packit fabffb
	applet_do_notify_with_pref (applet,
Packit fabffb
	                            _("Connection Established"),
Packit fabffb
	                            msg ? msg : _("You are now connected to the Mobile Broadband network."),
Packit fabffb
	                            "nm-device-wwan",
Packit fabffb
	                            PREF_DISABLE_CONNECTED_NOTIFICATIONS);
Packit fabffb
}
Packit fabffb
Packit fabffb
/********************************************************************/
Packit fabffb
Packit fabffb
static void
Packit fabffb
signal_quality_updated (GObject *object,
Packit fabffb
                        GParamSpec *pspec,
Packit fabffb
                        BroadbandDeviceInfo *info)
Packit fabffb
{
Packit fabffb
	applet_schedule_update_icon (info->applet);
Packit fabffb
	applet_schedule_update_menu (info->applet);
Packit fabffb
}
Packit fabffb
Packit fabffb
static void
Packit fabffb
access_technologies_updated (GObject *object,
Packit fabffb
                             GParamSpec *pspec,
Packit fabffb
                             BroadbandDeviceInfo *info)
Packit fabffb
{
Packit fabffb
	applet_schedule_update_icon (info->applet);
Packit fabffb
	applet_schedule_update_menu (info->applet);
Packit fabffb
}
Packit fabffb
Packit fabffb
static void
Packit fabffb
operator_info_updated (GObject *object,
Packit fabffb
                       GParamSpec *pspec,
Packit fabffb
                       BroadbandDeviceInfo *info)
Packit fabffb
{
Packit fabffb
	g_free (info->operator_name);
Packit fabffb
	info->operator_name = NULL;
Packit fabffb
Packit fabffb
	/* Prefer 3GPP info if given */
Packit fabffb
Packit fabffb
	if (info->mm_modem_3gpp) {
Packit fabffb
		info->operator_name = (mobile_helper_parse_3gpp_operator_name (
Packit fabffb
			                       &(info->mpd),
Packit fabffb
			                       mm_modem_3gpp_get_operator_name (info->mm_modem_3gpp),
Packit fabffb
			                       mm_modem_3gpp_get_operator_code (info->mm_modem_3gpp)));
Packit fabffb
		if (info->operator_name)
Packit fabffb
			return;
Packit fabffb
	}
Packit fabffb
Packit fabffb
	if (info->mm_modem_cdma)
Packit fabffb
		info->operator_name = (mobile_helper_parse_3gpp2_operator_name (
Packit fabffb
			                       &(info->mpd),
Packit fabffb
			                       mm_modem_cdma_get_sid (info->mm_modem_cdma)));
Packit fabffb
}
Packit fabffb
Packit fabffb
static void
Packit fabffb
setup_signals (BroadbandDeviceInfo *info,
Packit fabffb
               gboolean enable)
Packit fabffb
{
Packit fabffb
	if (enable) {
Packit fabffb
		g_assert (info->mm_modem_3gpp == NULL);
Packit fabffb
		g_assert (info->mm_modem_cdma == NULL);
Packit fabffb
		g_assert (info->operator_name_update_id == 0);
Packit fabffb
		g_assert (info->operator_code_update_id == 0);
Packit fabffb
		g_assert (info->sid_update_id == 0);
Packit fabffb
Packit fabffb
		info->mm_modem_3gpp = mm_object_get_modem_3gpp (info->mm_object);
Packit fabffb
		info->mm_modem_cdma = mm_object_get_modem_cdma (info->mm_object);
Packit fabffb
Packit fabffb
		if (info->mm_modem_3gpp) {
Packit fabffb
			info->operator_name_update_id = g_signal_connect (info->mm_modem_3gpp,
Packit fabffb
			                                                  "notify::operator-name",
Packit fabffb
			                                                  G_CALLBACK (operator_info_updated),
Packit fabffb
			                                                  info);
Packit fabffb
			info->operator_code_update_id = g_signal_connect (info->mm_modem_3gpp,
Packit fabffb
			                                                  "notify::operator-code",
Packit fabffb
			                                                  G_CALLBACK (operator_info_updated),
Packit fabffb
			                                                  info);
Packit fabffb
		}
Packit fabffb
Packit fabffb
		if (info->mm_modem_cdma) {
Packit fabffb
			info->sid_update_id = g_signal_connect (info->mm_modem_cdma,
Packit fabffb
			                                        "notify::sid",
Packit fabffb
			                                        G_CALLBACK (operator_info_updated),
Packit fabffb
			                                        info);
Packit fabffb
		}
Packit fabffb
Packit fabffb
		/* Load initial values */
Packit fabffb
		operator_info_updated (NULL, NULL, info);
Packit fabffb
	} else {
Packit fabffb
		if (info->mm_modem_3gpp) {
Packit fabffb
			if (info->operator_name_update_id) {
Packit fabffb
				if (g_signal_handler_is_connected (info->mm_modem_3gpp, info->operator_name_update_id))
Packit fabffb
					g_signal_handler_disconnect (info->mm_modem_3gpp, info->operator_name_update_id);
Packit fabffb
				info->operator_name_update_id = 0;
Packit fabffb
			}
Packit fabffb
			if (info->operator_code_update_id) {
Packit fabffb
				if (g_signal_handler_is_connected (info->mm_modem_3gpp, info->operator_code_update_id))
Packit fabffb
					g_signal_handler_disconnect (info->mm_modem_3gpp, info->operator_code_update_id);
Packit fabffb
				info->operator_code_update_id = 0;
Packit fabffb
			}
Packit fabffb
			g_clear_object (&info->mm_modem_3gpp);
Packit fabffb
		}
Packit fabffb
Packit fabffb
		if (info->mm_modem_cdma) {
Packit fabffb
			if (info->sid_update_id) {
Packit fabffb
				if (g_signal_handler_is_connected (info->mm_modem_cdma, info->sid_update_id))
Packit fabffb
					g_signal_handler_disconnect (info->mm_modem_cdma, info->sid_update_id);
Packit fabffb
				info->sid_update_id = 0;
Packit fabffb
			}
Packit fabffb
			g_clear_object (&info->mm_modem_cdma);
Packit fabffb
		}
Packit fabffb
	}
Packit fabffb
}
Packit fabffb
Packit fabffb
static void
Packit fabffb
modem_state_changed (MMModem *object,
Packit fabffb
                     gint old,
Packit fabffb
                     gint new,
Packit fabffb
                     guint reason,
Packit fabffb
                     BroadbandDeviceInfo *info)
Packit fabffb
{
Packit fabffb
	/* Modem just got enabled */
Packit fabffb
	if (old < MM_MODEM_STATE_ENABLED &&
Packit fabffb
	    new >= MM_MODEM_STATE_ENABLED) {
Packit fabffb
		setup_signals (info, TRUE);
Packit fabffb
	}
Packit fabffb
	/* Modem just got disabled */
Packit fabffb
	else if (old >= MM_MODEM_STATE_ENABLED &&
Packit fabffb
	    new < MM_MODEM_STATE_ENABLED) {
Packit fabffb
		setup_signals (info, FALSE);
Packit fabffb
	}
Packit fabffb
Packit fabffb
	/* Modem just got registered */
Packit fabffb
	if ((old < MM_MODEM_STATE_REGISTERED &&
Packit fabffb
	     new >= MM_MODEM_STATE_REGISTERED)) {
Packit fabffb
		guint32 mb_state;
Packit fabffb
		const char *signal_strength_icon;
Packit fabffb
Packit fabffb
		signal_strength_icon = mobile_helper_get_quality_icon_name (mm_modem_get_signal_quality(info->mm_modem, NULL));
Packit fabffb
Packit fabffb
		/* Notify about new registration info */
Packit fabffb
		mb_state = broadband_state_to_mb_state (info);
Packit fabffb
		if (mb_state == MB_STATE_HOME) {
Packit fabffb
			applet_do_notify_with_pref (info->applet,
Packit fabffb
			                            _("Mobile Broadband network."),
Packit fabffb
			                            _("You are now registered on the home network."),
Packit fabffb
			                            signal_strength_icon,
Packit fabffb
			                            PREF_DISABLE_CONNECTED_NOTIFICATIONS);
Packit fabffb
		} else if (mb_state == MB_STATE_ROAMING) {
Packit fabffb
			applet_do_notify_with_pref (info->applet,
Packit fabffb
			                            _("Mobile Broadband network."),
Packit fabffb
			                            _("You are now registered on a roaming network."),
Packit fabffb
			                            signal_strength_icon,
Packit fabffb
			                            PREF_DISABLE_CONNECTED_NOTIFICATIONS);
Packit fabffb
		}
Packit fabffb
	}
Packit fabffb
}
Packit fabffb
Packit fabffb
/********************************************************************/
Packit fabffb
Packit fabffb
static void
Packit fabffb
broadband_device_info_free (BroadbandDeviceInfo *info)
Packit fabffb
{
Packit fabffb
	setup_signals (info, FALSE);
Packit fabffb
Packit fabffb
	g_free (info->operator_name);
Packit fabffb
	if (info->mpd)
Packit fabffb
		g_object_unref (info->mpd);
Packit fabffb
Packit fabffb
	if (info->mm_sim)
Packit fabffb
		g_object_unref (info->mm_sim);
Packit fabffb
	if (info->mm_modem) {
Packit fabffb
		g_signal_handlers_disconnect_matched (info->mm_modem, G_SIGNAL_MATCH_DATA, 0, 0, NULL, NULL, info);
Packit fabffb
		g_object_unref (info->mm_modem);
Packit fabffb
	}
Packit fabffb
	if (info->mm_object)
Packit fabffb
		g_object_unref (info->mm_object);
Packit fabffb
Packit fabffb
	if (info->dialog)
Packit fabffb
		unlock_dialog_destroy (info);
Packit fabffb
	g_object_unref (info->cancellable);
Packit fabffb
Packit fabffb
	g_slice_free (BroadbandDeviceInfo, info);
Packit fabffb
}
Packit fabffb
Packit fabffb
static void
Packit fabffb
device_added (NMDevice *device,
Packit fabffb
              NMApplet *applet)
Packit fabffb
{
Packit fabffb
	NMDeviceModem *modem = NM_DEVICE_MODEM (device);
Packit fabffb
	BroadbandDeviceInfo *info;
Packit fabffb
	const char *udi;
Packit fabffb
	GDBusObject *modem_object;
Packit fabffb
Packit fabffb
	udi = nm_device_get_udi (device);
Packit fabffb
	if (!udi)
Packit fabffb
		return;
Packit fabffb
Packit fabffb
	if (g_object_get_data (G_OBJECT (modem), BROADBAND_INFO_TAG))
Packit fabffb
		return;
Packit fabffb
Packit fabffb
	if (!applet->mm1_running) {
Packit fabffb
		g_warning ("Cannot grab information for modem at %s: No ModemManager support",
Packit fabffb
		           nm_device_get_udi (device));
Packit fabffb
		return;
Packit fabffb
	}
Packit fabffb
Packit fabffb
	modem_object = g_dbus_object_manager_get_object (G_DBUS_OBJECT_MANAGER (applet->mm1),
Packit fabffb
	                                                 nm_device_get_udi (device));
Packit fabffb
	if (!modem_object) {
Packit fabffb
		g_warning ("Cannot grab information for modem at %s: Not found",
Packit fabffb
		           nm_device_get_udi (device));
Packit fabffb
		return;
Packit fabffb
	}
Packit fabffb
Packit fabffb
	info = g_slice_new0 (BroadbandDeviceInfo);
Packit fabffb
	info->applet = applet;
Packit fabffb
	info->device = device;
Packit fabffb
	info->mm_object = MM_OBJECT (modem_object);
Packit fabffb
	info->mm_modem = mm_object_get_modem (info->mm_object);
Packit fabffb
	info->cancellable = g_cancellable_new ();
Packit fabffb
Packit fabffb
	/* Setup signals */
Packit fabffb
Packit fabffb
	g_signal_connect (info->mm_modem,
Packit fabffb
	                  "state-changed",
Packit fabffb
	                  G_CALLBACK (modem_state_changed),
Packit fabffb
	                  info);
Packit fabffb
	g_signal_connect (info->mm_modem,
Packit fabffb
	                  "notify::signal-quality",
Packit fabffb
	                  G_CALLBACK (signal_quality_updated),
Packit fabffb
	                  info);
Packit fabffb
	g_signal_connect (info->mm_modem,
Packit fabffb
	                  "notify::access-technologies",
Packit fabffb
	                  G_CALLBACK (access_technologies_updated),
Packit fabffb
	                  info);
Packit fabffb
Packit fabffb
	/* Load initial values */
Packit fabffb
	signal_quality_updated (NULL, NULL, info);
Packit fabffb
	access_technologies_updated (NULL, NULL, info);
Packit fabffb
	if (mm_modem_get_state (info->mm_modem) >= MM_MODEM_STATE_ENABLED)
Packit fabffb
		setup_signals (info, TRUE);
Packit fabffb
Packit fabffb
	/* Asynchronously get SIM */
Packit fabffb
	mm_modem_get_sim (info->mm_modem,
Packit fabffb
	                  NULL, /* cancellable */
Packit fabffb
	                  (GAsyncReadyCallback)modem_get_sim_ready,
Packit fabffb
	                  info);
Packit fabffb
Packit fabffb
	/* Store device info */
Packit fabffb
	g_object_set_data_full (G_OBJECT (modem),
Packit fabffb
	                        BROADBAND_INFO_TAG,
Packit fabffb
	                        info,
Packit fabffb
	                        (GDestroyNotify)broadband_device_info_free);
Packit fabffb
}
Packit fabffb
Packit fabffb
/********************************************************************/
Packit fabffb
Packit fabffb
NMADeviceClass *
Packit fabffb
applet_device_broadband_get_class (NMApplet *applet)
Packit fabffb
{
Packit fabffb
	NMADeviceClass *dclass;
Packit fabffb
Packit fabffb
	dclass = g_slice_new0 (NMADeviceClass);
Packit fabffb
	if (!dclass)
Packit fabffb
		return NULL;
Packit fabffb
Packit fabffb
	dclass->new_auto_connection = new_auto_connection;
Packit fabffb
	dclass->add_menu_item = add_menu_item;
Packit fabffb
	dclass->device_added = device_added;
Packit fabffb
	dclass->notify_connected = notify_connected;
Packit fabffb
	dclass->get_icon = get_icon;
Packit fabffb
	dclass->get_secrets = get_secrets;
Packit fabffb
	dclass->secrets_request_size = sizeof (MobileHelperSecretsInfo);
Packit fabffb
Packit fabffb
	return dclass;
Packit fabffb
}