[gnome-control-center] network: include support for the 'ModemManager1' interface



commit 0225d1a9e73cf741f627d595925abb7e886164be
Author: Aleksander Morgado <aleksander lanedo com>
Date:   Mon Feb 4 15:41:37 2013 +0100

    network: include support for the 'ModemManager1' interface
    
    The control-center will automatically detect whether the modems exposed by
    NetworkManager are from the old or the new interface, and if they are from the
    new one it will use the libmm-glib support to gather the required information
    from them.
    
    The new ModemManager1 interfaces are exposed by ModemManager >= 0.7; and provide
    lots of new functionalities, like:
      * Improved connection bearer handling (e.g. multiple bearers at the same time)
      * Location support (GPS, LAC/CI, CDMA BS...)
      * Full SMS support through the new 'Messaging' interface.
      * ...

 configure.ac                       |    6 +-
 panels/network/cc-network-panel.c  |   50 +++++++++
 panels/network/net-device-mobile.c |  192 ++++++++++++++++++++++++++++++++----
 3 files changed, 225 insertions(+), 23 deletions(-)
---
diff --git a/configure.ac b/configure.ac
index d5f39aa..a3d3fc7 100644
--- a/configure.ac
+++ b/configure.ac
@@ -101,6 +101,7 @@ POLKIT_REQUIRED_VERSION=0.103
 GSD_REQUIRED_VERSION=3.7.3
 NETWORK_MANAGER_REQUIRED_VERSION=0.9.7.995
 NETWORK_MANAGER_APPLET_REQUIRED_VERSION=0.9.7.995
+MODEM_MANAGER_REQUIRED_VERSION=0.7
 LIBNOTIFY_REQUIRED_VERSION=0.7.3
 GNOME_DESKTOP_REQUIRED_VERSION=3.7.5
 SCHEMAS_REQUIRED_VERSION=3.7.2.2
@@ -183,10 +184,11 @@ PKG_CHECK_MODULES(NETWORK_MANAGER, NetworkManager >= $NETWORK_MANAGER_REQUIRED_V
                   libnm-glib >= $NETWORK_MANAGER_REQUIRED_VERSION
                   libnm-glib-vpn >= $NETWORK_MANAGER_REQUIRED_VERSION
                   libnm-util >= $NETWORK_MANAGER_REQUIRED_VERSION
-		  libnm-gtk >= $NETWORK_MANAGER_APPLET_REQUIRED_VERSION,
+                  libnm-gtk >= $NETWORK_MANAGER_APPLET_REQUIRED_VERSION
+                  mm-glib >= $MODEM_MANAGER_REQUIRED_VERSION,
                   [have_networkmanager=yes], have_networkmanager=no)
 if test "x$have_networkmanager" = xno ; then
-        AC_MSG_WARN(*** Network panel will not be built (NetworkManager $NETWORK_MANAGER_REQUIRED_VERSION or newer not found) ***)
+        AC_MSG_WARN(*** Network panel will not be built (NetworkManager or ModemManager not found) ***)
 else
 	AC_DEFINE(BUILD_NETWORK, 1, [Define to 1 to build the Network panel])
 fi
diff --git a/panels/network/cc-network-panel.c b/panels/network/cc-network-panel.c
index dee9af4..94ab9ed 100644
--- a/panels/network/cc-network-panel.c
+++ b/panels/network/cc-network-panel.c
@@ -2,6 +2,7 @@
  *
  * Copyright (C) 2010-2012 Richard Hughes <richard hughsie com>
  * Copyright (C) 2012 Thomas Bechtold <thomasbechtold jpberlin de>
+ * Copyright (C) 2013 Aleksander Morgado <aleksander gnu org>
  *
  * 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
@@ -50,6 +51,8 @@
 #include "network-dialogs.h"
 #include "connection-editor/net-connection-editor.h"
 
+#include <libmm-glib.h>
+
 CC_PANEL_REGISTER (CcNetworkPanel, cc_network_panel)
 
 #define NETWORK_PANEL_PRIVATE(o) \
@@ -70,6 +73,7 @@ struct _CcNetworkPanelPrivate
         GtkBuilder       *builder;
         GtkWidget        *treeview;
         NMClient         *client;
+        MMManager        *modem_manager;
         NMRemoteSettings *remote_settings;
         gboolean          updating_device;
         guint             nm_warning_idle;
@@ -212,6 +216,7 @@ cc_network_panel_dispose (GObject *object)
         g_clear_object (&priv->cancellable);
         g_clear_object (&priv->builder);
         g_clear_object (&priv->client);
+        g_clear_object (&priv->modem_manager);
         g_clear_object (&priv->remote_settings);
         g_clear_object (&priv->kill_switch_header);
         g_clear_object (&priv->rfkill);
