diff options
-rw-r--r-- | introspection/mm-modem-cdma.xml | 13 | ||||
-rw-r--r-- | src/mm-generic-cdma.c | 84 | ||||
-rw-r--r-- | src/mm-modem-cdma.c | 88 | ||||
-rw-r--r-- | src/mm-modem-cdma.h | 15 | ||||
-rwxr-xr-x | test/mm-test.py | 14 |
5 files changed, 212 insertions, 2 deletions
diff --git a/introspection/mm-modem-cdma.xml b/introspection/mm-modem-cdma.xml index ebde02a4..0c7e9e34 100644 --- a/introspection/mm-modem-cdma.xml +++ b/introspection/mm-modem-cdma.xml @@ -29,6 +29,19 @@ </arg> </method> + <method name="GetServingSystem"> + <tp:docstring> + Get the Service System details of the current network, if registered. + </tp:docstring> + <annotation name="org.freedesktop.DBus.GLib.Async" value=""/> + <annotation name="org.freedesktop.DBus.GLib.CSymbol" value="impl_modem_cdma_get_serving_system"/> + <arg name="info" type="(usu)" direction="out"> + <tp:docstring> + A structure containing the Band Class (0 = unknown, 1 = 800 MHz, 2 = 1900 MHz), the Band ("A" - "F" as defined by IS707-A), and the System ID of the serving network. + </tp:docstring> + </arg> + </method> + <signal name="SignalQuality"> <tp:docstring> The signal quality changed. diff --git a/src/mm-generic-cdma.c b/src/mm-generic-cdma.c index f836c6b1..89d7ff09 100644 --- a/src/mm-generic-cdma.c +++ b/src/mm-generic-cdma.c @@ -428,6 +428,89 @@ get_esn (MMModemCdma *modem, mm_serial_port_queue_command_cached (priv->primary, "+GSN", 3, get_string_done, info); } +static void +serving_system_invoke (MMCallbackInfo *info) +{ + MMModemCdmaServingSystemFn callback = (MMModemCdmaServingSystemFn) info->callback; + + callback (MM_MODEM_CDMA (info->modem), + GPOINTER_TO_UINT (mm_callback_info_get_data (info, "class")), + (char) GPOINTER_TO_UINT (mm_callback_info_get_data (info, "band")), + GPOINTER_TO_UINT (mm_callback_info_get_data (info, "sid")), + info->error, + info->user_data); +} + +static void +serving_system_done (MMSerialPort *port, + GString *response, + GError *error, + gpointer user_data) +{ + MMCallbackInfo *info = (MMCallbackInfo *) user_data; + char *reply = response->str; + int class = 0, sid = 99999, num; + char band = 'Z'; + + if (error) { + info->error = g_error_copy (error); + goto out; + } + + if (!strstr (reply, "+CSS: ")) { + info->error = g_error_new_literal (MM_MODEM_ERROR, MM_MODEM_ERROR_GENERAL, + "Could not parse Serving System results."); + goto out; + } + + /* Got valid reply */ + reply += 6; + + num = sscanf (reply, "%d, %c, %d", &class, &band, &sid); + if (num != 3) + num = sscanf (reply, "%d,%c,%d", &class, &band, &sid); + + if (num == 3) { + /* Normalize */ + class = CLAMP (class, 0, 4); + band = CLAMP (band, 'A', 'Z'); + if (sid < 0 || sid > 32767) + sid = 99999; + + /* 99 means unknown/no service */ + if (sid == 99999) { + info->error = g_error_new_literal (MM_MOBILE_ERROR, + MM_MOBILE_ERROR_NO_NETWORK, + "No service"); + } else { + mm_callback_info_set_data (info, "class", GUINT_TO_POINTER (class), NULL); + mm_callback_info_set_data (info, "band", GUINT_TO_POINTER (band), NULL); + mm_callback_info_set_data (info, "sid", GUINT_TO_POINTER (sid), NULL); + } + } else + info->error = g_error_new (MM_MODEM_ERROR, MM_MODEM_ERROR_GENERAL, + "%s", "Could not parse signal quality results"); + + out: + mm_callback_info_schedule (info); +} + +static void +get_serving_system (MMModemCdma *modem, + MMModemCdmaServingSystemFn callback, + gpointer user_data) +{ + MMGenericCdmaPrivate *priv = MM_GENERIC_CDMA_GET_PRIVATE (modem); + MMCallbackInfo *info; + + info = mm_callback_info_new_full (MM_MODEM (modem), + serving_system_invoke, + G_CALLBACK (callback), + user_data); + + mm_serial_port_queue_command (priv->primary, "+CSS?", 3, serving_system_done, info); +} + /*****************************************************************************/ /* MMModemSimple interface */ @@ -595,6 +678,7 @@ modem_cdma_init (MMModemCdma *cdma_modem_class) { cdma_modem_class->get_signal_quality = get_signal_quality; cdma_modem_class->get_esn = get_esn; + cdma_modem_class->get_serving_system = get_serving_system; } static void diff --git a/src/mm-modem-cdma.c b/src/mm-modem-cdma.c index 80de742a..01272590 100644 --- a/src/mm-modem-cdma.c +++ b/src/mm-modem-cdma.c @@ -8,6 +8,7 @@ static void impl_modem_cdma_get_signal_quality (MMModemCdma *modem, DBusGMethodInvocation *context); static void impl_modem_cdma_get_esn (MMModemCdma *modem, DBusGMethodInvocation *context); +static void impl_modem_cdma_get_serving_system (MMModemCdma *modem, DBusGMethodInvocation *context); #include "mm-modem-cdma-glue.h" @@ -19,6 +20,7 @@ enum { static guint signals[LAST_SIGNAL] = { 0 }; +/*****************************************************************************/ static void str_call_done (MMModem *modem, const char *result, GError *error, gpointer user_data) @@ -69,6 +71,91 @@ uint_call_done (MMModem *modem, guint32 result, GError *error, gpointer user_dat dbus_g_method_return (context, result); } +static void +serving_system_call_done (MMModemCdma *self, + guint32 class, + char band, + guint32 sid, + GError *error, + gpointer user_data) +{ + DBusGMethodInvocation *context = (DBusGMethodInvocation *) user_data; + + if (error) + dbus_g_method_return_error (context, error); + else { + GValueArray *array; + GValue value = { 0, }; + char band_str[2] = { 0, 0 }; + + array = g_value_array_new (3); + + /* Band Class */ + g_value_init (&value, G_TYPE_UINT); + g_value_set_uint (&value, class); + g_value_array_append (array, &value); + g_value_unset (&value); + + /* Band */ + g_value_init (&value, G_TYPE_STRING); + band_str[0] = band; + g_value_set_string (&value, band_str); + g_value_array_append (array, &value); + g_value_unset (&value); + + /* SID */ + g_value_init (&value, G_TYPE_UINT); + g_value_set_uint (&value, sid); + g_value_array_append (array, &value); + g_value_unset (&value); + + dbus_g_method_return (context, array); + } +} + +static void +serving_system_invoke (MMCallbackInfo *info) +{ + MMModemCdmaServingSystemFn callback = (MMModemCdmaServingSystemFn) info->callback; + + callback (MM_MODEM_CDMA (info->modem), 0, 0, 0, info->error, info->user_data); +} + +static void +serving_system_call_not_supported (MMModemCdma *self, + MMModemCdmaServingSystemFn callback, + gpointer user_data) +{ + MMCallbackInfo *info; + + info = mm_callback_info_new_full (MM_MODEM (self), serving_system_invoke, G_CALLBACK (callback), user_data); + info->error = g_error_new_literal (MM_MODEM_ERROR, MM_MODEM_ERROR_OPERATION_NOT_SUPPORTED, + "Operation not supported"); + + mm_callback_info_schedule (info); +} + +void +mm_modem_cdma_get_serving_system (MMModemCdma *self, + MMModemCdmaServingSystemFn callback, + gpointer user_data) +{ + g_return_if_fail (MM_IS_MODEM_CDMA (self)); + g_return_if_fail (callback != NULL); + + if (MM_MODEM_CDMA_GET_INTERFACE (self)->get_serving_system) + MM_MODEM_CDMA_GET_INTERFACE (self)->get_serving_system (self, callback, user_data); + else + serving_system_call_not_supported (self, callback, user_data); +} + +static void +impl_modem_cdma_get_serving_system (MMModemCdma *modem, + DBusGMethodInvocation *context) +{ + mm_modem_cdma_get_serving_system (modem, serving_system_call_done, context); +} + void mm_modem_cdma_get_esn (MMModemCdma *self, MMModemStringFn callback, @@ -119,7 +206,6 @@ mm_modem_cdma_signal_quality (MMModemCdma *self, g_signal_emit (self, signals[SIGNAL_QUALITY], 0, quality); } - /*****************************************************************************/ static void diff --git a/src/mm-modem-cdma.h b/src/mm-modem-cdma.h index 651cf99b..6a27a190 100644 --- a/src/mm-modem-cdma.h +++ b/src/mm-modem-cdma.h @@ -12,6 +12,13 @@ typedef struct _MMModemCdma MMModemCdma; +typedef void (*MMModemCdmaServingSystemFn) (MMModemCdma *modem, + guint32 class, + char band, + guint32 sid, + GError *error, + gpointer user_data); + struct _MMModemCdma { GTypeInterface g_iface; @@ -24,6 +31,10 @@ struct _MMModemCdma { MMModemStringFn callback, gpointer user_data); + void (*get_serving_system) (MMModemCdma *self, + MMModemCdmaServingSystemFn callback, + gpointer user_data); + /* Signals */ void (*signal_quality) (MMModemCdma *self, guint32 quality); @@ -39,6 +50,10 @@ void mm_modem_cdma_get_esn (MMModemCdma *self, MMModemStringFn callback, gpointer user_data); +void mm_modem_cdma_get_serving_system (MMModemCdma *self, + MMModemCdmaServingSystemFn callback, + gpointer user_data); + /* Protected */ void mm_modem_cdma_signal_quality (MMModemCdma *self, diff --git a/test/mm-test.py b/test/mm-test.py index df7f0e91..a5389672 100755 --- a/test/mm-test.py +++ b/test/mm-test.py @@ -12,13 +12,25 @@ MM_DBUS_INTERFACE_MODEM_CDMA='org.freedesktop.ModemManager.Modem.Cdma' MM_DBUS_INTERFACE_MODEM_GSM_CARD='org.freedesktop.ModemManager.Modem.Gsm.Card' MM_DBUS_INTERFACE_MODEM_GSM_NETWORK='org.freedesktop.ModemManager.Modem.Gsm.Network' +def get_cdma_band_class(band_class): + if band_class == 1: + return "800MHz" + elif band_class == 2: + return "1900MHz" + else: + return "Unknown" + def inspect_cdma(proxy): cdma = dbus.Interface(proxy, dbus_interface=MM_DBUS_INTERFACE_MODEM_CDMA) try: print "ESN: %s" % cdma.GetEsn() except dbus.exceptions.DBusException: pass - return + print "-------------------" + info = cdma.GetServingSystem() + print "Class: %s" % get_cdma_band_class(info[0]) + print "Band: %s" % info[1] + print "SID: %d" % info[2] def get_gsm_network_mode(modem): |