aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAleksander Morgado <aleksander@aleksander.es>2016-08-08 10:57:34 +0200
committerAleksander Morgado <aleksander@aleksander.es>2016-10-12 11:29:52 +0200
commita4466e83b71effb49d31d7fcbfe1f34c528fb547 (patch)
tree44b820b0728bcaa010a206f456f4f0bc475a7219
parent3a886d848dadd98eda8dff354c1d10450d7613fe (diff)
ublox: new +URAT=? response parser
-rw-r--r--plugins/ublox/mm-modem-helpers-ublox.c124
-rw-r--r--plugins/ublox/mm-modem-helpers-ublox.h6
-rw-r--r--plugins/ublox/tests/test-modem-helpers-ublox.c101
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 ();
}