@@ -681,6 +686,31 @@ panel_add_device (CcNetworkPanel *panel, NMDevice *device)
                                    "id", nm_device_get_udi (device),
                                    NULL);
 
+        if (type == NM_DEVICE_TYPE_MODEM &&
+            g_str_has_prefix (nm_device_get_udi (device), "/org/freedesktop/ModemManager1/Modem/")) {
+                GDBusObject *modem_object;
+
+                if (priv->modem_manager == NULL) {
+                        g_warning ("Cannot grab information for modem at %s: No ModemManager support",
+                                   nm_device_get_udi (device));
+                        goto out;
+                }
+
+                modem_object = g_dbus_object_manager_get_object (G_DBUS_OBJECT_MANAGER (priv->modem_manager),
+                                                                 nm_device_get_udi (device));
+                if (modem_object == NULL) {
+                        g_warning ("Cannot grab information for modem at %s: Not found",
+                                   nm_device_get_udi (device));
+                        goto out;
+                }
+
+                /* Set the modem object in the NetDeviceMobile */
+                g_object_set (net_device,
+                              "mm-object", modem_object,
+                              NULL);
+                g_object_unref (modem_object);
+        }
+
         /* add as a panel */
         if (device_g_type != NET_TYPE_DEVICE) {
                 notebook = GTK_NOTEBOOK (gtk_builder_get_object (panel->priv->builder,
@@ -1295,6 +1325,7 @@ cc_network_panel_init (CcNetworkPanel *panel)
         GtkTreeSelection *selection;
         GtkWidget *widget;
         GtkWidget *toplevel;
+        GDBusConnection *system_bus;
 
         panel->priv = NETWORK_PANEL_PRIVATE (panel);
         g_resources_register (cc_network_get_resource ());
@@ -1344,6 +1375,25 @@ cc_network_panel_init (CcNetworkPanel *panel)
         g_signal_connect (panel->priv->client, "device-removed",
                           G_CALLBACK (device_removed_cb), panel);
 
+        /* Setup ModemManager client */
+        system_bus = g_bus_get_sync (G_BUS_TYPE_SYSTEM, NULL, &error);
+        if (system_bus == NULL) {
+                g_warning ("Error connecting to system D-Bus: %s",
+                           error->message);
+                g_clear_error (&error);
+        } else {
+                panel->priv->modem_manager = mm_manager_new_sync (system_bus,
+                                                                  G_DBUS_OBJECT_MANAGER_CLIENT_FLAGS_NONE,
+                                                                  NULL,
+                                                                  &error);
+                if (panel->priv->modem_manager == NULL) {
+                        g_warning ("Error connecting to ModemManager: %s",
+                                   error->message);
+                        g_clear_error (&error);
+                }
+                g_object_unref (system_bus);
+        }
+
         widget = GTK_WIDGET (gtk_builder_get_object (panel->priv->builder,
                                                      "add_toolbutton"));
         g_signal_connect (widget, "clicked",
diff --git a/panels/network/net-device-mobile.c b/panels/network/net-device-mobile.c
index 9afbdb5..1f98278 100644
--- a/panels/network/net-device-mobile.c
+++ b/panels/network/net-device-mobile.c
@@ -1,6 +1,7 @@
 /* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 8 -*-
  *
  * Copyright (C) 2011-2012 Richard Hughes <richard hughsie com>
+ * Copyright (C) 2013 Aleksander Morgado <aleksander gnu org>
  *
  * Licensed under the GNU General Public License Version 2
  *
@@ -32,6 +33,8 @@
 #include "panel-common.h"
 #include "network-dialogs.h"
 
+#include <libmm-glib.h>
+
 #include "net-device-mobile.h"
 
 #define NET_DEVICE_MOBILE_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), NET_TYPE_DEVICE_MOBILE, NetDeviceMobilePrivate))
@@ -42,7 +45,13 @@ struct _NetDeviceMobilePrivate
 {
         GtkBuilder *builder;
         gboolean    updating_device;
+
+        /* Old MM < 0.7 support */
         GDBusProxy *gsm_proxy;
+
+        /* New MM >= 0.7 support */
+        MMObject   *mm_object;
+        guint       operator_name_updated;
 };
 
 enum {
@@ -51,6 +60,12 @@ enum {
         COLUMN_LAST
 };
 
+enum {
+        PROP_0,
+        PROP_MODEM_OBJECT,
+        PROP_LAST
+};
+
 G_DEFINE_TYPE (NetDeviceMobile, net_device_mobile, NET_TYPE_DEVICE)
 
 static GtkWidget *
@@ -226,21 +241,63 @@ device_add_device_connections (NetDeviceMobile *device_mobile,
 static void
 device_mobile_refresh_equipment_id (NetDeviceMobile *device_mobile)
 {
-        const char *str;
+        const gchar *equipment_id = NULL;
+
+        if (device_mobile->priv->mm_object != NULL) {
+                MMModem *modem;
+
+                /* Modem interface should always be present */
+                modem = mm_object_peek_modem (device_mobile->priv->mm_object);
+                equipment_id = mm_modem_get_equipment_identifier (modem);
 
-        str = g_object_get_data (G_OBJECT (device_mobile),
-                                 "ControlCenter::EquipmentIdentifier");
-        panel_set_device_widget_details (device_mobile->priv->builder, "imei", str);
+                /* Set equipment ID */
+                if (equipment_id != NULL) {
+                        g_debug ("[%s] Equipment ID set to '%s'",
+                                 mm_object_get_path (device_mobile->priv->mm_object),
+                                 equipment_id);
+                }
+        } else {
+                /* Assume old MM handling */
+                equipment_id = g_object_get_data (G_OBJECT (device_mobile),
+                                                  "ControlCenter::EquipmentIdentifier");
+        }
+
+        panel_set_device_widget_details (device_mobile->priv->builder, "imei", equipment_id);
 }
 
 static void
 device_mobile_refresh_operator_name (NetDeviceMobile *device_mobile)
 {
-        const char *str;
+        if (device_mobile->priv->mm_object != NULL) {
+                gchar *operator_name = NULL;
+                MMModem3gpp *modem_3gpp;
+
+                modem_3gpp = mm_object_peek_modem_3gpp (device_mobile->priv->mm_object);
+                if (modem_3gpp != NULL) {
+                        const gchar *operator_name_unsafe;
+
+                        operator_name_unsafe = mm_modem_3gpp_get_operator_name (modem_3gpp);
+                        if (operator_name_unsafe != NULL && operator_name_unsafe[0] != '\0')
+                                operator_name = g_strescape (operator_name_unsafe, NULL);
+                }
 
-        str = g_object_get_data (G_OBJECT (device_mobile),
-                                 "ControlCenter::OperatorName");
-        panel_set_device_widget_details (device_mobile->priv->builder, "provider", str);
+                /* Set operator name */
+                if (operator_name != NULL) {
+                        g_debug ("[%s] Operator name set to '%s'",
+                                 mm_object_get_path (device_mobile->priv->mm_object),
+                                 operator_name);
+                }
+
+                panel_set_device_widget_details (device_mobile->priv->builder, "provider", operator_name);
+                g_free (operator_name);
+        } else {
+                const char *str;
+
+                /* Assume old MM handling */
+                str = g_object_get_data (G_OBJECT (device_mobile),
+                                         "ControlCenter::OperatorName");
+                panel_set_device_widget_details (device_mobile->priv->builder, "provider", str);
+        }
 }
 
 static void
@@ -514,11 +571,13 @@ net_device_mobile_constructed (GObject *object)
         device = net_device_get_nm_device (NET_DEVICE (device_mobile));
         cancellable = net_object_get_cancellable (NET_OBJECT (device_mobile));
 
-        /* Only load proxies if we have broadband modems */
         caps = nm_device_modem_get_current_capabilities (NM_DEVICE_MODEM (device));
-        if ((caps & NM_DEVICE_MODEM_CAPABILITY_GSM_UMTS) ||
-            (caps & NM_DEVICE_MODEM_CAPABILITY_CDMA_EVDO) ||
-            (caps & NM_DEVICE_MODEM_CAPABILITY_LTE)) {
+
+        /* Only load proxies if we have broadband modems of the OLD ModemManager interface */
+        if (g_str_has_prefix (nm_device_get_udi (device), "/org/freedesktop/ModemManager/") &&
+            ((caps & NM_DEVICE_MODEM_CAPABILITY_GSM_UMTS) ||
+             (caps & NM_DEVICE_MODEM_CAPABILITY_CDMA_EVDO) ||
+             (caps & NM_DEVICE_MODEM_CAPABILITY_LTE))) {
                 g_dbus_proxy_new_for_bus (G_BUS_TYPE_SYSTEM,
                                           G_DBUS_PROXY_FLAGS_NONE,
                                           NULL,
@@ -528,15 +587,19 @@ net_device_mobile_constructed (GObject *object)
                                           cancellable,
                                           device_mobile_device_got_modem_manager_cb,
                                           device_mobile);
-                g_dbus_proxy_new_for_bus (G_BUS_TYPE_SYSTEM,
-                                          G_DBUS_PROXY_FLAGS_NONE,
-                                          NULL,
-                                          "org.freedesktop.ModemManager",
-                                          nm_device_get_udi (device),
-                                          "org.freedesktop.ModemManager.Modem.Gsm.Network",
-                                          cancellable,
-                                          device_mobile_device_got_modem_manager_gsm_cb,
-                                          device_mobile);
+
+                if ((caps & NM_DEVICE_MODEM_CAPABILITY_GSM_UMTS) ||
+                    (caps & NM_DEVICE_MODEM_CAPABILITY_LTE)) {
+                        g_dbus_proxy_new_for_bus (G_BUS_TYPE_SYSTEM,
+                                                  G_DBUS_PROXY_FLAGS_NONE,
+                                                  NULL,
+                                                  "org.freedesktop.ModemManager",
+                                                  nm_device_get_udi (device),
+                                                  "org.freedesktop.ModemManager.Modem.Gsm.Network",
+                                                  cancellable,
+                                                  device_mobile_device_got_modem_manager_gsm_cb,
+                                                  device_mobile);
+                }
         }
 
         client = net_object_get_client (NET_OBJECT (device_mobile));
@@ -547,6 +610,75 @@ net_device_mobile_constructed (GObject *object)
 }
 
 static void
+operator_name_updated (MMModem3gpp     *modem_3gpp_iface,
+                       GParamSpec      *pspec,
+                       NetDeviceMobile *self)
+{
+        device_mobile_refresh_operator_name (self);
+}
+
+static void
+net_device_mobile_setup_modem_object (NetDeviceMobile *self)
+{
+        MMModem3gpp *modem_3gpp;
+
+        if (self->priv->mm_object == NULL)
+                return;
+
+        /* Load equipment ID initially */
+        device_mobile_refresh_equipment_id (self);
+
+        /* Follow changes in operator name and load initial values */
+        modem_3gpp = mm_object_peek_modem_3gpp (self->priv->mm_object);
+        if (modem_3gpp != NULL) {
+                g_assert (self->priv->operator_name_updated == 0);
+                self->priv->operator_name_updated = g_signal_connect (modem_3gpp,
+                                                                      "notify::operator-name",
+                                                                      G_CALLBACK (operator_name_updated),
+                                                                      self);
+                device_mobile_refresh_operator_name (self);
+        }
+}
+
+
+static void
+net_device_mobile_get_property (GObject    *device_,
+                                guint       prop_id,
+                                GValue     *value,
+                                GParamSpec *pspec)
+{
+        NetDeviceMobile *self = NET_DEVICE_MOBILE (device_);
+
+        switch (prop_id) {
+        case PROP_MODEM_OBJECT:
+                g_value_set_object (value, self->priv->mm_object);
+                break;
+        default:
+                G_OBJECT_WARN_INVALID_PROPERTY_ID (self, prop_id, pspec);
+                break;
+        }
+}
+
+static void
+net_device_mobile_set_property (GObject      *device_,
+                                guint         prop_id,
+                                const GValue *value,
+                                GParamSpec   *pspec)
+{
+        NetDeviceMobile *self = NET_DEVICE_MOBILE (device_);
+
+        switch (prop_id) {
+        case PROP_MODEM_OBJECT:
+                self->priv->mm_object = g_value_dup_object (value);
+                net_device_mobile_setup_modem_object (self);
+                break;
+        default:
+                G_OBJECT_WARN_INVALID_PROPERTY_ID (self, prop_id, pspec);
+                break;
+        }
+}
+
+static void
 net_device_mobile_dispose (GObject *object)
 {
         NetDeviceMobile *device_mobile = NET_DEVICE_MOBILE (object);
@@ -555,6 +687,13 @@ net_device_mobile_dispose (GObject *object)
         g_clear_object (&priv->builder);
         g_clear_object (&priv->gsm_proxy);
 
+        if (priv->operator_name_updated) {
+                g_assert (priv->mm_object != NULL);
+                g_signal_handler_disconnect (mm_object_peek_modem_3gpp (priv->mm_object), priv->operator_name_updated);
+                priv->operator_name_updated = 0;
+        }
+        g_clear_object (&priv->mm_object);
+
         G_OBJECT_CLASS (net_device_mobile_parent_class)->dispose (object);
 }
 
@@ -566,9 +705,20 @@ net_device_mobile_class_init (NetDeviceMobileClass *klass)
 
         object_class->dispose = net_device_mobile_dispose;
         object_class->constructed = net_device_mobile_constructed;
+        object_class->get_property = net_device_mobile_get_property;
+        object_class->set_property = net_device_mobile_set_property;
         parent_class->add_to_notebook = device_mobile_proxy_add_to_notebook;
         parent_class->refresh = device_mobile_refresh;
+
         g_type_class_add_private (klass, sizeof (NetDeviceMobilePrivate));
+
+        g_object_class_install_property (object_class,
+                                         PROP_MODEM_OBJECT,
+                                         g_param_spec_object ("mm-object",
+                                                              NULL,
+                                                              NULL,
+                                                              MM_TYPE_OBJECT,
+                                                              G_PARAM_READWRITE));
 }
 
 static void


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]