aboutsummaryrefslogtreecommitdiff
path: root/plugins/mm-modem-icera.c
diff options
context:
space:
mode:
Diffstat (limited to 'plugins/mm-modem-icera.c')
-rw-r--r--plugins/mm-modem-icera.c75
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;
}
-