diff options
author | Aleksander Morgado <aleksander@aleksander.es> | 2015-12-21 17:08:53 +0100 |
---|---|---|
committer | Aleksander Morgado <aleksander@aleksander.es> | 2016-01-10 17:46:12 +0100 |
commit | 0ebf6d5da5b013faceb8d635d0896e9794c35fae (patch) | |
tree | 61c44dae4f955320ac0e26b9358d89ab1a281e1e /plugins/mbm/mm-modem-helpers-mbm.c | |
parent | 138b3dabc23f7e56adccbd76c42d9136af5b4329 (diff) |
mbm: query supported modes to the modem with +CFUN=?
We were trying to load the generic modes supported reported by either *CNTI=2 or
AT+WS46=?, so that then we could filter out the MBM-specific modes unsupported.
But, this may not be ideal, as both these two commands may fail:
[mm-broadband-modem.c:1612] modem_load_supported_modes(): loading supported modes...
[mm-port-serial.c:1237] mm_port_serial_open(): (ttyACM1) device open count is 3 (open)
[mm-port-serial.c:1294] _close_internal(): (ttyACM1) device open count is 2 (close)
[mm-port-serial-at.c:440] debug_log(): (ttyACM1): --> 'AT*CNTI=2<CR>'
[mm-port-serial-at.c:440] debug_log(): (ttyACM1): <-- '<CR><LF>ERROR<CR><LF>'
[mm-serial-parsers.c:364] mm_serial_parser_v1_parse(): Got failure code 100: Unknown error
[mm-broadband-modem.c:1546] supported_modes_cnti_ready(): Generic query of supported 3GPP networks with *CNTI failed: 'Unknown error'
[mm-port-serial.c:1237] mm_port_serial_open(): (ttyACM1) device open count is 3 (open)
[mm-port-serial.c:1294] _close_internal(): (ttyACM1) device open count is 2 (close)
[mm-port-serial-at.c:440] debug_log(): (ttyACM1): --> 'AT+WS46=?<CR>'
[mm-port-serial-at.c:440] debug_log(): (ttyACM1): <-- '<CR><LF>ERROR<CR><LF>'
[mm-serial-parsers.c:364] mm_serial_parser_v1_parse(): Got failure code 100: Unknown error
[mm-broadband-modem.c:1494] supported_modes_ws46_test_ready(): Generic query of supported 3GPP networks with WS46=? failed: 'Unknown error'
[mm-iface-modem.c:3974] load_supported_modes_ready(): couldn't load Supported Modes: 'Couldn't retrieve supported modes'
Instead, we'll ask the modem for the list of modes supported, and return that
directly.
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 42653d88..55557f20 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; +} |