diff options
author | Aleksander Morgado <aleksander@aleksander.es> | 2016-08-08 10:57:34 +0200 |
---|---|---|
committer | Aleksander Morgado <aleksander@aleksander.es> | 2016-10-12 11:29:52 +0200 |
commit | a4466e83b71effb49d31d7fcbfe1f34c528fb547 (patch) | |
tree | 44b820b0728bcaa010a206f456f4f0bc475a7219 | |
parent | 3a886d848dadd98eda8dff354c1d10450d7613fe (diff) |
ublox: new +URAT=? response parser
-rw-r--r-- | plugins/ublox/mm-modem-helpers-ublox.c | 124 | ||||
-rw-r--r-- | plugins/ublox/mm-modem-helpers-ublox.h | 6 | ||||
-rw-r--r-- | plugins/ublox/tests/test-modem-helpers-ublox.c | 101 |
3 files changed, 231 insertions, 0 deletions
diff --git a/plugins/ublox/mm-modem-helpers-ublox.c b/plugins/ublox/mm-modem-helpers-ublox.c index 0b0461c9..b20381ff 100644 --- a/plugins/ublox/mm-modem-helpers-ublox.c +++ b/plugins/ublox/mm-modem-helpers-ublox.c @@ -16,6 +16,7 @@ #include <glib.h> #include <string.h> +#include "mm-log.h" #include "mm-modem-helpers.h" #include "mm-modem-helpers-ublox.h" @@ -239,3 +240,126 @@ out: *out_ipv6_link_local_address = ipv6_link_local_address; return TRUE; } + +/*****************************************************************************/ +/* URAT=? response parser */ + +/* Index of the array is the ublox-specific value */ +static const MMModemMode ublox_combinations[] = { + ( MM_MODEM_MODE_2G ), + ( MM_MODEM_MODE_2G | MM_MODEM_MODE_3G ), + ( MM_MODEM_MODE_3G ), + ( MM_MODEM_MODE_4G ), + ( MM_MODEM_MODE_2G | MM_MODEM_MODE_3G | MM_MODEM_MODE_4G ), + ( MM_MODEM_MODE_2G | MM_MODEM_MODE_4G ), + ( MM_MODEM_MODE_3G | MM_MODEM_MODE_4G ), +}; + +GArray * +mm_ublox_parse_urat_test_response (const gchar *response, + GError **error) +{ + GArray *combinations = NULL; + GArray *selected = NULL; + GArray *preferred = NULL; + gchar **split; + guint split_len; + GError *inner_error = NULL; + guint i; + + /* + * E.g.: + * AT+URAT=? + * +URAT: (0-6),(0,2,3) + */ + response = mm_strip_tag (response, "+URAT:"); + split = mm_split_string_groups (response); + split_len = g_strv_length (split); + if (split_len > 2 || split_len < 1) { + inner_error = g_error_new (MM_CORE_ERROR, MM_CORE_ERROR_FAILED, + "Unexpected number of groups in +URAT=? response: %u", g_strv_length (split)); + goto out; + } + + /* The selected list must have values */ + selected = mm_parse_uint_list (split[0], &inner_error); + if (inner_error) + goto out; + + if (!selected) { + inner_error = g_error_new (MM_CORE_ERROR, MM_CORE_ERROR_FAILED, + "No selected RAT values given in +URAT=? response"); + goto out; + } + + /* For our purposes, the preferred list may be empty */ + preferred = mm_parse_uint_list (split[1], &inner_error); + if (inner_error) + goto out; + + /* Build array of combinations */ + combinations = g_array_new (FALSE, FALSE, sizeof (MMModemModeCombination)); + + for (i = 0; i < selected->len; i++) { + guint selected_value; + MMModemModeCombination combination; + guint j; + + selected_value = g_array_index (selected, guint, i); + if (selected_value >= G_N_ELEMENTS (ublox_combinations)) { + mm_warn ("Unexpected AcT value: %u", selected_value); + continue; + } + + /* Combination without any preferred */ + combination.allowed = ublox_combinations[selected_value]; + combination.preferred = MM_MODEM_MODE_NONE; + g_array_append_val (combinations, combination); + + if (mm_count_bits_set (combination.allowed) == 1) + continue; + + if (!preferred) + continue; + + for (j = 0; j < preferred->len; j++) { + guint preferred_value; + + preferred_value = g_array_index (preferred, guint, j); + if (preferred_value >= G_N_ELEMENTS (ublox_combinations)) { + mm_warn ("Unexpected AcT preferred value: %u", preferred_value); + continue; + } + combination.preferred = ublox_combinations[preferred_value]; + if (mm_count_bits_set (combination.preferred) != 1) { + mm_warn ("AcT preferred value should be a single AcT: %u", preferred_value); + continue; + } + if (!(combination.allowed & combination.preferred)) + continue; + g_array_append_val (combinations, combination); + } + } + + if (combinations->len == 0) { + inner_error = g_error_new (MM_CORE_ERROR, MM_CORE_ERROR_FAILED, + "No combinations built from +URAT=? response"); + goto out; + } + +out: + g_strfreev (split); + if (selected) + g_array_unref (selected); + if (preferred) + g_array_unref (preferred); + + if (inner_error) { + if (combinations) + g_array_unref (combinations); + g_propagate_error (error, inner_error); + return NULL; + } + + return combinations; +} diff --git a/plugins/ublox/mm-modem-helpers-ublox.h b/plugins/ublox/mm-modem-helpers-ublox.h index c97724da..2e25a10e 100644 --- a/plugins/ublox/mm-modem-helpers-ublox.h +++ b/plugins/ublox/mm-modem-helpers-ublox.h @@ -57,4 +57,10 @@ gboolean mm_ublox_parse_uipaddr_response (const gchar *response, gchar **out_ipv6_link_local_address, GError **error); +/*****************************************************************************/ +/* URAT=? response parser */ + +GArray *mm_ublox_parse_urat_test_response (const gchar *response, + GError **error); + #endif /* MM_MODEM_HELPERS_UBLOX_H */ diff --git a/plugins/ublox/tests/test-modem-helpers-ublox.c b/plugins/ublox/tests/test-modem-helpers-ublox.c index d1e5e497..814e3811 100644 --- a/plugins/ublox/tests/test-modem-helpers-ublox.c +++ b/plugins/ublox/tests/test-modem-helpers-ublox.c @@ -182,6 +182,97 @@ test_uipaddr_response (void) } /*****************************************************************************/ +/* Test URAT=? responses */ + +static void +compare_combinations (const gchar *response, + const MMModemModeCombination *expected_combinations, + guint n_expected_combinations) +{ + GArray *combinations; + GError *error = NULL; + guint i; + + combinations = mm_ublox_parse_urat_test_response (response, &error); + g_assert_no_error (error); + g_assert (combinations); + + g_assert_cmpuint (combinations->len, ==, n_expected_combinations); + + for (i = 0; i < combinations->len; i++) { + MMModemModeCombination combination; + guint j; + gboolean found = FALSE; + + combination = g_array_index (combinations, MMModemModeCombination, i); + for (j = 0; !found && j < n_expected_combinations; j++) + found = (combination.allowed == expected_combinations[j].allowed && + combination.preferred == expected_combinations[j].preferred); + g_assert (found); + } + + g_array_unref (combinations); +} + +static void +test_urat_test_response_2g (void) +{ + static const MMModemModeCombination expected_combinations[] = { + { MM_MODEM_MODE_2G, MM_MODEM_MODE_NONE } + }; + + compare_combinations ("+URAT: 0", expected_combinations, G_N_ELEMENTS (expected_combinations)); + compare_combinations ("+URAT: 0,0", expected_combinations, G_N_ELEMENTS (expected_combinations)); + compare_combinations ("+URAT: (0)", expected_combinations, G_N_ELEMENTS (expected_combinations)); + compare_combinations ("+URAT: (0),(0)", expected_combinations, G_N_ELEMENTS (expected_combinations)); +} + +static void +test_urat_test_response_2g3g (void) +{ + static const MMModemModeCombination expected_combinations[] = { + { MM_MODEM_MODE_2G, MM_MODEM_MODE_NONE }, + { MM_MODEM_MODE_3G, MM_MODEM_MODE_NONE }, + { MM_MODEM_MODE_2G | MM_MODEM_MODE_3G, MM_MODEM_MODE_NONE }, + { MM_MODEM_MODE_2G | MM_MODEM_MODE_3G, MM_MODEM_MODE_2G }, + { MM_MODEM_MODE_2G | MM_MODEM_MODE_3G, MM_MODEM_MODE_3G }, + }; + + compare_combinations ("+URAT: (0,1,2),(0,2)", expected_combinations, G_N_ELEMENTS (expected_combinations)); + compare_combinations ("+URAT: (0-2),(0,2)", expected_combinations, G_N_ELEMENTS (expected_combinations)); +} + +static void +test_urat_test_response_2g3g4g (void) +{ + static const MMModemModeCombination expected_combinations[] = { + { MM_MODEM_MODE_2G, MM_MODEM_MODE_NONE }, + { MM_MODEM_MODE_3G, MM_MODEM_MODE_NONE }, + { MM_MODEM_MODE_4G, MM_MODEM_MODE_NONE }, + + { MM_MODEM_MODE_2G | MM_MODEM_MODE_3G, MM_MODEM_MODE_NONE }, + { MM_MODEM_MODE_2G | MM_MODEM_MODE_3G, MM_MODEM_MODE_2G }, + { MM_MODEM_MODE_2G | MM_MODEM_MODE_3G, MM_MODEM_MODE_3G }, + + { MM_MODEM_MODE_2G | MM_MODEM_MODE_4G, MM_MODEM_MODE_NONE }, + { MM_MODEM_MODE_2G | MM_MODEM_MODE_4G, MM_MODEM_MODE_2G }, + { MM_MODEM_MODE_2G | MM_MODEM_MODE_4G, MM_MODEM_MODE_4G }, + + { MM_MODEM_MODE_3G | MM_MODEM_MODE_4G, MM_MODEM_MODE_NONE }, + { MM_MODEM_MODE_3G | MM_MODEM_MODE_4G, MM_MODEM_MODE_3G }, + { MM_MODEM_MODE_3G | MM_MODEM_MODE_4G, MM_MODEM_MODE_4G }, + + { MM_MODEM_MODE_2G | MM_MODEM_MODE_3G | MM_MODEM_MODE_4G, MM_MODEM_MODE_NONE }, + { MM_MODEM_MODE_2G | MM_MODEM_MODE_3G | MM_MODEM_MODE_4G, MM_MODEM_MODE_2G }, + { MM_MODEM_MODE_2G | MM_MODEM_MODE_3G | MM_MODEM_MODE_4G, MM_MODEM_MODE_3G }, + { MM_MODEM_MODE_2G | MM_MODEM_MODE_3G | MM_MODEM_MODE_4G, MM_MODEM_MODE_4G }, + }; + + compare_combinations ("+URAT: (0,1,2,3,4,5,6),(0,2,3)", expected_combinations, G_N_ELEMENTS (expected_combinations)); + compare_combinations ("+URAT: (0-6),(0,2,3)", expected_combinations, G_N_ELEMENTS (expected_combinations)); +} + +/*****************************************************************************/ void _mm_log (const char *loc, @@ -210,9 +301,19 @@ int main (int argc, char **argv) g_type_init (); g_test_init (&argc, &argv, NULL); +<<<<<<< HEAD g_test_add_func ("/MM/ublox/uusbconf/response", test_uusbconf_response); g_test_add_func ("/MM/ublox/ubmconf/response", test_ubmconf_response); g_test_add_func ("/MM/ublox/uipaddr/response", test_uipaddr_response); +======= + g_test_add_func ("/MM/ublox/uusbconf/response", test_uusbconf_response); + g_test_add_func ("/MM/ublox/ubmconf/response", test_ubmconf_response); + g_test_add_func ("/MM/ublox/uipaddr/response", test_uipaddr_response); + g_test_add_func ("/MM/ublox/cgcontrdp/response", test_cgcontrdp_response); + g_test_add_func ("/MM/ublox/urat/test/response/2g", test_urat_test_response_2g); + g_test_add_func ("/MM/ublox/urat/test/response/2g3g", test_urat_test_response_2g3g); + g_test_add_func ("/MM/ublox/urat/test/response/2g3g4g", test_urat_test_response_2g3g4g); +>>>>>>> 759a486... ublox: new +URAT=? response parser return g_test_run (); } |