diff options
author | Aleksander Morgado <aleksander@aleksander.es> | 2014-02-26 15:51:11 +0100 |
---|---|---|
committer | Aleksander Morgado <aleksander@aleksander.es> | 2014-02-28 16:35:18 +0100 |
commit | e6430acaaaa56eae95206a564109e2a04c99e7c5 (patch) | |
tree | 00e494a98dc76df790df293d34e413810d8da6ae | |
parent | 82067915d16a5e367346a3b62489b6efcb19f834 (diff) |
cinterion: add helper to parse AT^SCFG="Radio/Band" response in 3G devices
-rw-r--r-- | plugins/cinterion/mm-broadband-modem-cinterion.c | 68 | ||||
-rw-r--r-- | plugins/cinterion/mm-modem-helpers-cinterion.c | 71 | ||||
-rw-r--r-- | plugins/cinterion/mm-modem-helpers-cinterion.h | 7 | ||||
-rw-r--r-- | plugins/cinterion/tests/test-modem-helpers-cinterion.c | 60 |
4 files changed, 146 insertions, 60 deletions
diff --git a/plugins/cinterion/mm-broadband-modem-cinterion.c b/plugins/cinterion/mm-broadband-modem-cinterion.c index ae43493c..688cd2e0 100644 --- a/plugins/cinterion/mm-broadband-modem-cinterion.c +++ b/plugins/cinterion/mm-broadband-modem-cinterion.c @@ -1102,72 +1102,22 @@ get_2g_band_ready (MMBroadbandModemCinterion *self, static void get_3g_band_ready (MMBroadbandModemCinterion *self, GAsyncResult *res, - GSimpleAsyncResult *operation_result) + GSimpleAsyncResult *simple) { const gchar *response; GError *error = NULL; - GArray *bands_array = NULL; - GRegex *regex; - GMatchInfo *match_info = NULL; + GArray *bands = NULL; response = mm_base_modem_at_command_finish (MM_BASE_MODEM (self), res, &error); - if (!response) { - /* Let the error be critical. */ - g_simple_async_result_take_error (operation_result, error); - g_simple_async_result_complete (operation_result); - g_object_unref (operation_result); - return; - } - - /* The AT^SCFG? command replies a list of several different config - * values. We will only look for 'Radio/Band". - * - * AT+SCFG="Radio/Band" - * ^SCFG: "Radio/Band",127 - * - * Note that in this case, the <rba> replied is a number, not a string. - */ - regex = g_regex_new ("\\^SCFG:\\s*\"Radio/Band\",\\s*(\\d*)", 0, 0, NULL); - g_assert (regex != NULL); - - if (g_regex_match_full (regex, response, strlen (response), 0, 0, &match_info, NULL)) { - gchar *current; - - current = g_match_info_fetch (match_info, 1); - if (current) { - guint32 current_int; - guint i; - - current_int = (guint32) atoi (current); - - for (i = 0; i < G_N_ELEMENTS (bands_3g); i++) { - if (current_int & bands_3g[i].cinterion_band_flag) { - if (G_UNLIKELY (!bands_array)) - bands_array = g_array_new (FALSE, FALSE, sizeof (MMModemBand)); - g_array_append_val (bands_array, bands_3g[i].mm_band); - } - } - - g_free (current); - } - } - - if (match_info) - g_match_info_free (match_info); - g_regex_unref (regex); - - if (!bands_array) - g_simple_async_result_set_error (operation_result, - MM_CORE_ERROR, - MM_CORE_ERROR_FAILED, - "Couldn't parse current bands reply"); + if (!response) + g_simple_async_result_take_error (simple, error); + else if (!mm_cinterion_parse_scfg_3g_response (response, &bands, &error)) + g_simple_async_result_take_error (simple, error); else - g_simple_async_result_set_op_res_gpointer (operation_result, - bands_array, - (GDestroyNotify)g_array_unref); + g_simple_async_result_set_op_res_gpointer (simple, bands, (GDestroyNotify)g_array_unref); - g_simple_async_result_complete (operation_result); - g_object_unref (operation_result); + g_simple_async_result_complete (simple); + g_object_unref (simple); } static void diff --git a/plugins/cinterion/mm-modem-helpers-cinterion.c b/plugins/cinterion/mm-modem-helpers-cinterion.c index 7e350512..8fe641b7 100644 --- a/plugins/cinterion/mm-modem-helpers-cinterion.c +++ b/plugins/cinterion/mm-modem-helpers-cinterion.c @@ -15,6 +15,7 @@ #include <config.h> #include <string.h> +#include <stdlib.h> #include "ModemManager.h" #define _LIBMM_INSIDE_MM @@ -98,6 +99,8 @@ mm_cinterion_parse_scfg_3g_test (const gchar *response, } } } + + g_free (maxbandstr); } if (match_info) @@ -119,3 +122,71 @@ mm_cinterion_parse_scfg_3g_test (const gchar *response, return TRUE; } + +/*****************************************************************************/ +/* ^SCFG (3G) response parser + * + * Example: + * AT^SCFG="Radio/Band" + * ^SCFG: "Radio/Band",127 + */ + +gboolean +mm_cinterion_parse_scfg_3g_response (const gchar *response, + GArray **current_bands, + GError **error) +{ + GRegex *r; + GMatchInfo *match_info; + GError *inner_error = NULL; + GArray *bands = NULL; + + if (!response) { + g_set_error (error, MM_CORE_ERROR, MM_CORE_ERROR_FAILED, "Missing response"); + return FALSE; + } + + r = g_regex_new ("\\^SCFG:\\s*\"Radio/Band\",\\s*(\\d*)", 0, 0, NULL); + g_assert (r != NULL); + + if (g_regex_match_full (r, response, strlen (response), 0, 0, &match_info, NULL)) { + gchar *current; + + current = g_match_info_fetch (match_info, 1); + if (current) { + guint32 current_int; + guint i; + + current_int = (guint32) atoi (current); + + for (i = 0; i < G_N_ELEMENTS (bands_3g); i++) { + if (current_int & bands_3g[i].cinterion_band_flag) { + if (G_UNLIKELY (!bands)) + bands = g_array_sized_new (FALSE, FALSE, sizeof (MMModemBand), 4); + g_array_append_val (bands, bands_3g[i].mm_band); + } + } + + g_free (current); + } + } + + if (match_info) + g_match_info_free (match_info); + g_regex_unref (r); + + if (!bands) + inner_error = g_error_new (MM_CORE_ERROR, + MM_CORE_ERROR_FAILED, + "No valid bands found in ^SCFG=? response"); + + if (inner_error) { + g_propagate_error (error, inner_error); + return FALSE; + } + + g_assert (bands != NULL && bands->len > 0); + *current_bands = bands; + + return TRUE; +} diff --git a/plugins/cinterion/mm-modem-helpers-cinterion.h b/plugins/cinterion/mm-modem-helpers-cinterion.h index f71f951f..aa9f96aa 100644 --- a/plugins/cinterion/mm-modem-helpers-cinterion.h +++ b/plugins/cinterion/mm-modem-helpers-cinterion.h @@ -25,4 +25,11 @@ gboolean mm_cinterion_parse_scfg_3g_test (const gchar *response, GArray **supported_bands, GError **error); +/*****************************************************************************/ +/* ^SCFG response parser */ + +gboolean mm_cinterion_parse_scfg_3g_response (const gchar *response, + GArray **bands, + GError **error); + #endif /* MM_MODEM_HELPERS_CINTERION_H */ diff --git a/plugins/cinterion/tests/test-modem-helpers-cinterion.c b/plugins/cinterion/tests/test-modem-helpers-cinterion.c index 4f9436f0..cc603992 100644 --- a/plugins/cinterion/tests/test-modem-helpers-cinterion.c +++ b/plugins/cinterion/tests/test-modem-helpers-cinterion.c @@ -115,6 +115,63 @@ test_scfg (void) } /*****************************************************************************/ +/* Test ^SCFG responses */ + +static void +common_test_scfg_response (const gchar *response, + GArray *expected_bands) +{ + GArray *bands = NULL; + gchar *expected_bands_str; + gchar *bands_str; + GError *error = NULL; + gboolean res; + + res = mm_cinterion_parse_scfg_3g_response (response, &bands, &error); + g_assert_no_error (error); + g_assert (res == TRUE); + g_assert (bands != NULL); + + g_array_sort (bands, (GCompareFunc)sort_band); + g_array_sort (expected_bands, (GCompareFunc)sort_band); + + expected_bands_str = mm_common_build_bands_string ((const MMModemBand *)expected_bands->data, + expected_bands->len); + bands_str = mm_common_build_bands_string ((const MMModemBand *)bands->data, + bands->len); + + /* Instead of comparing the array one by one, compare the strings built from the mask + * (we get a nicer error if it fails) */ + g_assert_cmpstr (bands_str, ==, expected_bands_str); + + g_free (bands_str); + g_free (expected_bands_str); +} + +static void +test_scfg_response (void) +{ + GArray *expected_bands; + MMModemBand single; + const gchar *response = + "^SCFG: \"Radio/Band\",127\r\n" + "\r\n"; + + expected_bands = g_array_sized_new (FALSE, FALSE, sizeof (MMModemBand), 9); + single = MM_MODEM_BAND_EGSM, g_array_append_val (expected_bands, single); + single = MM_MODEM_BAND_DCS, g_array_append_val (expected_bands, single); + single = MM_MODEM_BAND_PCS, g_array_append_val (expected_bands, single); + single = MM_MODEM_BAND_G850, g_array_append_val (expected_bands, single); + single = MM_MODEM_BAND_U2100, g_array_append_val (expected_bands, single); + single = MM_MODEM_BAND_U1900, g_array_append_val (expected_bands, single); + single = MM_MODEM_BAND_U850, g_array_append_val (expected_bands, single); + + common_test_scfg_response (response, expected_bands); + + g_array_unref (expected_bands); +} + +/*****************************************************************************/ void _mm_log (const char *loc, @@ -143,7 +200,8 @@ int main (int argc, char **argv) g_type_init (); g_test_init (&argc, &argv, NULL); - g_test_add_func ("/MM/cinterion/scfg", test_scfg); + g_test_add_func ("/MM/cinterion/scfg", test_scfg); + g_test_add_func ("/MM/cinterion/scfg/response", test_scfg_response); return g_test_run (); } |