diff options
-rw-r--r-- | plugins/cinterion/mm-modem-helpers-cinterion.c | 149 | ||||
-rw-r--r-- | plugins/cinterion/mm-modem-helpers-cinterion.h | 11 | ||||
-rw-r--r-- | plugins/cinterion/tests/test-modem-helpers-cinterion.c | 118 |
3 files changed, 278 insertions, 0 deletions
diff --git a/plugins/cinterion/mm-modem-helpers-cinterion.c b/plugins/cinterion/mm-modem-helpers-cinterion.c index 118cbb67..bffe00a9 100644 --- a/plugins/cinterion/mm-modem-helpers-cinterion.c +++ b/plugins/cinterion/mm-modem-helpers-cinterion.c @@ -20,6 +20,7 @@ #include "ModemManager.h" #define _LIBMM_INSIDE_MM #include <libmm-glib.h> +#include "mm-log.h" #include "mm-charsets.h" #include "mm-errors-types.h" #include "mm-modem-helpers-cinterion.h" @@ -235,6 +236,154 @@ mm_cinterion_parse_scfg_response (const gchar *response, } /*****************************************************************************/ +/* +CNMI test parser + * + * Example (PHS8): + * AT+CNMI=? + * +CNMI: (0,1,2),(0,1),(0,2),(0),(1) + */ + +static GArray * +read_number_list (const gchar *str) +{ + GError *inner_error = NULL; + GArray *out = NULL; + GRegex *r; + GMatchInfo *match_info; + + if (!str) + return NULL; + + r = g_regex_new ("(\\d),?", G_REGEX_UNGREEDY, 0, NULL); + g_assert (r != NULL); + + g_regex_match_full (r, str, strlen (str), 0, 0, &match_info, &inner_error); + while (!inner_error && g_match_info_matches (match_info)) { + guint aux; + + if (mm_get_uint_from_match_info (match_info, 1, &aux)) { + if (!out) + out = g_array_sized_new (FALSE, FALSE, sizeof (guint), 3); + g_array_append_val (out, aux); + } + g_match_info_next (match_info, &inner_error); + } + + if (inner_error) { + mm_warn ("Unexpected error matching +CNMI response: '%s'", inner_error->message); + g_error_free (inner_error); + } + + g_match_info_free (match_info); + g_regex_unref (r); + + return out; +} + +gboolean +mm_cinterion_parse_cnmi_test (const gchar *response, + GArray **supported_mode, + GArray **supported_mt, + GArray **supported_bm, + GArray **supported_ds, + GArray **supported_bfr, + GError **error) +{ + GRegex *r; + GMatchInfo *match_info; + GError *inner_error = NULL; + + if (!response) { + g_set_error (error, MM_CORE_ERROR, MM_CORE_ERROR_FAILED, "Missing response"); + return FALSE; + } + + r = g_regex_new ("\\+CNMI:\\s*\\((.*)\\),\\((.*)\\),\\((.*)\\),\\((.*)\\),\\((.*)\\)", + G_REGEX_DOLLAR_ENDONLY | G_REGEX_RAW, + 0, NULL); + g_assert (r != NULL); + + g_regex_match_full (r, response, strlen (response), 0, 0, &match_info, &inner_error); + if (!inner_error && g_match_info_matches (match_info)) { + if (supported_mode) { + gchar *str; + + str = mm_get_string_unquoted_from_match_info (match_info, 1); + *supported_mode = read_number_list (str); + g_free (str); + } + if (supported_mt) { + gchar *str; + + str = mm_get_string_unquoted_from_match_info (match_info, 2); + *supported_mt = read_number_list (str); + g_free (str); + } + if (supported_bm) { + gchar *str; + + str = mm_get_string_unquoted_from_match_info (match_info, 3); + *supported_bm = read_number_list (str); + g_free (str); + } + if (supported_ds) { + gchar *str; + + str = mm_get_string_unquoted_from_match_info (match_info, 4); + *supported_ds = read_number_list (str); + g_free (str); + } + if (supported_bfr) { + gchar *str; + + str = mm_get_string_unquoted_from_match_info (match_info, 5); + *supported_bfr = read_number_list (str); + g_free (str); + } + } + + if (match_info) + g_match_info_free (match_info); + g_regex_unref (r); + + if ((supported_mode && *supported_mode == NULL) || + (supported_mt && *supported_mt == NULL) || + (supported_bm && *supported_bm == NULL) || + (supported_ds && *supported_ds == NULL) || + (supported_bfr && *supported_bfr == NULL)) + inner_error = g_error_new (MM_CORE_ERROR, + MM_CORE_ERROR_FAILED, + "Error parsing +CNMI=? response"); + + if (inner_error) { + if (supported_mode && *supported_mode) { + g_array_unref (*supported_mode); + *supported_mode = NULL; + } + if (supported_mt && *supported_mt) { + g_array_unref (*supported_mt); + *supported_mt = NULL; + } + if (supported_bm && *supported_bm) { + g_array_unref (*supported_bm); + *supported_bm = NULL; + } + if (supported_ds && *supported_ds) { + g_array_unref (*supported_ds); + *supported_ds = NULL; + } + if (supported_bfr && *supported_bfr) { + g_array_unref (*supported_bfr); + *supported_bfr = NULL; + } + g_propagate_error (error, inner_error); + return FALSE; + } + + return TRUE; +} + +/*****************************************************************************/ /* Build Cinterion-specific band value */ gboolean diff --git a/plugins/cinterion/mm-modem-helpers-cinterion.h b/plugins/cinterion/mm-modem-helpers-cinterion.h index ecc10460..d37bcb07 100644 --- a/plugins/cinterion/mm-modem-helpers-cinterion.h +++ b/plugins/cinterion/mm-modem-helpers-cinterion.h @@ -35,6 +35,17 @@ gboolean mm_cinterion_parse_scfg_response (const gchar *response, GError **error); /*****************************************************************************/ +/* +CNMI test parser */ + +gboolean mm_cinterion_parse_cnmi_test (const gchar *response, + GArray **supported_mode, + GArray **supported_mt, + GArray **supported_bm, + GArray **supported_ds, + GArray **supported_bfr, + GError **error); + +/*****************************************************************************/ /* Build Cinterion-specific band value */ gboolean mm_cinterion_build_band (GArray *bands, diff --git a/plugins/cinterion/tests/test-modem-helpers-cinterion.c b/plugins/cinterion/tests/test-modem-helpers-cinterion.c index 7604dfaa..26b07ab2 100644 --- a/plugins/cinterion/tests/test-modem-helpers-cinterion.c +++ b/plugins/cinterion/tests/test-modem-helpers-cinterion.c @@ -213,6 +213,123 @@ test_scfg_response_3g (void) } /*****************************************************************************/ +/* Test ^SCFG test */ + +static void +compare_arrays (const GArray *supported, + const GArray *expected) +{ + guint i; + + g_assert_cmpuint (supported->len, ==, expected->len); + for (i = 0; i < supported->len; i++) { + gboolean found = FALSE; + guint j; + + for (j = 0; j < expected->len && !found; j++) { + if (g_array_index (supported, guint, i) == g_array_index (expected, guint, j)) + found = TRUE; + } + g_assert (found); + } +} + +static void +common_test_cnmi (const gchar *response, + const GArray *expected_mode, + const GArray *expected_mt, + const GArray *expected_bm, + const GArray *expected_ds, + const GArray *expected_bfr) +{ + GArray *supported_mode = NULL; + GArray *supported_mt = NULL; + GArray *supported_bm = NULL; + GArray *supported_ds = NULL; + GArray *supported_bfr = NULL; + GError *error = NULL; + gboolean res; + + g_assert (expected_mode != NULL); + g_assert (expected_mt != NULL); + g_assert (expected_bm != NULL); + g_assert (expected_ds != NULL); + g_assert (expected_bfr != NULL); + + res = mm_cinterion_parse_cnmi_test (response, + &supported_mode, + &supported_mt, + &supported_bm, + &supported_ds, + &supported_bfr, + &error); + g_assert_no_error (error); + g_assert (res == TRUE); + g_assert (supported_mode != NULL); + g_assert (supported_mt != NULL); + g_assert (supported_bm != NULL); + g_assert (supported_ds != NULL); + g_assert (supported_bfr != NULL); + + compare_arrays (supported_mode, expected_mode); + compare_arrays (supported_mt, expected_mt); + compare_arrays (supported_bm, expected_bm); + compare_arrays (supported_ds, expected_ds); + compare_arrays (supported_bfr, expected_bfr); + + g_array_unref (supported_mode); + g_array_unref (supported_mt); + g_array_unref (supported_bm); + g_array_unref (supported_ds); + g_array_unref (supported_bfr); +} + +static void +test_cnmi_phs8 (void) +{ + GArray *expected_mode; + GArray *expected_mt; + GArray *expected_bm; + GArray *expected_ds; + GArray *expected_bfr; + guint val; + const gchar *response = + "+CNMI: (0,1,2),(0,1),(0,2),(0),(1)\r\n" + "\r\n"; + + expected_mode = g_array_sized_new (FALSE, FALSE, sizeof (guint), 3); + val = 0, g_array_append_val (expected_mode, val); + val = 1, g_array_append_val (expected_mode, val); + val = 2, g_array_append_val (expected_mode, val); + + expected_mt = g_array_sized_new (FALSE, FALSE, sizeof (guint), 2); + val = 0, g_array_append_val (expected_mt, val); + val = 1, g_array_append_val (expected_mt, val); + + expected_bm = g_array_sized_new (FALSE, FALSE, sizeof (guint), 2); + val = 0, g_array_append_val (expected_bm, val); + val = 2, g_array_append_val (expected_bm, val); + + expected_ds = g_array_sized_new (FALSE, FALSE, sizeof (guint), 1); + val = 0, g_array_append_val (expected_ds, val); + + expected_bfr = g_array_sized_new (FALSE, FALSE, sizeof (guint), 1); + val = 1, g_array_append_val (expected_bfr, val); + + common_test_cnmi (response, + expected_mode, + expected_mt, + expected_bm, + expected_ds, + expected_bfr); + + g_array_unref (expected_mode); + g_array_unref (expected_mt); + g_array_unref (expected_bm); + g_array_unref (expected_ds); + g_array_unref (expected_bfr);} + +/*****************************************************************************/ /* Test ^SIND responses */ static void @@ -281,6 +398,7 @@ int main (int argc, char **argv) g_test_add_func ("/MM/cinterion/scfg/response/3g", test_scfg_response_3g); g_test_add_func ("/MM/cinterion/scfg/response/2g", test_scfg_response_2g); g_test_add_func ("/MM/cinterion/scfg/response/2g/ucs2", test_scfg_response_2g_ucs2); + g_test_add_func ("/MM/cinterion/cnmi/phs8", test_cnmi_phs8); g_test_add_func ("/MM/cinterion/sind/response/simstatus", test_sind_response_simstatus); return g_test_run (); |