[network-manager-applet/aleksander/mm1-applet: 8/10] applet: new support for the 'ModemManager1' interface
- From: Aleksander Morgado <aleksm src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [network-manager-applet/aleksander/mm1-applet: 8/10] applet: new support for the 'ModemManager1' interface
- Date: Tue, 15 Jan 2013 10:28:45 +0000 (UTC)
commit 079dcf1b3da56f843bcf327df5fa004fe9343a57
Author: Aleksander Morgado <aleksander lanedo com>
Date: Thu Dec 13 14:22:46 2012 +0100
applet: new support for the 'ModemManager1' interface
src/Makefile.am | 7 +
src/applet-device-broadband.c | 1079 +++++++++++++++++++++++++++++++++++++++++
src/applet-device-broadband.h | 31 ++
src/applet-device-cdma.c | 6 +-
src/applet-device-gsm.c | 20 +-
src/applet.c | 99 ++++
src/applet.h | 12 +
7 files changed, 1241 insertions(+), 13 deletions(-)
---
diff --git a/src/Makefile.am b/src/Makefile.am
index 6d5ecee..05eaaf0 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -72,6 +72,13 @@ nm_applet_LDADD = \
${top_builddir}/src/wireless-security/libwireless-security.la \
${top_builddir}/src/libnm-gtk/libnm-gtk.la
+if WITH_MODEM_MANAGER_1
+nm_applet_SOURCES += \
+ applet-device-broadband.h \
+ applet-device-broadband.c
+nm_applet_CPPFLAGS += $(MM_GLIB_CFLAGS)
+nm_applet_LDADD += $(MM_GLIB_LIBS)
+endif
if BUILD_MIGRATION_TOOL
SUBDIRS += gconf-helpers
diff --git a/src/applet-device-broadband.c b/src/applet-device-broadband.c
new file mode 100644
index 0000000..cbaf763
--- /dev/null
+++ b/src/applet-device-broadband.c
@@ -0,0 +1,1079 @@
+/* -*- Mode: C; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */
+/* NetworkManager Applet -- allow user control over networking
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * (C) Copyright 2012 Aleksander Morgado <aleksander gnu org>
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <ctype.h>
+
+#include <glib/gi18n.h>
+#include <gtk/gtk.h>
+
+#include <nm-device.h>
+#include <nm-device-modem.h>
+#include <nm-utils.h>
+#include <gnome-keyring.h>
+
+#include "applet.h"
+#include "applet-device-broadband.h"
+#include "applet-dialogs.h"
+#include "mobile-helpers.h"
+#include "nm-ui-utils.h"
+#include "mb-menu-item.h"
+
+typedef struct {
+ NMApplet *applet;
+ NMDevice *device;
+
+ MMObject *mm_object;
+ MMModem *mm_modem;
+ MMModem3gpp *mm_modem_3gpp;
+ MMModemCdma *mm_modem_cdma;
+ MMSim *mm_sim;
+
+ /* Operator info */
+ gchar *operator_name;
+ guint operator_name_update_id;
+ guint operator_code_update_id;
+ guint sid_update_id;
+ NMAMobileProvidersDatabase *mpd;
+
+ /* Unlock dialog stuff */
+ GtkWidget *dialog;
+ gpointer keyring_id;
+} BroadbandDeviceInfo;
+
+/********************************************************************/
+
+static gboolean
+new_auto_connection (NMDevice *device,
+ gpointer dclass_data,
+ AppletNewAutoConnectionCallback callback,
+ gpointer callback_data)
+{
+ return mobile_helper_wizard (nm_device_modem_get_current_capabilities (NM_DEVICE_MODEM (device)),
+ callback,
+ callback_data);
+}
+
+/********************************************************************/
+
+typedef struct {
+ NMApplet *applet;
+ NMDevice *device;
+} ConnectNetworkInfo;
+
+static void
+add_and_activate_connection_done (NMClient *client,
+ NMActiveConnection *active,
+ const char *connection_path,
+ GError *error,
+ gpointer user_data)
+{
+ if (error)
+ g_warning ("Failed to add/activate connection: (%d) %s", error->code, error->message);
+}
+
+static void
+wizard_done (NMConnection *connection,
+ gboolean auto_created,
+ gboolean canceled,
+ gpointer user_data)
+{
+ ConnectNetworkInfo *info = user_data;
+
+ if (canceled == FALSE) {
+ g_return_if_fail (connection != NULL);
+
+ /* Ask NM to add the new connection and activate it; NM will fill in the
+ * missing details based on the specific object and the device.
+ */
+ nm_client_add_and_activate_connection (info->applet->nm_client,
+ connection,
+ info->device,
+ "/",
+ add_and_activate_connection_done,
+ info->applet);
+ }
+
+ g_object_unref (info->device);
+ g_free (info);
+}
+
+void
+applet_broadband_connect_network (NMApplet *applet,
+ NMDevice *device)
+{
+ ConnectNetworkInfo *info;
+
+ info = g_malloc0 (sizeof (*info));
+ info->applet = applet;
+ info->device = g_object_ref (device);
+
+ if (!mobile_helper_wizard (nm_device_modem_get_current_capabilities (NM_DEVICE_MODEM (device)),
+ wizard_done,
+ info)) {
+ g_warning ("Couldn't run mobile wizard for broadband device");
+ g_object_unref (info->device);
+ g_free (info);
+ }
+}
+
+/********************************************************************/
+
+static void unlock_dialog_new (NMDevice *device,
+ BroadbandDeviceInfo *info);
+
+static void
+unlock_dialog_destroy (BroadbandDeviceInfo *info)
+{
+ gtk_widget_destroy (info->dialog);
+ info->dialog = NULL;
+}
+
+static void
+dialog_sim_send_puk_ready (MMSim *sim,
+ GAsyncResult *res,
+ BroadbandDeviceInfo *info)
+{
+ GError *error = NULL;
+
+ if (!mm_sim_send_puk_finish (sim, res, &error)) {
+ const gchar *msg;
+
+ if (g_error_matches (error,
+ MM_MOBILE_EQUIPMENT_ERROR,
+ MM_MOBILE_EQUIPMENT_ERROR_INCORRECT_PASSWORD))
+ msg = _("Wrong PUK code; please contact your provider.");
+ else {
+ g_dbus_error_strip_remote_error (error);
+ msg = error ? error->message : NULL;
+ }
+
+ applet_mobile_pin_dialog_stop_spinner (info->dialog, msg);
+
+ g_warning ("Failed to send PUK to devid: '%s' simid: '%s' : %s",
+ mm_modem_get_device_identifier (info->mm_modem),
+ mm_sim_get_identifier (info->mm_sim),
+ error->message);
+
+ g_error_free (error);
+ return;
+ }
+
+ /* Good */
+ unlock_dialog_destroy (info);
+}
+
+static void
+dialog_sim_send_pin_ready (MMSim *sim,
+ GAsyncResult *res,
+ BroadbandDeviceInfo *info)
+{
+ GError *error = NULL;
+
+ if (!mm_sim_send_pin_finish (sim, res, &error)) {
+ if (g_error_matches (error,
+ MM_MOBILE_EQUIPMENT_ERROR,
+ MM_MOBILE_EQUIPMENT_ERROR_SIM_PUK)) {
+ /* Destroy previous dialog and launch a new one rebuilt to ask for PUK */
+ unlock_dialog_destroy (info);
+ unlock_dialog_new (info->device, info);
+ } else {
+ const gchar *msg = NULL;
+
+ /* Report error and re-try PIN request */
+ if (g_error_matches (error,
+ MM_MOBILE_EQUIPMENT_ERROR,
+ MM_MOBILE_EQUIPMENT_ERROR_INCORRECT_PASSWORD))
+ msg = _("Wrong PIN code; please contact your provider.");
+ else {
+ g_dbus_error_strip_remote_error (error);
+ msg = error ? error->message : NULL;
+ }
+
+ applet_mobile_pin_dialog_stop_spinner (info->dialog, msg);
+ }
+
+ g_warning ("Failed to send PIN to devid: '%s' simid: '%s' : %s",
+ mm_modem_get_device_identifier (info->mm_modem),
+ mm_sim_get_identifier (info->mm_sim),
+ error->message);
+
+ g_error_free (error);
+ return;
+ }
+
+ /* Good */
+
+ if (applet_mobile_pin_dialog_get_auto_unlock (info->dialog)) {
+ const gchar *code1;
+
+ code1 = applet_mobile_pin_dialog_get_entry1 (info->dialog);
+ mobile_helper_save_pin_in_keyring (mm_modem_get_device_identifier (info->mm_modem),
+ mm_sim_get_identifier (info->mm_sim),
+ code1);
+ } else
+ mobile_helper_delete_pin_in_keyring (mm_modem_get_device_identifier (info->mm_modem));
+
+ unlock_dialog_destroy (info);
+}
+
+static void
+unlock_dialog_response (GtkDialog *dialog,
+ gint response,
+ gpointer user_data)
+{
+ BroadbandDeviceInfo *info = user_data;
+ const char *code1, *code2;
+ MMModemLock lock;
+
+ if (response == GTK_RESPONSE_CANCEL || response == GTK_RESPONSE_DELETE_EVENT) {
+ unlock_dialog_destroy (info);
+ return;
+ }
+
+ lock = GPOINTER_TO_UINT (g_object_get_data (G_OBJECT (info->dialog), "unlock-code"));
+ g_assert (lock == MM_MODEM_LOCK_SIM_PIN || lock == MM_MODEM_LOCK_SIM_PUK);
+
+ /* Start the spinner to show the progress of the unlock */
+ applet_mobile_pin_dialog_start_spinner (info->dialog, _("Sending unlock code..."));
+
+ code1 = applet_mobile_pin_dialog_get_entry1 (info->dialog);
+ if (!code1 || !strlen (code1)) {
+ g_warn_if_fail (code1 != NULL);
+ g_warn_if_fail (strlen (code1));
+ unlock_dialog_destroy (info);
+ return;
+ }
+
+ /* Send the code to ModemManager */
+ if (lock == MM_MODEM_LOCK_SIM_PIN) {
+ mm_sim_send_pin (info->mm_sim,
+ code1,
+ NULL, /* cancellable */
+ (GAsyncReadyCallback)dialog_sim_send_pin_ready,
+ info);
+ return;
+ }
+
+ if (lock == MM_MODEM_LOCK_SIM_PUK) {
+ code2 = applet_mobile_pin_dialog_get_entry2 (info->dialog);
+ if (!code2) {
+ g_warn_if_fail (code2 != NULL);
+ unlock_dialog_destroy (info);
+ return;
+ }
+
+ mm_sim_send_puk (info->mm_sim,
+ code1, /* puk */
+ code2, /* new pin */
+ NULL, /* cancellable */
+ (GAsyncReadyCallback)dialog_sim_send_puk_ready,
+ info);
+ return;
+ }
+
+ g_assert_not_reached ();
+}
+
+static void
+unlock_dialog_new (NMDevice *device,
+ BroadbandDeviceInfo *info)
+{
+ MMModemLock lock;
+ const gchar *unlock_required;
+
+ if (info->dialog)
+ return;
+
+ /* We can only unlock PIN or PUK here */
+ lock = mm_modem_get_unlock_required (info->mm_modem);
+ if (lock == MM_MODEM_LOCK_SIM_PIN)
+ unlock_required = "sim-pin";
+ else if (lock == MM_MODEM_LOCK_SIM_PUK)
+ unlock_required = "sim-puk";
+ else {
+ g_warning ("Cannot unlock devid: '%s' simid: '%s' : unhandled lock code '%s'",
+ mm_modem_get_device_identifier (info->mm_modem),
+ mm_sim_get_identifier (info->mm_sim),
+ mm_modem_lock_get_string (lock));
+ return;
+ }
+
+ info->dialog = applet_mobile_pin_dialog_new (unlock_required,
+ nma_utils_get_device_description (device));
+
+ g_object_set_data (G_OBJECT (info->dialog), "unlock-code", GUINT_TO_POINTER (lock));
+ g_signal_connect (info->dialog, "response", G_CALLBACK (unlock_dialog_response), info);
+
+ /* Need to resize the dialog after hiding widgets */
+ gtk_window_resize (GTK_WINDOW (info->dialog), 400, 100);
+
+ /* Show the dialog */
+ gtk_widget_realize (info->dialog);
+ gtk_window_present (GTK_WINDOW (info->dialog));
+}
+
+static void
+autounlock_sim_send_pin_ready (MMSim *sim,
+ GAsyncResult *res,
+ BroadbandDeviceInfo *info)
+{
+ GError *error = NULL;
+
+ if (!mm_sim_send_pin_finish (sim, res, &error)) {
+ g_warning ("Failed to auto-unlock devid: '%s' simid: '%s' : %s",
+ mm_modem_get_device_identifier (info->mm_modem),
+ mm_sim_get_identifier (info->mm_sim),
+ error->message);
+ g_error_free (error);
+
+ /* Remove PIN from keyring right away */
+ mobile_helper_delete_pin_in_keyring (mm_modem_get_device_identifier (info->mm_modem));
+
+ /* Ask the user */
+ unlock_dialog_new (info->device, info);
+ }
+}
+
+static void
+keyring_pin_check_cb (GnomeKeyringResult result,
+ GList *list,
+ gpointer user_data)
+{
+ BroadbandDeviceInfo *info = user_data;
+ GList *iter;
+ const char *pin = NULL;
+ const char *simid;
+
+ info->keyring_id = NULL;
+
+ if (result != GNOME_KEYRING_RESULT_OK) {
+ /* No saved PIN, just ask the user */
+ unlock_dialog_new (info->device, info);
+ return;
+ }
+
+ /* Look for a result with a matching "simid" attribute since that's
+ * better than just using a matching "devid". The PIN is really tied
+ * to the SIM, not the modem itself.
+ */
+ simid = mm_sim_get_identifier (info->mm_sim);
+ if (simid) {
+ for (iter = list;
+ (pin == NULL) && iter;
+ iter = g_list_next (iter)) {
+ GnomeKeyringFound *found = iter->data;
+ int i;
+
+ /* Look for a matching "simid" attribute */
+ for (i = 0; (pin == NULL) && i < found->attributes->len; i++) {
+ GnomeKeyringAttribute attr = gnome_keyring_attribute_list_index (found->attributes, i);
+
+ if (g_strcmp0 (attr.name, "simid") == 0 &&
+ attr.type == GNOME_KEYRING_ATTRIBUTE_TYPE_STRING &&
+ g_strcmp0 (attr.value.string, simid) == 0) {
+ pin = found->secret;
+ break;
+ }
+ }
+ }
+ }
+
+ if (pin == NULL) {
+ /* Fall back to the first result's PIN */
+ pin = ((GnomeKeyringFound *) list->data)->secret;
+ if (pin == NULL) {
+ /* Should never get here */
+ g_warn_if_fail (pin != NULL);
+ unlock_dialog_new (info->device, info);
+ return;
+ }
+ }
+
+ mm_sim_send_pin (info->mm_sim,
+ pin,
+ NULL, /* cancellable */
+ (GAsyncReadyCallback)autounlock_sim_send_pin_ready,
+ info);
+}
+
+static void
+modem_get_sim_ready (MMModem *modem,
+ GAsyncResult *res,
+ BroadbandDeviceInfo *info)
+{
+ info->mm_sim = mm_modem_get_sim_finish (modem, res, NULL);
+ if (!info->mm_sim)
+ /* Ok, the modem may not need it actually */
+ return;
+
+ /* Do nothing if we're not locked */
+ if (mm_modem_get_state (info->mm_modem) != MM_MODEM_STATE_LOCKED)
+ return;
+
+ /* If we have a device ID ask the keyring for any saved SIM-PIN codes */
+ if (mm_modem_get_device_identifier (info->mm_modem) &&
+ mm_modem_get_unlock_required (info->mm_modem) == MM_MODEM_LOCK_SIM_PIN) {
+ g_warn_if_fail (info->keyring_id == NULL);
+ info->keyring_id = gnome_keyring_find_itemsv (GNOME_KEYRING_ITEM_GENERIC_SECRET,
+ keyring_pin_check_cb,
+ info,
+ NULL,
+ "devid",
+ GNOME_KEYRING_ATTRIBUTE_TYPE_STRING,
+ mm_modem_get_device_identifier (info->mm_modem),
+ NULL);
+ return;
+ }
+
+ /* Couldn't get a device ID, but unlock required; present dialog */
+ unlock_dialog_new (info->device, info);
+}
+
+/********************************************************************/
+
+static gboolean
+get_secrets (SecretsRequest *req,
+ GError **error)
+{
+ NMDevice *device;
+ BroadbandDeviceInfo *devinfo;
+
+ device = applet_get_device_for_connection (req->applet, req->connection);
+ if (!device) {
+ g_set_error (error,
+ NM_SECRET_AGENT_ERROR,
+ NM_SECRET_AGENT_ERROR_INTERNAL_ERROR,
+ "%s.%d (%s): failed to find device for active connection.",
+ __FILE__, __LINE__, __func__);
+ return FALSE;
+ }
+
+ if (!mobile_helper_get_secrets (nm_device_modem_get_current_capabilities (NM_DEVICE_MODEM (device)),
+ req,
+ error))
+ return FALSE;
+
+ devinfo = g_object_get_data (G_OBJECT (device), "devinfo");
+ g_assert (devinfo);
+
+ /* A GetSecrets PIN dialog overrides the initial unlock dialog */
+ if (devinfo->dialog)
+ unlock_dialog_destroy (devinfo);
+
+ return TRUE;
+}
+
+/********************************************************************/
+
+static guint32
+broadband_state_to_mb_state (BroadbandDeviceInfo *info)
+{
+ MMModemState state;
+
+ state = mm_modem_get_state (info->mm_modem);
+
+ switch (state) {
+ case MM_MODEM_STATE_FAILED:
+ case MM_MODEM_STATE_UNKNOWN:
+ g_warn_if_reached ();
+ case MM_MODEM_STATE_INITIALIZING:
+ case MM_MODEM_STATE_LOCKED:
+ case MM_MODEM_STATE_DISABLED:
+ case MM_MODEM_STATE_DISABLING:
+ case MM_MODEM_STATE_ENABLING:
+ return MB_STATE_UNKNOWN;
+
+ case MM_MODEM_STATE_ENABLED:
+ return MB_STATE_IDLE;
+
+ case MM_MODEM_STATE_SEARCHING:
+ return MB_STATE_SEARCHING;
+
+ case MM_MODEM_STATE_REGISTERED:
+ case MM_MODEM_STATE_DISCONNECTING:
+ case MM_MODEM_STATE_CONNECTING:
+ case MM_MODEM_STATE_CONNECTED:
+ break;
+ default:
+ g_warn_if_reached ();
+ return MB_STATE_UNKNOWN;
+ }
+
+ /* home or roaming? */
+
+ if (info->mm_modem_3gpp) {
+ switch (mm_modem_3gpp_get_registration_state (info->mm_modem_3gpp)) {
+ case MM_MODEM_3GPP_REGISTRATION_STATE_HOME:
+ return MB_STATE_HOME;
+ case MM_MODEM_3GPP_REGISTRATION_STATE_ROAMING:
+ return MB_STATE_ROAMING;
+ default:
+ /* Skip, we may be registered in EVDO/CDMA1x instead... */
+ break;
+ }
+ }
+
+ if (info->mm_modem_cdma) {
+ /* EVDO state overrides 1X state for now */
+ switch (mm_modem_cdma_get_evdo_registration_state (info->mm_modem_cdma)) {
+ case MM_MODEM_CDMA_REGISTRATION_STATE_HOME:
+ return MB_STATE_HOME;
+ case MM_MODEM_CDMA_REGISTRATION_STATE_ROAMING:
+ return MB_STATE_ROAMING;
+ case MM_MODEM_CDMA_REGISTRATION_STATE_REGISTERED:
+ /* Assume home... */
+ return MB_STATE_HOME;
+ default:
+ /* Skip, we may be registered in CDMA1x instead... */
+ break;
+ }
+
+ switch (mm_modem_cdma_get_cdma1x_registration_state (info->mm_modem_cdma)) {
+ case MM_MODEM_CDMA_REGISTRATION_STATE_HOME:
+ return MB_STATE_HOME;
+ case MM_MODEM_CDMA_REGISTRATION_STATE_ROAMING:
+ return MB_STATE_ROAMING;
+ case MM_MODEM_CDMA_REGISTRATION_STATE_REGISTERED:
+ /* Assume home... */
+ return MB_STATE_HOME;
+ default:
+ break;
+ }
+ }
+
+ return MB_STATE_UNKNOWN;
+}
+
+static guint32
+broadband_act_to_mb_act (BroadbandDeviceInfo *info)
+{
+ MMModemAccessTechnology act;
+
+ act = mm_modem_get_access_technologies (info->mm_modem);
+
+ g_return_val_if_fail (act != MM_MODEM_ACCESS_TECHNOLOGY_ANY, MB_TECH_UNKNOWN);
+
+ /* We get a MASK of values, but we need to report only ONE.
+ * So just return the 'best' one found */
+
+ /* Prefer 4G technologies over 3G and 2G */
+ if (act & MM_MODEM_ACCESS_TECHNOLOGY_LTE)
+ return MB_TECH_LTE;
+
+ /* Prefer 3GPP 3G technologies over 3GPP 2G or 3GPP2 */
+ if (act & MM_MODEM_ACCESS_TECHNOLOGY_HSPA_PLUS)
+ return MB_TECH_HSPA_PLUS;
+ if (act & MM_MODEM_ACCESS_TECHNOLOGY_HSPA)
+ return MB_TECH_HSPA;
+ if (act & MM_MODEM_ACCESS_TECHNOLOGY_HSUPA)
+ return MB_TECH_HSUPA;
+ if (act & MM_MODEM_ACCESS_TECHNOLOGY_HSDPA)
+ return MB_TECH_HSDPA;
+ if (act & MM_MODEM_ACCESS_TECHNOLOGY_UMTS)
+ return MB_TECH_UMTS;
+
+ /* Prefer 3GPP2 3G technologies over 2G */
+ if (act & MM_MODEM_ACCESS_TECHNOLOGY_EVDO0 ||
+ act & MM_MODEM_ACCESS_TECHNOLOGY_EVDOA ||
+ act & MM_MODEM_ACCESS_TECHNOLOGY_EVDOB)
+ return MB_TECH_EVDO;
+
+ /* Prefer 3GPP 2G technologies over 3GPP2 2G */
+ if (act & MM_MODEM_ACCESS_TECHNOLOGY_EDGE)
+ return MB_TECH_EDGE;
+ if (act & MM_MODEM_ACCESS_TECHNOLOGY_GPRS)
+ return MB_TECH_GPRS;
+ if (act & MM_MODEM_ACCESS_TECHNOLOGY_GSM ||
+ act & MM_MODEM_ACCESS_TECHNOLOGY_GSM_COMPACT)
+ return MB_TECH_GSM;
+
+ /* Last, 3GPP2 2G */
+ if (act & MM_MODEM_ACCESS_TECHNOLOGY_1XRTT)
+ return MB_TECH_1XRTT;
+
+ return MB_TECH_UNKNOWN;
+}
+
+static GdkPixbuf *
+get_icon (NMDevice *device,
+ NMDeviceState state,
+ NMConnection *connection,
+ char **tip,
+ NMApplet *applet)
+{
+ BroadbandDeviceInfo *info;
+
+ info = g_object_get_data (G_OBJECT (device), "devinfo");
+ g_assert (info);
+
+ return mobile_helper_get_icon (device,
+ state,
+ connection,
+ tip,
+ applet,
+ broadband_state_to_mb_state (info),
+ broadband_act_to_mb_act (info),
+ mm_modem_get_signal_quality (info->mm_modem, NULL),
+ (mm_modem_get_state (info->mm_modem) >= MM_MODEM_STATE_ENABLED));
+}
+
+/********************************************************************/
+
+typedef struct {
+ NMApplet *applet;
+ NMDevice *device;
+ NMConnection *connection;
+} BroadbandMenuItemInfo;
+
+static void
+menu_item_info_destroy (BroadbandMenuItemInfo *info)
+{
+ g_object_unref (G_OBJECT (info->device));
+ if (info->connection)
+ g_object_unref (info->connection);
+ g_slice_free (BroadbandMenuItemInfo, info);
+}
+
+static void
+menu_item_activate (GtkMenuItem *item,
+ BroadbandMenuItemInfo *info)
+{
+ applet_menu_item_activate_helper (info->device,
+ info->connection,
+ "/",
+ info->applet,
+ info);
+}
+
+static void
+add_connection_item (NMDevice *device,
+ NMConnection *connection,
+ GtkWidget *item,
+ GtkWidget *menu,
+ NMApplet *applet)
+{
+ BroadbandMenuItemInfo *info;
+
+ info = g_slice_new0 (BroadbandMenuItemInfo);
+ info->applet = applet;
+ info->device = g_object_ref (G_OBJECT (device));
+ info->connection = connection ? g_object_ref (connection) : NULL;
+
+ g_signal_connect_data (item, "activate",
+ G_CALLBACK (menu_item_activate),
+ info,
+ (GClosureNotify) menu_item_info_destroy, 0);
+
+ gtk_menu_shell_append (GTK_MENU_SHELL (menu), item);
+}
+
+static void
+add_menu_item (NMDevice *device,
+ guint32 n_devices,
+ NMConnection *active,
+ GtkWidget *menu,
+ NMApplet *applet)
+{
+ BroadbandDeviceInfo *info;
+ char *text;
+ GtkWidget *item;
+ GSList *connections, *all, *iter;
+
+ info = g_object_get_data (G_OBJECT (device), "devinfo");
+
+ all = applet_get_all_connections (applet);
+ connections = nm_device_filter_connections (device, all);
+ g_slist_free (all);
+
+ if (n_devices > 1) {
+ const char *desc;
+
+ desc = nma_utils_get_device_description (device);
+ text = g_strdup_printf (_("Mobile Broadband (%s)"), desc);
+ } else {
+ text = g_strdup (_("Mobile Broadband"));
+ }
+
+ item = applet_menu_item_create_device_item_helper (device, applet, text);
+ gtk_widget_set_sensitive (item, FALSE);
+ gtk_menu_shell_append (GTK_MENU_SHELL (menu), item);
+ gtk_widget_show (item);
+ g_free (text);
+
+ /* Add the active connection */
+ if (active) {
+ NMSettingConnection *s_con;
+
+ s_con = nm_connection_get_setting_connection (active);
+ g_assert (s_con);
+
+ item = nm_mb_menu_item_new (nm_setting_connection_get_id (s_con),
+ mm_modem_get_signal_quality (info->mm_modem, NULL),
+ info->operator_name,
+ TRUE,
+ broadband_act_to_mb_act (info),
+ broadband_state_to_mb_state (info),
+ mm_modem_get_state (info->mm_modem) >= MM_MODEM_STATE_ENABLED,
+ applet);
+ gtk_widget_set_sensitive (GTK_WIDGET (item), TRUE);
+ add_connection_item (device, active, item, menu, applet);
+ }
+
+ /* Notify user of unmanaged or unavailable device */
+ if (nm_device_get_state (device) > NM_DEVICE_STATE_DISCONNECTED) {
+ item = nma_menu_device_get_menu_item (device, applet, NULL);
+ if (item) {
+ gtk_menu_shell_append (GTK_MENU_SHELL (menu), item);
+ gtk_widget_show (item);
+ }
+ } else {
+ /* Otherwise show idle registration state or disabled */
+ item = nm_mb_menu_item_new (NULL,
+ mm_modem_get_signal_quality (info->mm_modem, NULL),
+ info->operator_name,
+ FALSE,
+ broadband_act_to_mb_act (info),
+ broadband_state_to_mb_state (info),
+ mm_modem_get_state (info->mm_modem) >= MM_MODEM_STATE_ENABLED,
+ applet);
+ gtk_widget_set_sensitive (GTK_WIDGET (item), FALSE);
+ gtk_menu_shell_append (GTK_MENU_SHELL (menu), item);
+ }
+
+ /* Add the default / inactive connection items */
+ if (!nma_menu_device_check_unusable (device)) {
+ if ((!active && g_slist_length (connections)) || (active && g_slist_length (connections) > 1))
+ applet_menu_item_add_complex_separator_helper (menu, applet, _("Available"), -1);
+
+ if (g_slist_length (connections)) {
+ for (iter = connections; iter; iter = g_slist_next (iter)) {
+ NMConnection *connection = NM_CONNECTION (iter->data);
+
+ if (connection != active) {
+ item = applet_new_menu_item_helper (connection, NULL, FALSE);
+ add_connection_item (device, connection, item, menu, applet);
+ }
+ }
+ } else {
+ /* Default connection item */
+ item = gtk_check_menu_item_new_with_label (_("New Mobile Broadband connection..."));
+ add_connection_item (device, NULL, item, menu, applet);
+ }
+ }
+
+ g_slist_free (connections);
+}
+
+/********************************************************************/
+
+static void
+device_state_changed (NMDevice *device,
+ NMDeviceState new_state,
+ NMDeviceState old_state,
+ NMDeviceStateReason reason,
+ NMApplet *applet)
+{
+ NMConnection *connection;
+ NMSettingConnection *s_con = NULL;
+ char *str = NULL;
+
+ if (new_state != NM_DEVICE_STATE_ACTIVATED)
+ return;
+
+ connection = applet_find_active_connection_for_device (device, applet, NULL);
+ if (connection) {
+ const char *id;
+
+ s_con = nm_connection_get_setting_connection (connection);
+ id = s_con ? nm_setting_connection_get_id (s_con) : NULL;
+ if (id)
+ str = g_strdup_printf (_("You are now connected to '%s'."), id);
+ }
+
+ applet_do_notify_with_pref (applet,
+ _("Connection Established"),
+ str ? str : _("You are now connected to the Mobile Broadband network."),
+ "nm-device-wwan",
+ PREF_DISABLE_CONNECTED_NOTIFICATIONS);
+ g_free (str);
+}
+
+/********************************************************************/
+
+static void
+signal_quality_updated (GObject *object,
+ GParamSpec *pspec,
+ BroadbandDeviceInfo *info)
+{
+ applet_schedule_update_icon (info->applet);
+}
+
+static void
+access_technologies_updated (GObject *object,
+ GParamSpec *pspec,
+ BroadbandDeviceInfo *info)
+{
+ applet_schedule_update_icon (info->applet);
+}
+
+static void
+operator_info_updated (GObject *object,
+ GParamSpec *pspec,
+ BroadbandDeviceInfo *info)
+{
+ g_free (info->operator_name);
+ info->operator_name = NULL;
+
+ /* Prefer 3GPP info if given */
+
+ if (info->mm_modem_3gpp) {
+ info->operator_name = (mobile_helper_parse_3gpp_operator_name (
+ &(info->mpd),
+ mm_modem_3gpp_get_operator_name (info->mm_modem_3gpp),
+ mm_modem_3gpp_get_operator_code (info->mm_modem_3gpp)));
+ if (info->operator_name)
+ return;
+ }
+
+ if (info->mm_modem_cdma)
+ info->operator_name = (mobile_helper_parse_3gpp2_operator_name (
+ &(info->mpd),
+ mm_modem_cdma_get_sid (info->mm_modem_cdma)));
+}
+
+static void
+setup_signals (BroadbandDeviceInfo *info,
+ gboolean enable)
+{
+ if (enable) {
+ g_assert (info->mm_modem_3gpp == NULL);
+ g_assert (info->mm_modem_cdma == NULL);
+ g_assert (info->operator_name_update_id == 0);
+ g_assert (info->operator_code_update_id == 0);
+ g_assert (info->sid_update_id == 0);
+
+ info->mm_modem_3gpp = mm_object_get_modem_3gpp (info->mm_object);
+ info->mm_modem_cdma = mm_object_get_modem_cdma (info->mm_object);
+
+ if (info->mm_modem_3gpp) {
+ info->operator_name_update_id = g_signal_connect (info->mm_modem_3gpp,
+ "notify::operator-name",
+ G_CALLBACK (operator_info_updated),
+ info);
+ info->operator_code_update_id = g_signal_connect (info->mm_modem_3gpp,
+ "notify::operator-code",
+ G_CALLBACK (operator_info_updated),
+ info);
+ }
+
+ if (info->mm_modem_cdma) {
+ info->sid_update_id = g_signal_connect (info->mm_modem_cdma,
+ "notify::sid",
+ G_CALLBACK (operator_info_updated),
+ info);
+ }
+
+ /* Load initial values */
+ operator_info_updated (NULL, NULL, info);
+ } else {
+ if (info->mm_modem_3gpp) {
+ if (info->operator_name_update_id) {
+ if (g_signal_handler_is_connected (info->mm_modem_3gpp, info->operator_name_update_id))
+ g_signal_handler_disconnect (info->mm_modem_3gpp, info->operator_name_update_id);
+ info->operator_name_update_id = 0;
+ }
+ if (info->operator_code_update_id) {
+ if (g_signal_handler_is_connected (info->mm_modem_3gpp, info->operator_code_update_id))
+ g_signal_handler_disconnect (info->mm_modem_3gpp, info->operator_code_update_id);
+ info->operator_code_update_id = 0;
+ }
+ g_clear_object (&info->mm_modem_3gpp);
+ }
+
+ if (info->mm_modem_cdma) {
+ if (info->sid_update_id) {
+ if (g_signal_handler_is_connected (info->mm_modem_cdma, info->sid_update_id))
+ g_signal_handler_disconnect (info->mm_modem_cdma, info->sid_update_id);
+ info->sid_update_id = 0;
+ }
+ g_clear_object (&info->mm_modem_cdma);
+ }
+ }
+}
+
+static void
+modem_state_changed (MMModem *object,
+ gint old,
+ gint new,
+ guint reason,
+ BroadbandDeviceInfo *info)
+{
+ /* Modem just got enabled */
+ if (old < MM_MODEM_STATE_ENABLED &&
+ new >= MM_MODEM_STATE_ENABLED) {
+ setup_signals (info, TRUE);
+ }
+ /* Modem just got disabled */
+ else if (old >= MM_MODEM_STATE_ENABLED &&
+ new < MM_MODEM_STATE_ENABLED) {
+ setup_signals (info, FALSE);
+ }
+
+ /* Modem just got registered */
+ if ((old < MM_MODEM_STATE_REGISTERED &&
+ new >= MM_MODEM_STATE_REGISTERED)) {
+ guint32 mb_state;
+
+ /* Notify about new registration info */
+ mb_state = broadband_state_to_mb_state (info);
+ if (mb_state == MB_STATE_HOME) {
+ applet_do_notify_with_pref (info->applet,
+ _("Mobile Broadband network."),
+ _("You are now registered on the home network."),
+ "nm-signal-100",
+ PREF_DISABLE_CONNECTED_NOTIFICATIONS);
+ } else if (mb_state == MB_STATE_ROAMING) {
+ applet_do_notify_with_pref (info->applet,
+ _("Mobile Broadband network."),
+ _("You are now registered on a roaming network."),
+ "nm-signal-100",
+ PREF_DISABLE_CONNECTED_NOTIFICATIONS);
+ }
+ }
+}
+
+/********************************************************************/
+
+static void
+broadband_device_info_free (BroadbandDeviceInfo *info)
+{
+ setup_signals (info, FALSE);
+
+ g_free (info->operator_name);
+ if (info->mpd)
+ g_object_unref (info->mpd);
+
+ if (info->mm_sim)
+ g_object_unref (info->mm_sim);
+ if (info->mm_modem)
+ g_object_unref (info->mm_modem);
+ if (info->mm_object)
+ g_object_unref (info->mm_object);
+
+ if (info->keyring_id)
+ gnome_keyring_cancel_request (info->keyring_id);
+ if (info->dialog)
+ unlock_dialog_destroy (info);
+
+ g_slice_free (BroadbandDeviceInfo, info);
+}
+
+static void
+device_added (NMDevice *device,
+ NMApplet *applet)
+{
+ NMDeviceModem *modem = NM_DEVICE_MODEM (device);
+ BroadbandDeviceInfo *info;
+ const char *udi;
+ GDBusObject *modem_object;
+
+ udi = nm_device_get_udi (device);
+ if (!udi)
+ return;
+
+ if (!applet->mm1) {
+ g_warning ("Cannot grab information for modem at %s: No ModemManager support",
+ nm_device_get_udi (device));
+ return;
+ }
+
+ modem_object = g_dbus_object_manager_get_object (G_DBUS_OBJECT_MANAGER (applet->mm1),
+ nm_device_get_udi (device));
+ if (!modem_object) {
+ g_warning ("Cannot grab information for modem at %s: Not found",
+ nm_device_get_udi (device));
+ return;
+ }
+
+ info = g_slice_new0 (BroadbandDeviceInfo);
+ info->applet = applet;
+ info->device = device;
+ info->mm_object = MM_OBJECT (modem_object);
+ info->mm_modem = mm_object_get_modem (info->mm_object);
+
+ /* Setup signals */
+
+ g_signal_connect (info->mm_modem,
+ "state-changed",
+ G_CALLBACK (modem_state_changed),
+ info);
+ g_signal_connect (info->mm_modem,
+ "notify::signal-quality",
+ G_CALLBACK (signal_quality_updated),
+ info);
+ g_signal_connect (info->mm_modem,
+ "notify::access-technologies",
+ G_CALLBACK (access_technologies_updated),
+ info);
+
+ /* Load initial values */
+ signal_quality_updated (NULL, NULL, info);
+ access_technologies_updated (NULL, NULL, info);
+ if (mm_modem_get_state (info->mm_modem) >= MM_MODEM_STATE_ENABLED)
+ setup_signals (info, TRUE);
+
+ /* Asynchronously get SIM */
+ mm_modem_get_sim (info->mm_modem,
+ NULL, /* cancellable */
+ (GAsyncReadyCallback)modem_get_sim_ready,
+ info);
+
+ /* Store device info */
+ g_object_set_data_full (G_OBJECT (modem),
+ "devinfo",
+ info,
+ (GDestroyNotify)broadband_device_info_free);
+}
+
+/********************************************************************/
+
+NMADeviceClass *
+applet_device_broadband_get_class (NMApplet *applet)
+{
+ NMADeviceClass *dclass;
+
+ dclass = g_slice_new0 (NMADeviceClass);
+ if (!dclass)
+ return NULL;
+
+ dclass->new_auto_connection = new_auto_connection;
+ dclass->add_menu_item = add_menu_item;
+ dclass->device_added = device_added;
+ dclass->device_state_changed = device_state_changed;
+ dclass->get_icon = get_icon;
+ dclass->get_secrets = get_secrets;
+ dclass->secrets_request_size = sizeof (MobileHelperSecretsInfo);
+
+ return dclass;
+}
diff --git a/src/applet-device-broadband.h b/src/applet-device-broadband.h
new file mode 100644
index 0000000..1d3f2da
--- /dev/null
+++ b/src/applet-device-broadband.h
@@ -0,0 +1,31 @@
+/* -*- Mode: C; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */
+/* NetworkManager Applet -- allow user control over networking
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * (C) Copyright 2012 Aleksander Morgado <aleksander gnu org>
+ */
+
+#ifndef __APPLET_DEVICE_BROADBAND_H__
+#define __APPLET_DEVICE_BROADBAND_H__
+
+#include "applet.h"
+
+NMADeviceClass *applet_device_broadband_get_class (NMApplet *applet);
+
+void applet_broadband_connect_network (NMApplet *applet,
+ NMDevice *device);
+
+#endif /* __APPLET_DEVICE_BROADBAND_H__ */
diff --git a/src/applet-device-cdma.c b/src/applet-device-cdma.c
index ed9ac56..91f71f6 100644
--- a/src/applet-device-cdma.c
+++ b/src/applet-device-cdma.c
@@ -623,7 +623,7 @@ signal_quality_changed_cb (DBusGProxy *proxy,
applet_schedule_update_icon (info->applet);
}
-#define MM_DBUS_INTERFACE_MODEM "org.freedesktop.ModemManager.Modem"
+#define MM_OLD_DBUS_INTERFACE_MODEM "org.freedesktop.ModemManager.Modem"
#define DBUS_TYPE_G_MAP_OF_VARIANT (dbus_g_type_get_map ("GHashTable", G_TYPE_STRING, G_TYPE_VALUE))
static void
@@ -635,7 +635,7 @@ modem_properties_changed (DBusGProxy *proxy,
CdmaDeviceInfo *info = user_data;
GValue *value;
- if (!strcmp (interface, MM_DBUS_INTERFACE_MODEM)) {
+ if (!strcmp (interface, MM_OLD_DBUS_INTERFACE_MODEM)) {
value = g_hash_table_lookup (props, "Enabled");
if (value && G_VALUE_HOLDS_BOOLEAN (value)) {
info->modem_enabled = g_value_get_boolean (value);
@@ -730,7 +730,7 @@ cdma_device_added (NMDevice *device, NMApplet *applet)
/* Ask whether the device is enabled */
dbus_g_proxy_begin_call (info->props_proxy, "Get",
enabled_reply, info, NULL,
- G_TYPE_STRING, MM_DBUS_INTERFACE_MODEM,
+ G_TYPE_STRING, MM_OLD_DBUS_INTERFACE_MODEM,
G_TYPE_STRING, "Enabled",
G_TYPE_INVALID);
}
diff --git a/src/applet-device-gsm.c b/src/applet-device-gsm.c
index 22e3f7a..4ffebcd 100644
--- a/src/applet-device-gsm.c
+++ b/src/applet-device-gsm.c
@@ -894,7 +894,7 @@ simid_reply (DBusGProxy *proxy, DBusGProxyCall *call, gpointer user_data)
check_start_polling (info);
}
-#define MM_DBUS_INTERFACE_MODEM_GSM_CARD "org.freedesktop.ModemManager.Modem.Gsm.Card"
+#define MM_OLD_DBUS_INTERFACE_MODEM_GSM_CARD "org.freedesktop.ModemManager.Modem.Gsm.Card"
static void
unlock_reply (DBusGProxy *proxy, DBusGProxyCall *call, gpointer user_data)
@@ -927,7 +927,7 @@ unlock_reply (DBusGProxy *proxy, DBusGProxyCall *call, gpointer user_data)
/* Get SIM card identifier */
dbus_g_proxy_begin_call (info->props_proxy, "Get",
simid_reply, info, NULL,
- G_TYPE_STRING, MM_DBUS_INTERFACE_MODEM_GSM_CARD,
+ G_TYPE_STRING, MM_OLD_DBUS_INTERFACE_MODEM_GSM_CARD,
G_TYPE_STRING, "SimIdentifier",
G_TYPE_INVALID);
}
@@ -1058,8 +1058,8 @@ signal_quality_changed_cb (DBusGProxy *proxy,
applet_schedule_update_icon (info->applet);
}
-#define MM_DBUS_INTERFACE_MODEM "org.freedesktop.ModemManager.Modem"
-#define MM_DBUS_INTERFACE_MODEM_GSM_NETWORK "org.freedesktop.ModemManager.Modem.Gsm.Network"
+#define MM_OLD_DBUS_INTERFACE_MODEM "org.freedesktop.ModemManager.Modem"
+#define MM_OLD_DBUS_INTERFACE_MODEM_GSM_NETWORK "org.freedesktop.ModemManager.Modem.Gsm.Network"
static void
modem_properties_changed (DBusGProxy *proxy,
@@ -1070,7 +1070,7 @@ modem_properties_changed (DBusGProxy *proxy,
GsmDeviceInfo *info = user_data;
GValue *value;
- if (!strcmp (interface, MM_DBUS_INTERFACE_MODEM)) {
+ if (!strcmp (interface, MM_OLD_DBUS_INTERFACE_MODEM)) {
value = g_hash_table_lookup (props, "UnlockRequired");
if (value && G_VALUE_HOLDS_STRING (value)) {
g_free (info->unlock_required);
@@ -1093,7 +1093,7 @@ modem_properties_changed (DBusGProxy *proxy,
}
check_start_polling (info);
}
- } else if (!strcmp (interface, MM_DBUS_INTERFACE_MODEM_GSM_NETWORK)) {
+ } else if (!strcmp (interface, MM_OLD_DBUS_INTERFACE_MODEM_GSM_NETWORK)) {
value = g_hash_table_lookup (props, "AccessTechnology");
if (value && G_VALUE_HOLDS_UINT (value)) {
info->act = g_value_get_uint (value);
@@ -1150,7 +1150,7 @@ gsm_device_added (NMDevice *device, NMApplet *applet)
info->net_proxy = dbus_g_proxy_new_for_name (info->bus,
"org.freedesktop.ModemManager",
udi,
- MM_DBUS_INTERFACE_MODEM_GSM_NETWORK);
+ MM_OLD_DBUS_INTERFACE_MODEM_GSM_NETWORK);
if (!info->net_proxy) {
g_message ("%s: failed to create GSM Network proxy.", __func__);
gsm_device_info_free (info);
@@ -1188,19 +1188,19 @@ gsm_device_added (NMDevice *device, NMApplet *applet)
/* Ask whether the device needs to be unlocked */
dbus_g_proxy_begin_call (info->props_proxy, "GetAll",
unlock_reply, info, NULL,
- G_TYPE_STRING, MM_DBUS_INTERFACE_MODEM,
+ G_TYPE_STRING, MM_OLD_DBUS_INTERFACE_MODEM,
G_TYPE_INVALID);
/* Ask whether the device is enabled */
dbus_g_proxy_begin_call (info->props_proxy, "Get",
enabled_reply, info, NULL,
- G_TYPE_STRING, MM_DBUS_INTERFACE_MODEM,
+ G_TYPE_STRING, MM_OLD_DBUS_INTERFACE_MODEM,
G_TYPE_STRING, "Enabled",
G_TYPE_INVALID);
dbus_g_proxy_begin_call (info->props_proxy, "Get",
access_tech_reply, info, NULL,
- G_TYPE_STRING, MM_DBUS_INTERFACE_MODEM_GSM_NETWORK,
+ G_TYPE_STRING, MM_OLD_DBUS_INTERFACE_MODEM_GSM_NETWORK,
G_TYPE_STRING, "AccessTechnology",
G_TYPE_INVALID);
}
diff --git a/src/applet.c b/src/applet.c
index 21b549f..bade3e3 100644
--- a/src/applet.c
+++ b/src/applet.c
@@ -80,6 +80,10 @@
#include "shell-watcher.h"
#include "nm-ui-utils.h"
+#if WITH_MODEM_MANAGER_1
+# include "applet-device-broadband.h"
+#endif
+
#define NOTIFY_CAPS_ACTIONS_KEY "actions"
extern gboolean shell_debug;
@@ -190,6 +194,21 @@ impl_dbus_connect_to_3g_network (NMApplet *applet,
return FALSE;
}
+#if WITH_MODEM_MANAGER_1
+ if (g_str_has_prefix (nm_device_get_udi (device), "/org/freedesktop/ModemManager1/Modem/")) {
+ if (applet->mm1_running) {
+ applet_broadband_connect_network (applet, device);
+ return TRUE;
+ }
+
+ g_set_error_literal (error,
+ NM_SECRET_AGENT_ERROR,
+ NM_SECRET_AGENT_ERROR_INTERNAL_ERROR,
+ "ModemManager was not found");
+ return FALSE;
+ }
+#endif
+
caps = nm_device_modem_get_current_capabilities (NM_DEVICE_MODEM (device));
if (caps & NM_DEVICE_MODEM_CAPABILITY_GSM_UMTS) {
applet_gsm_connect_network (applet, device);
@@ -223,6 +242,15 @@ get_device_class (NMDevice *device, NMApplet *applet)
else if (NM_IS_DEVICE_MODEM (device)) {
NMDeviceModemCapabilities caps;
+#if WITH_MODEM_MANAGER_1
+ if (g_str_has_prefix (nm_device_get_udi (device), "/org/freedesktop/ModemManager1/Modem/")) {
+ if (applet->mm1_running)
+ return applet->broadband_class;
+ g_message ("%s: ModemManager was not found", __func__);
+ return NULL;
+ }
+#endif
+
caps = nm_device_modem_get_current_capabilities (NM_DEVICE_MODEM (device));
if (caps & NM_DEVICE_MODEM_CAPABILITY_GSM_UMTS)
return applet->gsm_class;
@@ -258,6 +286,10 @@ get_device_class_from_connection (NMConnection *connection, NMApplet *applet)
return applet->ethernet_class;
else if (!strcmp (ctype, NM_SETTING_WIRELESS_SETTING_NAME))
return applet->wifi_class;
+#if WITH_MODEM_MANAGER_1
+ else if (applet->mm1_running && (!strcmp (ctype, NM_SETTING_GSM_SETTING_NAME) || !strcmp (ctype, NM_SETTING_CDMA_SETTING_NAME)))
+ return applet->broadband_class;
+#endif
else if (!strcmp (ctype, NM_SETTING_GSM_SETTING_NAME))
return applet->gsm_class;
else if (!strcmp (ctype, NM_SETTING_CDMA_SETTING_NAME))
@@ -2455,6 +2487,56 @@ foo_client_setup (NMApplet *applet)
g_idle_add (foo_set_initial_state, applet);
}
+#if WITH_MODEM_MANAGER_1
+
+static void
+mm1_name_owner_changed_cb (GDBusObjectManagerClient *mm1,
+ GParamSpec *pspec,
+ NMApplet *applet)
+{
+ gchar *name_owner;
+
+ name_owner = g_dbus_object_manager_client_get_name_owner (mm1);
+ applet->mm1_running = !!name_owner;
+ g_free (name_owner);
+}
+
+static void
+mm1_client_setup (NMApplet *applet)
+{
+ GDBusConnection *system_bus;
+ GError *error = NULL;
+
+ system_bus = g_bus_get_sync (G_BUS_TYPE_SYSTEM, NULL, &error);
+ if (!system_bus) {
+ g_warning ("Error connecting to system D-Bus: %s",
+ error->message);
+ g_clear_error (&error);
+ return;
+ }
+
+ applet->mm1 = (mm_manager_new_sync (
+ system_bus,
+ G_DBUS_OBJECT_MANAGER_CLIENT_FLAGS_NONE,
+ NULL,
+ &error));
+ if (!applet->mm1) {
+ g_warning ("Error connecting to ModemManager: %s",
+ error->message);
+ g_clear_error (&error);
+ return;
+ }
+
+ /* Check whether the ModemManager is really running */
+ g_signal_connect (applet->mm1,
+ "notify::name-owner",
+ G_CALLBACK (mm1_name_owner_changed_cb),
+ applet);
+ mm1_name_owner_changed_cb (G_DBUS_OBJECT_MANAGER_CLIENT (applet->mm1), NULL, applet);
+}
+
+#endif /* WITH_MODEM_MANAGER_1 */
+
static GdkPixbuf *
applet_common_get_device_icon (NMDeviceState state, NMApplet *applet)
{
@@ -3426,6 +3508,11 @@ constructor (GType type,
applet->cdma_class = applet_device_cdma_get_class (applet);
g_assert (applet->cdma_class);
+#if WITH_MODEM_MANAGER_1
+ applet->broadband_class = applet_device_broadband_get_class (applet);
+ g_assert (applet->broadband_class);
+#endif
+
applet->bt_class = applet_device_bt_get_class (applet);
g_assert (applet->bt_class);
@@ -3434,6 +3521,10 @@ constructor (GType type,
foo_client_setup (applet);
+#if WITH_MODEM_MANAGER_1
+ mm1_client_setup (applet);
+#endif
+
/* Track embedding to help debug issues where user has removed the
* notification area applet from the panel, and thus nm-applet too.
*/
@@ -3465,6 +3556,9 @@ static void finalize (GObject *object)
g_slice_free (NMADeviceClass, applet->wifi_class);
g_slice_free (NMADeviceClass, applet->gsm_class);
g_slice_free (NMADeviceClass, applet->cdma_class);
+#if WITH_MODEM_MANAGER_1
+ g_slice_free (NMADeviceClass, applet->broadband_class);
+#endif
g_slice_free (NMADeviceClass, applet->bt_class);
g_slice_free (NMADeviceClass, applet->wimax_class);
@@ -3497,6 +3591,11 @@ static void finalize (GObject *object)
if (applet->nm_client)
g_object_unref (applet->nm_client);
+#if WITH_MODEM_MANAGER_1
+ if (applet->mm1)
+ g_object_unref (applet->mm1);
+#endif
+
if (applet->fallback_icon)
g_object_unref (applet->fallback_icon);
diff --git a/src/applet.h b/src/applet.h
index 368c7c7..0a429a8 100644
--- a/src/applet.h
+++ b/src/applet.h
@@ -47,6 +47,10 @@
#include "applet-agent.h"
#include "shell-watcher.h"
+#if WITH_MODEM_MANAGER_1
+#include <libmm-glib.h>
+#endif
+
#define NM_TYPE_APPLET (nma_get_type())
#define NM_APPLET(object) (G_TYPE_CHECK_INSTANCE_CAST((object), NM_TYPE_APPLET, NMApplet))
#define NM_APPLET_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass), NM_TYPE_APPLET, NMAppletClass))
@@ -95,6 +99,11 @@ typedef struct
GSettings *gsettings;
+#if WITH_MODEM_MANAGER_1
+ MMManager *mm1;
+ gboolean mm1_running;
+#endif
+
/* Permissions */
NMClientPermissionResult permissions[NM_CLIENT_PERMISSION_LAST + 1];
@@ -103,6 +112,9 @@ typedef struct
NMADeviceClass *wifi_class;
NMADeviceClass *gsm_class;
NMADeviceClass *cdma_class;
+#if WITH_MODEM_MANAGER_1
+ NMADeviceClass *broadband_class;
+#endif
NMADeviceClass *bt_class;
NMADeviceClass *wimax_class;
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]