diff options
author | Aleksander Morgado <aleksander@lanedo.com> | 2013-11-08 00:06:07 +0100 |
---|---|---|
committer | Aleksander Morgado <aleksander@lanedo.com> | 2013-11-11 16:49:49 +0100 |
commit | beb8316d6e8614d09cb6759cce6ee246d6e42f00 (patch) | |
tree | cf0e886ee69081ab8fe492bedb3d1098f0b72f53 | |
parent | 75e924bd0f97306d4e2e1530a21df0ecb11a5eca (diff) | |
download | ModemManager-beb8316d6e8614d09cb6759cce6ee246d6e42f00.tar.gz |
huawei: new ^SYSCFGEX=? test parser
-rw-r--r-- | plugins/huawei/mm-modem-helpers-huawei.c | 180 | ||||
-rw-r--r-- | plugins/huawei/mm-modem-helpers-huawei.h | 12 | ||||
-rw-r--r-- | plugins/huawei/tests/test-modem-helpers-huawei.c | 185 |
3 files changed, 377 insertions, 0 deletions
diff --git a/plugins/huawei/mm-modem-helpers-huawei.c b/plugins/huawei/mm-modem-helpers-huawei.c index 7322e3cb1..0bbbfc866 100644 --- a/plugins/huawei/mm-modem-helpers-huawei.c +++ b/plugins/huawei/mm-modem-helpers-huawei.c @@ -662,3 +662,183 @@ mm_huawei_parse_syscfg_test (const gchar *response, return out; } + +/*****************************************************************************/ +/* ^SYSCFGEX test parser */ + +static void +huawei_syscfgex_combination_free (MMHuaweiSyscfgexCombination *item) +{ + /* Just the contents, not the item itself! */ + g_free (item->mode_str); +} + +static gboolean +parse_mode_combination_string (const gchar *mode_str, + MMModemMode *allowed, + MMModemMode *preferred) +{ + guint n; + + if (g_str_equal (mode_str, "00")) { + *allowed = MM_MODEM_MODE_ANY; + *preferred = MM_MODEM_MODE_NONE; + return TRUE; + } + + *allowed = MM_MODEM_MODE_NONE; + *preferred = MM_MODEM_MODE_NONE; + + for (n = 0; n < strlen (mode_str); n+=2) { + MMModemMode mode; + + if (g_ascii_strncasecmp (&mode_str[n], "01", 2) == 0) + /* GSM */ + mode = MM_MODEM_MODE_2G; + else if (g_ascii_strncasecmp (&mode_str[n], "02", 2) == 0) + /* WCDMA */ + mode = MM_MODEM_MODE_3G; + else if (g_ascii_strncasecmp (&mode_str[n], "03", 2) == 0) + /* LTE */ + mode = MM_MODEM_MODE_4G; + else if (g_ascii_strncasecmp (&mode_str[n], "04", 2) == 0) + /* CDMA Note: no EV-DO, just return single value, so assume CDMA1x*/ + mode = MM_MODEM_MODE_2G; + else + mode = MM_MODEM_MODE_NONE; + + if (mode != MM_MODEM_MODE_NONE) { + /* The first one in the list is the preferred combination */ + if (n == 0) + *preferred |= mode; + *allowed |= mode; + } + } + + switch (mm_count_bits_set (*allowed)) { + case 0: + /* No allowed, error */ + return FALSE; + case 1: + /* If only one mode allowed, NONE preferred */ + *preferred = MM_MODEM_MODE_NONE; + /* fall down */ + default: + return TRUE; + } +} + +static GArray * +parse_mode_combination_string_list (const gchar *modes_str, + GError **error) +{ + GArray *supported_mode_combinations; + gchar **mode_combinations; + MMModemMode all = MM_MODEM_MODE_NONE; + gboolean has_all = FALSE; + guint i; + + mode_combinations = g_strsplit (modes_str, ",", -1); + supported_mode_combinations = g_array_sized_new (FALSE, + FALSE, + sizeof (MMHuaweiSyscfgexCombination), + g_strv_length (mode_combinations)); + g_array_set_clear_func (supported_mode_combinations, + (GDestroyNotify)huawei_syscfgex_combination_free); + + for (i = 0; mode_combinations[i]; i++) { + MMHuaweiSyscfgexCombination combination; + + mode_combinations[i] = mm_strip_quotes (mode_combinations[i]); + if (!parse_mode_combination_string (mode_combinations[i], + &combination.allowed, + &combination.preferred)) + continue; + + if (combination.allowed != MM_MODEM_MODE_ANY) { + combination.mode_str = g_strdup (mode_combinations[i]); + g_array_append_val (supported_mode_combinations, combination); + + all |= combination.allowed; + } else { + /* don't add the all_combination here, we may have more + * combinations in the loop afterwards */ + has_all = TRUE; + } + } + + /* Add here the all_combination */ + if (has_all) { + MMHuaweiSyscfgexCombination combination; + + combination.allowed = all; + combination.preferred = MM_MODEM_MODE_NONE; + combination.mode_str = g_strdup ("00"); + g_array_append_val (supported_mode_combinations, combination); + } + + /* If we didn't build a valid array of combinations, return an error */ + if (supported_mode_combinations->len == 0) { + g_set_error (error, + MM_CORE_ERROR, + MM_CORE_ERROR_FAILED, + "Cannot parse list of allowed mode combinations: '%s'", + modes_str); + g_array_unref (supported_mode_combinations); + return NULL; + } + + return supported_mode_combinations; +} + +GArray * +mm_huawei_parse_syscfgex_test (const gchar *response, + GError **error) +{ + gchar **split; + GError *inner_error = NULL; + GArray *out; + + if (!response || !g_str_has_prefix (response, "^SYSCFGEX:")) { + g_set_error (error, + MM_CORE_ERROR, + MM_CORE_ERROR_FAILED, + "Missing ^SYSCFGEX prefix"); + return NULL; + } + + /* Examples: + * + * ^SYSCFGEX: ("00","03","02","01","99"), + * ((2000004e80380,"GSM850/GSM900/GSM1800/GSM1900/WCDMA850/WCDMA900/WCDMA1900/WCDMA2100"), + * (3fffffff,"All Bands")), + * (0-3), + * (0-4), + * ((800c5,"LTE2100/LTE1800/LTE2600/LTE900/LTE800"), + * (7fffffffffffffff,"All bands")) + */ + split = split_groups (mm_strip_tag (response, "^SYSCFGEX:"), error); + if (!split) + return NULL; + + /* We expect 5 string chunks */ + if (g_strv_length (split) < 5) { + g_set_error (error, + MM_CORE_ERROR, + MM_CORE_ERROR_FAILED, + "Unexpected ^SYSCFGEX format"); + g_strfreev (split); + return NULL; + } + + out = parse_mode_combination_string_list (split[0], &inner_error); + + g_strfreev (split); + + if (inner_error) { + g_propagate_error (error, inner_error); + return NULL; + } + + return out; +} diff --git a/plugins/huawei/mm-modem-helpers-huawei.h b/plugins/huawei/mm-modem-helpers-huawei.h index d0cbf6936..687c82d6a 100644 --- a/plugins/huawei/mm-modem-helpers-huawei.h +++ b/plugins/huawei/mm-modem-helpers-huawei.h @@ -76,4 +76,16 @@ typedef struct { GArray *mm_huawei_parse_syscfg_test (const gchar *response, GError **error); +/*****************************************************************************/ +/* ^SYSCFGEX test parser */ + +typedef struct { + gchar *mode_str; + MMModemMode allowed; + MMModemMode preferred; +} MMHuaweiSyscfgexCombination; + +GArray *mm_huawei_parse_syscfgex_test (const gchar *response, + GError **error); + #endif /* MM_MODEM_HELPERS_HUAWEI_H */ diff --git a/plugins/huawei/tests/test-modem-helpers-huawei.c b/plugins/huawei/tests/test-modem-helpers-huawei.c index fbf287f09..b1105605e 100644 --- a/plugins/huawei/tests/test-modem-helpers-huawei.c +++ b/plugins/huawei/tests/test-modem-helpers-huawei.c @@ -523,6 +523,190 @@ test_syscfg (void) } /*****************************************************************************/ +/* Test ^SYSCFGEX=? responses */ + +#define MAX_SYSCFGEX_COMBINATIONS 5 + +typedef struct { + const gchar *str; + MMHuaweiSyscfgexCombination expected_modes[MAX_SYSCFGEX_COMBINATIONS]; +} SyscfgexTest; + +static const SyscfgexTest syscfgex_tests[] = { + { + "^SYSCFGEX: (\"00\",\"03\",\"02\",\"01\",\"99\")," + "((2000004e80380,\"GSM850/GSM900/GSM1800/GSM1900/WCDMA850/WCDMA900/WCDMA1900/WCDMA2100\"),(3fffffff,\"All Bands\"))," + "(0-3)," + "(0-4)," + "((800c5,\"LTE2100/LTE1800/LTE2600/LTE900/LTE800\"),(7fffffffffffffff,\"All bands\"))" + "\r\n", + { + { + .mode_str = "00", + .allowed = (MM_MODEM_MODE_4G | MM_MODEM_MODE_3G | MM_MODEM_MODE_2G), + .preferred = MM_MODEM_MODE_NONE + }, + { + .mode_str = "03", + .allowed = MM_MODEM_MODE_4G, + .preferred = MM_MODEM_MODE_NONE + }, + { + .mode_str = "02", + .allowed = MM_MODEM_MODE_3G, + .preferred = MM_MODEM_MODE_NONE + }, + { + .mode_str = "01", + .allowed = MM_MODEM_MODE_2G, + .preferred = MM_MODEM_MODE_NONE + }, + { NULL, 0, 0 } + } + }, + { + "^SYSCFGEX: (\"030201\",\"0302\",\"03\",\"99\")," + "((2000004e80380,\"GSM850/GSM900/GSM1800/GSM1900/WCDMA850/WCDMA900/WCDMA1900/WCDMA2100\"),(3fffffff,\"All Bands\"))," + "(0-3)," + "(0-4)," + "((800c5,\"LTE2100/LTE1800/LTE2600/LTE900/LTE800\"),(7fffffffffffffff,\"All bands\"))" + "\r\n", + { + { + .mode_str = "030201", + .allowed = (MM_MODEM_MODE_4G | MM_MODEM_MODE_3G | MM_MODEM_MODE_2G), + .preferred = MM_MODEM_MODE_4G + }, + { + .mode_str = "0302", + .allowed = (MM_MODEM_MODE_4G | MM_MODEM_MODE_3G), + .preferred = MM_MODEM_MODE_4G + }, + { + .mode_str = "03", + .allowed = MM_MODEM_MODE_4G, + .preferred = MM_MODEM_MODE_NONE + }, + { NULL, 0, 0 } + } + }, + { + "^SYSCFGEX: (\"03\")," + "((2000004e80380,\"GSM850/GSM900/GSM1800/GSM1900/WCDMA850/WCDMA900/WCDMA1900/WCDMA2100\"),(3fffffff,\"All Bands\"))," + "(0-3)," + "(0-4)," + "((800c5,\"LTE2100/LTE1800/LTE2600/LTE900/LTE800\"),(7fffffffffffffff,\"All bands\"))" + "\r\n", + { + { + .mode_str = "03", + .allowed = MM_MODEM_MODE_4G, + .preferred = MM_MODEM_MODE_NONE + }, + { NULL, 0, 0 } + } + }, + { + "^SYSCFGEX: (\"00\",\"01\",\"02\",\"0102\",\"0201\")," + "((3fffffff,\"All Bands\"),(2000000400180,\"GSM900/GSM1800/WCDMA900/WCDMA2100\"),(6A80000,\"GSM850/GSM1900/WCDMA850/AWS/WCDMA1900\"))," + "(0-2)," + "(0-4)," + "," /* NOTE: Non-LTE modem, LTE Bands EMPTY */ + "\r\n", + { + { + .mode_str = "00", + .allowed = (MM_MODEM_MODE_3G | MM_MODEM_MODE_2G), + .preferred = MM_MODEM_MODE_NONE + }, + { + .mode_str = "01", + .allowed = MM_MODEM_MODE_2G, + .preferred = MM_MODEM_MODE_NONE + }, + { + .mode_str = "02", + .allowed = MM_MODEM_MODE_3G, + .preferred = MM_MODEM_MODE_NONE + }, + { + .mode_str = "0102", + .allowed = (MM_MODEM_MODE_2G | MM_MODEM_MODE_3G), + .preferred = MM_MODEM_MODE_2G + }, + { + .mode_str = "0201", + .allowed = (MM_MODEM_MODE_2G | MM_MODEM_MODE_3G), + .preferred = MM_MODEM_MODE_3G + } + } + } +}; + +static void +test_syscfgex (void) +{ + guint i; + + for (i = 0; i < G_N_ELEMENTS (syscfgex_tests); i++) { + GError *error = NULL; + GArray *combinations = NULL; + guint j; + guint n_expected_combinations = 0; + + for (j = 0; j < MAX_SYSCFGEX_COMBINATIONS; j++) { + if (syscfgex_tests[i].expected_modes[j].mode_str != NULL) + n_expected_combinations++; + } + + combinations = mm_huawei_parse_syscfgex_test (syscfgex_tests[i].str, &error); + g_assert_no_error (error); + g_assert (combinations != NULL); + g_assert_cmpuint (combinations->len, ==, n_expected_combinations); + +#if defined ENABLE_TEST_MESSAGE_TRACES + for (j = 0; j < combinations->len; j++) { + MMHuaweiSyscfgexCombination *single; + gchar *allowed_str; + gchar *preferred_str; + + single = &g_array_index (combinations, MMHuaweiSyscfgexCombination, j); + allowed_str = mm_modem_mode_build_string_from_mask (single->allowed); + preferred_str = mm_modem_mode_build_string_from_mask (single->preferred); + mm_dbg ("Test[%u], Combination[%u]: \"%s\", \"%s\", \"%s\"", + i, + j, + single->mode_str, + allowed_str, + preferred_str); + g_free (allowed_str); + g_free (preferred_str); + } +#endif + + for (j = 0; j < combinations->len; j++) { + MMHuaweiSyscfgexCombination *single; + guint k; + gboolean found = FALSE; + + single = &g_array_index (combinations, MMHuaweiSyscfgexCombination, j); + for (k = 0; k <= n_expected_combinations; k++) { + if (g_str_equal (single->mode_str, syscfgex_tests[i].expected_modes[k].mode_str) && + single->allowed == syscfgex_tests[i].expected_modes[k].allowed && + single->preferred == syscfgex_tests[i].expected_modes[k].preferred) { + found = TRUE; + break; + } + } + + g_assert (found == TRUE); + } + + g_array_unref (combinations); + } +} + +/*****************************************************************************/ void _mm_log (const char *loc, @@ -556,6 +740,7 @@ int main (int argc, char **argv) g_test_add_func ("/MM/huawei/sysinfoex", test_sysinfoex); g_test_add_func ("/MM/huawei/prefmode", test_prefmode); g_test_add_func ("/MM/huawei/syscfg", test_syscfg); + g_test_add_func ("/MM/huawei/syscfgex", test_syscfgex); return g_test_run (); } |