diff options
Diffstat (limited to 'plugins/mbm/mm-modem-helpers-mbm.c')
-rw-r--r-- | plugins/mbm/mm-modem-helpers-mbm.c | 100 |
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; +} |