diff options
Diffstat (limited to 'plugins/mm-modem-icera.c')
-rw-r--r-- | plugins/mm-modem-icera.c | 75 |
1 files changed, 61 insertions, 14 deletions
diff --git a/plugins/mm-modem-icera.c b/plugins/mm-modem-icera.c index b093b34..8933142 100644 --- a/plugins/mm-modem-icera.c +++ b/plugins/mm-modem-icera.c @@ -192,11 +192,13 @@ nwstate_to_act (const char *str) return MM_MODEM_GSM_ACCESS_TECH_UMTS; else if (!strcmp (str, "3g")) return MM_MODEM_GSM_ACCESS_TECH_UMTS; - else if (!strcmp (str, "3G-HSDPA")) + else if (!strcmp (str, "R99")) + return MM_MODEM_GSM_ACCESS_TECH_UMTS; + else if (!strcmp (str, "3G-HSDPA") || !strcmp (str, "HSDPA")) return MM_MODEM_GSM_ACCESS_TECH_HSDPA; - else if (!strcmp (str, "3G-HSUPA")) + else if (!strcmp (str, "3G-HSUPA") || !strcmp (str, "HSUPA")) return MM_MODEM_GSM_ACCESS_TECH_HSUPA; - else if (!strcmp (str, "3G-HSDPA-HSUPA")) + else if (!strcmp (str, "3G-HSDPA-HSUPA") || !strcmp (str, "HSDPA-HSUPA")) return MM_MODEM_GSM_ACCESS_TECH_HSPA; return MM_MODEM_GSM_ACCESS_TECH_UNKNOWN; @@ -219,7 +221,15 @@ nwstate_changed (MMAtSerialPort *port, g_free (str); } - str = g_match_info_fetch (info, 3); + /* Check the <connection state> field first for the connected access + * technology, otherwise if not connected (ie, "-") use the available + * access technology from the <tech> field. + */ + str = g_match_info_fetch (info, 4); + if (!str || (strcmp (str, "-") == 0)) { + g_free (str); + str = g_match_info_fetch (info, 3); + } if (str) { act = nwstate_to_act (str); g_free (str); @@ -357,13 +367,48 @@ icera_disconnect_done (MMModem *modem, } static void +query_network_error_code_done (MMAtSerialPort *port, + GString *response, + GError *error, + gpointer user_data) +{ + MMModemIcera *self = MM_MODEM_ICERA (user_data); + MMModemIceraPrivate *priv = MM_MODEM_ICERA_GET_PRIVATE (self); + MMCallbackInfo *info = priv->connect_pending_data; + int nw_activation_err; + + /* If the modem has already been removed, return without + * scheduling callback */ + if (mm_callback_info_check_modem_removed (info)) + return; + + if ((error == NULL) && g_str_has_prefix (response->str, "%IER: ")) { + if (sscanf (response->str + 6, "%*d,%*d,%d", &nw_activation_err)) { + /* 3GPP TS 24.008 Annex G error codes: + * 27 - Unknown or missing access point name + * 33 - Requested service option not subscribed + */ + if (nw_activation_err == 27 || nw_activation_err == 33) + info->error = mm_mobile_error_for_code (MM_MOBILE_ERROR_GPRS_NOT_SUBSCRIBED); + } + } + + if (info->error == NULL) { + /* Generic error since parsing the specific one didn't work */ + info->error = g_error_new_literal (MM_MODEM_ERROR, + MM_MODEM_ERROR_GENERAL, + "Call setup failed"); + } + connect_pending_done (self); +} + +static void connection_enabled (MMAtSerialPort *port, GMatchInfo *match_info, gpointer user_data) { MMModemIcera *self = MM_MODEM_ICERA (user_data); - MMModemIceraPrivate *priv = MM_MODEM_ICERA_GET_PRIVATE (self); - MMCallbackInfo *info = priv->connect_pending_data; + MMAtSerialPort *primary; char *str; int status, cid, tmp; @@ -400,12 +445,11 @@ connection_enabled (MMAtSerialPort *port, break; case 3: /* Call setup failure? */ - if (info) { - info->error = g_error_new_literal (MM_MODEM_ERROR, - MM_MODEM_ERROR_GENERAL, - "Call setup failed"); - } - connect_pending_done (self); + primary = mm_generic_gsm_get_at_port (MM_GENERIC_GSM(self), MM_PORT_TYPE_PRIMARY); + g_assert (primary); + /* Get additional error details */ + mm_at_serial_port_queue_command (primary, "AT%IER?", 3, + query_network_error_code_done, self); break; default: mm_warn ("Unknown Icera connect status %d", status); @@ -717,7 +761,11 @@ mm_modem_icera_register_unsolicted_handlers (MMModemIcera *self, { GRegex *regex; - /* %NWSTATE: <rssi>,<mccmnc>,<tech>,<connected>,<regulation> */ + /* %NWSTATE: <rssi>,<mccmnc>,<tech>,<connection state>,<regulation> + * + * <connection state> shows the actual access technology in-use when a + * PS connection is active. + */ regex = g_regex_new ("\\r\\n%NWSTATE:\\s*(-?\\d+),(\\d+),([^,]*),([^,]*),(\\d+)\\r\\n", G_REGEX_RAW | G_REGEX_OPTIMIZE, 0, NULL); mm_at_serial_port_add_unsolicited_msg_handler (port, regex, nwstate_changed, self, NULL); g_regex_unref (regex); @@ -848,4 +896,3 @@ mm_modem_icera_get_type (void) return icera_type; } - |