summaryrefslogtreecommitdiff
path: root/plugins/mbm/mm-modem-helpers-mbm.c
diff options
context:
space:
mode:
Diffstat (limited to 'plugins/mbm/mm-modem-helpers-mbm.c')
-rw-r--r--plugins/mbm/mm-modem-helpers-mbm.c100
1 files changed, 99 insertions, 1 deletions
diff --git a/plugins/mbm/mm-modem-helpers-mbm.c b/plugins/mbm/mm-modem-helpers-mbm.c
index 42653d884..55557f20c 100644
--- a/plugins/mbm/mm-modem-helpers-mbm.c
+++ b/plugins/mbm/mm-modem-helpers-mbm.c
@@ -89,7 +89,7 @@ mm_mbm_parse_e2ipcfg_response (const gchar *response,
}
/* *E2IPCFG: (1,<IP>)(2,<gateway>)(3,<DNS>)(3,<DNS>)
- *
+ *
* *E2IPCFG: (1,"46.157.32.246")(2,"46.157.32.243")(3,"193.213.112.4")(3,"130.67.15.198")
* *E2IPCFG: (1,"fe80:0000:0000:0000:0000:0000:e537:1801")(3,"2001:4600:0004:0fff:0000:0000:0000:0054")(3,"2001:4600:0004:1fff:0000:0000:0000:0054")
* *E2IPCFG: (1,"fe80:0000:0000:0000:0000:0027:b7fe:9401")(3,"fd00:976a:0000:0000:0000:0000:0000:0009")
@@ -164,3 +164,101 @@ done:
return !!*ip_config;
}
+/*****************************************************************************/
+
+#define CFUN_TAG "+CFUN:"
+
+static void
+add_supported_mode (guint32 *mask,
+ guint mode)
+{
+ g_assert (mask);
+
+ if (mode >= 32)
+ g_warning ("Ignored unexpected mode in +CFUN match: %d", mode);
+ else
+ *mask |= (1 << mode);
+}
+
+gboolean
+mm_mbm_parse_cfun_test (const gchar *response,
+ guint32 *supported_mask,
+ GError **error)
+{
+ gchar **groups;
+ guint32 mask = 0;
+
+ g_assert (supported_mask);
+
+ if (!response || !g_str_has_prefix (response, CFUN_TAG)) {
+ g_set_error_literal (error, MM_CORE_ERROR, MM_CORE_ERROR_FAILED,
+ "Missing " CFUN_TAG " prefix");
+ return FALSE;
+ }
+
+ /*
+ * AT+CFUN=?
+ * +CFUN: (0,1,4-6),(0,1)
+ * OK
+ */
+
+ /* Strip tag from response */
+ response = mm_strip_tag (response, CFUN_TAG);
+
+ /* Split response in (groups) */
+ groups = mm_split_string_groups (response);
+
+ /* First group is the one listing supported modes */
+ if (groups && groups[0]) {
+ gchar **supported_modes;
+
+ supported_modes = g_strsplit_set (groups[0], ", ", -1);
+ if (supported_modes) {
+ guint i;
+
+ for (i = 0; supported_modes[i]; i++) {
+ gchar *separator;
+ guint mode;
+
+ if (!supported_modes[i][0])
+ continue;
+
+ /* Check if this is a range that's being given to us */
+ separator = strchr (supported_modes[i], '-');
+ if (separator) {
+ gchar *first_str;
+ gchar *last_str;
+ guint first;
+ guint last;
+
+ *separator = '\0';
+ first_str = supported_modes[i];
+ last_str = separator + 1;
+
+ if (!mm_get_uint_from_str (first_str, &first))
+ g_warning ("Couldn't match range start: '%s'", first_str);
+ else if (!mm_get_uint_from_str (last_str, &last))
+ g_warning ("Couldn't match range stop: '%s'", last_str);
+ else if (first >= last)
+ g_warning ("Couldn't match range: wrong first '%s' and last '%s' items", first_str, last_str);
+ else {
+ for (mode = first; mode <= last; mode++)
+ add_supported_mode (&mask, mode);
+ }
+ } else {
+ if (!mm_get_uint_from_str (supported_modes[i], &mode))
+ g_warning ("Couldn't match mode: '%s'", supported_modes[i]);
+ else
+ add_supported_mode (&mask, mode);
+ }
+ }
+
+ g_strfreev (supported_modes);
+ }
+ }
+ g_strfreev (groups);
+
+ if (mask)
+ *supported_mask = mask;
+ return !!mask;
+}