[gnome-control-center] network: try to guess operator name from MCCMNC or SID
- From: Aleksander Morgado <aleksm src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gnome-control-center] network: try to guess operator name from MCCMNC or SID
- Date: Tue, 12 Feb 2013 16:43:35 +0000 (UTC)
commit d28b756e61665046ccfb83c79daab71189f56ee6
Author: Aleksander Morgado <aleksander lanedo com>
Date: Tue Feb 5 18:57:26 2013 +0100
network: try to guess operator name from MCCMNC or SID
When the network doesn't provide a valid text string with the current operator
name, try to guess it using either the 3GPP MCCMNC pair or with the CDMA SID.
Guessing is based on the Mobile Providers Database for which there is an API in
libnm-gtk (>= 0.9.7.995).
The same logic to guess operator name is used in gnome-shell.
panels/network/net-device-mobile.c | 197 +++++++++++++++++++++++++++++++++--
1 files changed, 185 insertions(+), 12 deletions(-)
---
diff --git a/panels/network/net-device-mobile.c b/panels/network/net-device-mobile.c
index 1f98278..aafdc79 100644
--- a/panels/network/net-device-mobile.c
+++ b/panels/network/net-device-mobile.c
@@ -29,6 +29,7 @@
#include <nm-device.h>
#include <nm-device-modem.h>
#include <nm-remote-connection.h>
+#include <nm-mobile-providers.h>
#include "panel-common.h"
#include "network-dialogs.h"
@@ -48,10 +49,13 @@ struct _NetDeviceMobilePrivate
/* Old MM < 0.7 support */
GDBusProxy *gsm_proxy;
+ GDBusProxy *cdma_proxy;
/* New MM >= 0.7 support */
MMObject *mm_object;
guint operator_name_updated;
+
+ NMAMobileProvidersDatabase *mpd;
};
enum {
@@ -265,14 +269,57 @@ device_mobile_refresh_equipment_id (NetDeviceMobile *device_mobile)
panel_set_device_widget_details (device_mobile->priv->builder, "imei", equipment_id);
}
+static gchar *
+device_mobile_find_provider (NetDeviceMobile *device_mobile,
+ const gchar *mccmnc,
+ guint32 sid)
+{
+ NMAMobileProvider *provider;
+ GString *name = NULL;
+
+ if (device_mobile->priv->mpd == NULL) {
+ GError *error = NULL;
+
+ /* Use defaults */
+ device_mobile->priv->mpd = nma_mobile_providers_database_new_sync (NULL, NULL, NULL, &error);
+ if (device_mobile->priv->mpd == NULL) {
+ g_debug ("Couldn't load mobile providers database: %s",
+ error ? error->message : "");
+ g_clear_error (&error);
+ return NULL;
+ }
+ }
+
+ if (mccmnc != NULL) {
+ provider = nma_mobile_providers_database_lookup_3gpp_mcc_mnc (device_mobile->priv->mpd, mccmnc);
+ if (provider != NULL)
+ name = g_string_new (nma_mobile_provider_get_name (provider));
+ }
+
+ if (sid != 0) {
+ provider = nma_mobile_providers_database_lookup_cdma_sid (device_mobile->priv->mpd, sid);
+ if (provider != NULL) {
+ if (name == NULL)
+ name = g_string_new (nma_mobile_provider_get_name (provider));
+ else
+ g_string_append_printf (name, ", %s", nma_mobile_provider_get_name (provider));
+ }
+ }
+
+ return (name != NULL ? g_string_free (name, FALSE) : NULL);
+}
+
static void
device_mobile_refresh_operator_name (NetDeviceMobile *device_mobile)
{
if (device_mobile->priv->mm_object != NULL) {
gchar *operator_name = NULL;
MMModem3gpp *modem_3gpp;
+ MMModemCdma *modem_cdma;
modem_3gpp = mm_object_peek_modem_3gpp (device_mobile->priv->mm_object);
+ modem_cdma = mm_object_peek_modem_cdma (device_mobile->priv->mm_object);
+
if (modem_3gpp != NULL) {
const gchar *operator_name_unsafe;
@@ -281,6 +328,19 @@ device_mobile_refresh_operator_name (NetDeviceMobile *device_mobile)
operator_name = g_strescape (operator_name_unsafe, NULL);
}
+ /* If not directly given in the 3GPP interface, try to guess from
+ * MCCMNC/SID */
+ if (operator_name == NULL) {
+ const gchar *mccmnc = NULL;
+ guint32 sid = 0;
+
+ if (modem_3gpp != NULL)
+ mccmnc = mm_modem_3gpp_get_operator_code (modem_3gpp);
+ if (modem_cdma != NULL)
+ sid = mm_modem_cdma_get_sid (modem_cdma);
+ operator_name = device_mobile_find_provider (device_mobile, mccmnc, sid);
+ }
+
/* Set operator name */
if (operator_name != NULL) {
g_debug ("[%s] Operator name set to '%s'",
@@ -291,12 +351,28 @@ device_mobile_refresh_operator_name (NetDeviceMobile *device_mobile)
panel_set_device_widget_details (device_mobile->priv->builder, "provider", operator_name);
g_free (operator_name);
} else {
- const char *str;
+ const gchar *gsm;
+ const gchar *cdma;
/* 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);
+ gsm = g_object_get_data (G_OBJECT (device_mobile),
+ "ControlCenter::OperatorNameGsm");
+ cdma = g_object_get_data (G_OBJECT (device_mobile),
+ "ControlCenter::OperatorNameCdma");
+
+ if (gsm != NULL && cdma != NULL) {
+ gchar *both;
+
+ both = g_strdup_printf ("%s, %s", gsm, cdma);
+ panel_set_device_widget_details (device_mobile->priv->builder, "provider", both);
+ g_free (both);
+ } else if (gsm != NULL) {
+ panel_set_device_widget_details (device_mobile->priv->builder, "provider", gsm);
+ } else if (cdma != NULL) {
+ panel_set_device_widget_details (device_mobile->priv->builder, "provider", cdma);
+ } else {
+ panel_set_device_widget_details (device_mobile->priv->builder, "provider", NULL);
+ }
}
}
@@ -446,7 +522,8 @@ device_mobile_device_got_modem_manager_cb (GObject *source_object,
static void
device_mobile_save_operator_name (NetDeviceMobile *device_mobile,
- const gchar *operator_name)
+ const gchar *field,
+ const gchar *operator_name)
{
gchar *operator_name_safe = NULL;
@@ -455,7 +532,7 @@ device_mobile_save_operator_name (NetDeviceMobile *device_mobile,
/* save */
g_object_set_data_full (G_OBJECT (device_mobile),
- "ControlCenter::OperatorName",
+ field,
operator_name_safe,
g_free);
/* refresh */
@@ -463,9 +540,9 @@ device_mobile_save_operator_name (NetDeviceMobile *device_mobile,
}
static void
-device_mobile_get_registration_info_cb (GObject *source_object,
+device_mobile_get_registration_info_cb (GObject *source_object,
GAsyncResult *res,
- gpointer user_data)
+ gpointer user_data)
{
gchar *operator_code = NULL;
GError *error = NULL;
@@ -488,8 +565,16 @@ device_mobile_get_registration_info_cb (GObject *source_object,
&operator_code,
&operator_name);
+ /* If none give, try to guess it */
+ if (operator_name == NULL || operator_name[0] == '\0') {
+ g_free (operator_name);
+ operator_name = device_mobile_find_provider (device_mobile, operator_code, 0);
+ }
+
/* save and refresh */
- device_mobile_save_operator_name (device_mobile, operator_name);
+ device_mobile_save_operator_name (device_mobile,
+ "ControlCenter::OperatorNameGsm",
+ operator_name);
g_free (operator_name);
g_free (operator_code);
@@ -517,17 +602,25 @@ device_mobile_gsm_signal_cb (GDBusProxy *proxy,
&operator_code,
&operator_name);
+ /* If none given, try to guess it */
+ if (operator_name == NULL || operator_name[0] == '\0') {
+ g_free (operator_name);
+ operator_name = device_mobile_find_provider (device_mobile, operator_code, 0);
+ }
+
/* save and refresh */
- device_mobile_save_operator_name (device_mobile, operator_name);
+ device_mobile_save_operator_name (device_mobile,
+ "ControlCenter::OperatorNameGsm",
+ operator_name);
g_free (operator_code);
g_free (operator_name);
}
static void
-device_mobile_device_got_modem_manager_gsm_cb (GObject *source_object,
+device_mobile_device_got_modem_manager_gsm_cb (GObject *source_object,
GAsyncResult *res,
- gpointer user_data)
+ gpointer user_data)
{
GError *error = NULL;
NetDeviceMobile *device_mobile = (NetDeviceMobile *)user_data;
@@ -558,6 +651,72 @@ device_mobile_device_got_modem_manager_gsm_cb (GObject *source_object,
}
static void
+device_mobile_get_serving_system_cb (GObject *source_object,
+ GAsyncResult *res,
+ gpointer user_data)
+{
+ NetDeviceMobile *device_mobile = (NetDeviceMobile *)user_data;
+ GVariant *result = NULL;
+ GError *error = NULL;
+
+ guint32 band_class;
+ gchar *band;
+ guint32 sid;
+ gchar *operator_name;
+
+ result = g_dbus_proxy_call_finish (G_DBUS_PROXY (source_object), res, &error);
+ if (result == NULL) {
+ g_warning ("Error getting serving system: %s\n",
+ error->message);
+ g_error_free (error);
+ return;
+ }
+
+ /* get values */
+ g_variant_get (result, "((usu))",
+ &band_class,
+ &band,
+ &sid);
+
+ operator_name = device_mobile_find_provider (device_mobile, NULL, sid);
+
+ /* save and refresh */
+ device_mobile_save_operator_name (device_mobile,
+ "ControlCenter::OperatorNameCdma",
+ operator_name);
+
+ g_free (band);
+ g_variant_unref (result);
+}
+
+static void
+device_mobile_device_got_modem_manager_cdma_cb (GObject *source_object,
+ GAsyncResult *res,
+ gpointer user_data)
+{
+ GError *error = NULL;
+ NetDeviceMobile *device_mobile = (NetDeviceMobile *)user_data;
+
+ device_mobile->priv->cdma_proxy = g_dbus_proxy_new_for_bus_finish (res, &error);
+ if (device_mobile->priv->cdma_proxy == NULL) {
+ g_warning ("Error creating ModemManager CDMA proxy: %s\n",
+ error->message);
+ g_error_free (error);
+ return;
+ }
+
+ /* Load initial value */
+ g_dbus_proxy_call (device_mobile->priv->cdma_proxy,
+ "GetServingSystem",
+ NULL,
+ G_DBUS_CALL_FLAGS_NONE,
+ -1,
+ NULL,
+ device_mobile_get_serving_system_cb,
+ device_mobile);
+}
+
+static void
net_device_mobile_constructed (GObject *object)
{
GCancellable *cancellable;
@@ -600,6 +759,18 @@ net_device_mobile_constructed (GObject *object)
device_mobile_device_got_modem_manager_gsm_cb,
device_mobile);
}
+
+ if (caps & NM_DEVICE_MODEM_CAPABILITY_CDMA_EVDO) {
+ 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.Cdma",
+ cancellable,
+ device_mobile_device_got_modem_manager_cdma_cb,
+ device_mobile);
+ }
}
client = net_object_get_client (NET_OBJECT (device_mobile));
@@ -686,6 +857,7 @@ net_device_mobile_dispose (GObject *object)
g_clear_object (&priv->builder);
g_clear_object (&priv->gsm_proxy);
+ g_clear_object (&priv->cdma_proxy);
if (priv->operator_name_updated) {
g_assert (priv->mm_object != NULL);
@@ -693,6 +865,7 @@ net_device_mobile_dispose (GObject *object)
priv->operator_name_updated = 0;
}
g_clear_object (&priv->mm_object);
+ g_clear_object (&priv->mpd);
G_OBJECT_CLASS (net_device_mobile_parent_class)->dispose (object);
}
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]