aboutsummaryrefslogtreecommitdiff
path: root/plugins/mm-modem-option-utils.c
diff options
context:
space:
mode:
Diffstat (limited to 'plugins/mm-modem-option-utils.c')
-rw-r--r--plugins/mm-modem-option-utils.c141
1 files changed, 96 insertions, 45 deletions
diff --git a/plugins/mm-modem-option-utils.c b/plugins/mm-modem-option-utils.c
index e4ce9759..25ce5a70 100644
--- a/plugins/mm-modem-option-utils.c
+++ b/plugins/mm-modem-option-utils.c
@@ -21,6 +21,7 @@
#include "mm-callback-info.h"
#include "mm-at-serial-port.h"
#include "mm-generic-gsm.h"
+#include "mm-modem-helpers.h"
static void
option_get_allowed_mode_done (MMAtSerialPort *port,
@@ -143,6 +144,87 @@ option_set_allowed_mode (MMGenericGsm *gsm,
g_free (command);
}
+static gboolean
+octi_to_mm (char octi, MMModemGsmAccessTech *out_act)
+{
+ if (octi == '1') {
+ *out_act = MM_MODEM_GSM_ACCESS_TECH_GSM;
+ return TRUE;
+ } else if (octi == '2') {
+ *out_act = MM_MODEM_GSM_ACCESS_TECH_GPRS;
+ return TRUE;
+ } else if (octi == '3') {
+ *out_act = MM_MODEM_GSM_ACCESS_TECH_EDGE;
+ return TRUE;
+ }
+ return FALSE;
+}
+
+static gboolean
+owcti_to_mm (char owcti, MMModemGsmAccessTech *out_act)
+{
+ if (owcti == '1') {
+ *out_act = MM_MODEM_GSM_ACCESS_TECH_UMTS;
+ return TRUE;
+ } else if (owcti == '2') {
+ *out_act = MM_MODEM_GSM_ACCESS_TECH_HSDPA;
+ return TRUE;
+ } else if (owcti == '3') {
+ *out_act = MM_MODEM_GSM_ACCESS_TECH_HSUPA;
+ return TRUE;
+ } else if (owcti == '4') {
+ *out_act = MM_MODEM_GSM_ACCESS_TECH_HSPA;
+ return TRUE;
+ }
+ return FALSE;
+}
+
+static void
+octi_request_done (MMAtSerialPort *port,
+ GString *response,
+ GError *error,
+ gpointer user_data)
+{
+ const char *p;
+ MMModemGsmAccessTech act = MM_MODEM_GSM_ACCESS_TECH_UNKNOWN;
+ GRegex *r;
+ GMatchInfo *match_info;
+ char *str;
+
+ if (!error) {
+ p = mm_strip_tag (response->str, "_OCTI:");
+
+ r = g_regex_new ("(\\d),(\\d)", G_REGEX_UNGREEDY, 0, NULL);
+ g_return_if_fail (r != NULL);
+
+ g_regex_match (r, p, 0, &match_info);
+ if (g_match_info_matches (match_info)) {
+ str = g_match_info_fetch (match_info, 2);
+ if (str && octi_to_mm (str[0], &act))
+ mm_generic_gsm_update_access_technology (MM_GENERIC_GSM (user_data), act);
+ g_free (str);
+ }
+ g_match_info_free (match_info);
+ g_regex_unref (r);
+ }
+}
+
+static void
+owcti_request_done (MMAtSerialPort *port,
+ GString *response,
+ GError *error,
+ gpointer user_data)
+{
+ const char *p;
+ MMModemGsmAccessTech act = MM_MODEM_GSM_ACCESS_TECH_UNKNOWN;
+
+ if (!error) {
+ p = mm_strip_tag (response->str, "_OWCTI:");
+ if (owcti_to_mm (*p, &act))
+ mm_generic_gsm_update_access_technology (MM_GENERIC_GSM (user_data), act);
+ }
+}
+
static void
option_ossys_tech_changed (MMAtSerialPort *port,
GMatchInfo *info,
@@ -161,13 +243,20 @@ option_ossys_tech_changed (MMAtSerialPort *port,
act = MM_MODEM_GSM_ACCESS_TECH_UMTS;
break;
default:
- /* _OSSYSI only indicates general 2G/3G mode */
break;
}
}
g_free (str);
mm_generic_gsm_update_access_technology (MM_GENERIC_GSM (user_data), act);
+
+ /* _OSSYSI only indicates general 2G/3G mode, so queue up some explicit
+ * access technology requests.
+ */
+ if (act == MM_MODEM_GSM_ACCESS_TECH_GPRS)
+ mm_at_serial_port_queue_command (port, "AT_OCTI?", 3, octi_request_done, user_data);
+ else if (act == MM_MODEM_GSM_ACCESS_TECH_UMTS)
+ mm_at_serial_port_queue_command (port, "AT_OWCTI?", 3, owcti_request_done, user_data);
}
static void
@@ -179,27 +268,9 @@ option_2g_tech_changed (MMAtSerialPort *port,
char *str;
str = g_match_info_fetch (match_info, 1);
- switch (atoi (str)) {
- case 1:
- act = MM_MODEM_GSM_ACCESS_TECH_GSM;
- break;
- case 2:
- act = MM_MODEM_GSM_ACCESS_TECH_GPRS;
- break;
- case 3:
- act = MM_MODEM_GSM_ACCESS_TECH_EDGE;
- break;
- default:
- break;
- }
+ if (octi_to_mm (str[0], &act))
+ mm_generic_gsm_update_access_technology (MM_GENERIC_GSM (user_data), act);
g_free (str);
-
- /* At the moment we can't do much with this since it's not consistently
- * reported by the modem. _OSSYSI appears to always be reported, but
- * doesn't provide the granularity that _OCTI and _OWCTI do, and so it
- * would overwrite any _OCTI or _OWCTI response, and cause the access tech
- * to flip-flop often.
- */
}
static void
@@ -211,30 +282,9 @@ option_3g_tech_changed (MMAtSerialPort *port,
char *str;
str = g_match_info_fetch (match_info, 1);
- switch (atoi (str)) {
- case 1:
- act = MM_MODEM_GSM_ACCESS_TECH_UMTS;
- break;
- case 2:
- act = MM_MODEM_GSM_ACCESS_TECH_HSDPA;
- break;
- case 3:
- act = MM_MODEM_GSM_ACCESS_TECH_HSUPA;
- break;
- case 4:
- act = MM_MODEM_GSM_ACCESS_TECH_HSPA;
- break;
- default:
- break;
- }
+ if (owcti_to_mm (str[0], &act))
+ mm_generic_gsm_update_access_technology (MM_GENERIC_GSM (user_data), act);
g_free (str);
-
- /* At the moment we can't do much with this since it's not consistently
- * reported by the modem. _OSSYSI appears to always be reported, but
- * doesn't provide the granularity that _OCTI and _OWCTI do, and so it
- * would overwrite any _OCTI or _OWCTI response, and cause the access tech
- * to flip-flop often.
- */
}
static void
@@ -273,7 +323,7 @@ option_register_unsolicted_handlers (MMGenericGsm *modem, MMAtSerialPort *port)
mm_at_serial_port_add_unsolicited_msg_handler (port, regex, option_2g_tech_changed, modem, NULL);
g_regex_unref (regex);
- regex = g_regex_new ("\\r\\n_OWCTI:\\s*(\\d+)\\r\\n", G_REGEX_RAW | G_REGEX_OPTIMIZE, 0, NULL);
+ regex = g_regex_new ("\\r\\n_OUWCTI:\\s*(\\d+)\\r\\n", G_REGEX_RAW | G_REGEX_OPTIMIZE, 0, NULL);
mm_at_serial_port_add_unsolicited_msg_handler (port, regex, option_3g_tech_changed, modem, NULL);
g_regex_unref (regex);
@@ -292,6 +342,7 @@ option_change_unsolicited_messages (MMGenericGsm *modem, gboolean enabled)
mm_at_serial_port_queue_command (primary, enabled ? "_OSSYS=1" : "_OSSYS=0", 3, NULL, NULL);
mm_at_serial_port_queue_command (primary, enabled ? "_OCTI=1" : "_OCTI=0", 3, NULL, NULL);
+ mm_at_serial_port_queue_command (primary, enabled ? "_OUWCTI=1" : "_OUWCTI=0", 3, NULL, NULL);
mm_at_serial_port_queue_command (primary, enabled ? "_OSQI=1" : "_OSQI=0", 3, NULL, NULL);
}