ublox: new +URAT=? response parser
This commit is contained in:
@@ -16,6 +16,7 @@
|
|||||||
#include <glib.h>
|
#include <glib.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
|
||||||
|
#include "mm-log.h"
|
||||||
#include "mm-modem-helpers.h"
|
#include "mm-modem-helpers.h"
|
||||||
#include "mm-modem-helpers-ublox.h"
|
#include "mm-modem-helpers-ublox.h"
|
||||||
|
|
||||||
@@ -239,3 +240,126 @@ out:
|
|||||||
*out_ipv6_link_local_address = ipv6_link_local_address;
|
*out_ipv6_link_local_address = ipv6_link_local_address;
|
||||||
return TRUE;
|
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;
|
||||||
|
}
|
||||||
|
@@ -57,4 +57,10 @@ gboolean mm_ublox_parse_uipaddr_response (const gchar *response,
|
|||||||
gchar **out_ipv6_link_local_address,
|
gchar **out_ipv6_link_local_address,
|
||||||
GError **error);
|
GError **error);
|
||||||
|
|
||||||
|
/*****************************************************************************/
|
||||||
|
/* URAT=? response parser */
|
||||||
|
|
||||||
|
GArray *mm_ublox_parse_urat_test_response (const gchar *response,
|
||||||
|
GError **error);
|
||||||
|
|
||||||
#endif /* MM_MODEM_HELPERS_UBLOX_H */
|
#endif /* MM_MODEM_HELPERS_UBLOX_H */
|
||||||
|
@@ -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
|
void
|
||||||
@@ -210,9 +301,19 @@ int main (int argc, char **argv)
|
|||||||
g_type_init ();
|
g_type_init ();
|
||||||
g_test_init (&argc, &argv, NULL);
|
g_test_init (&argc, &argv, NULL);
|
||||||
|
|
||||||
|
<<<<<<< HEAD
|
||||||
g_test_add_func ("/MM/ublox/uusbconf/response", test_uusbconf_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/ubmconf/response", test_ubmconf_response);
|
||||||
g_test_add_func ("/MM/ublox/uipaddr/response", test_uipaddr_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 ();
|
return g_test_run ();
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user