ublox: new +URAT=? response parser

This commit is contained in:
Aleksander Morgado
2016-08-08 10:57:34 +02:00
parent 3a886d848d
commit a4466e83b7
3 changed files with 231 additions and 0 deletions

View File

@@ -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;
}

View File

@@ -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 */

View File

@@ -181,6 +181,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
@@ -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 ();
}