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.
This commit is contained in:
parent
0225d1a9e7
commit
d28b756e61
1 changed files with 185 additions and 12 deletions
|
@ -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;
|
||||
|
@ -557,6 +650,72 @@ device_mobile_device_got_modem_manager_gsm_cb (GObject *source_object,
|
|||
device_mobile);
|
||||
}
|
||||
|
||||
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)
|
||||
{
|
||||
|
@ -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);
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue