xmm: new common XACT? parser for Intel XMM based devices
This commit is contained in:

committed by
Dan Williams

parent
142f1d0360
commit
023ba97d9c
@@ -338,3 +338,123 @@ out:
|
||||
*bands_out = bands;
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
/* AT+XACT? response parser */
|
||||
|
||||
gboolean
|
||||
mm_xmm_parse_xact_query_response (const gchar *response,
|
||||
MMModemModeCombination *mode_out,
|
||||
GArray **bands_out,
|
||||
GError **error)
|
||||
{
|
||||
GRegex *r;
|
||||
GMatchInfo *match_info;
|
||||
GError *inner_error = NULL;
|
||||
GArray *bands = NULL;
|
||||
guint i;
|
||||
|
||||
MMModemModeCombination mode = {
|
||||
.allowed = MM_MODEM_MODE_NONE,
|
||||
.preferred = MM_MODEM_MODE_NONE,
|
||||
};
|
||||
|
||||
/* At least one */
|
||||
g_assert (mode_out || bands_out);
|
||||
|
||||
/*
|
||||
* AT+XACT?
|
||||
* +XACT: 4,1,2,1,2,4,5,8,101,102,103,104,105,107,108,111,...
|
||||
*
|
||||
* Note: the first 3 fields corresponde to allowed and preferred modes. Only the
|
||||
* first one of those 3 first fields is mandatory, the other two may be empty.
|
||||
*/
|
||||
r = g_regex_new ("\\+XACT: (\\d+),([^,]*),([^,]*),(.*)(?:\\r\\n)?",
|
||||
G_REGEX_DOLLAR_ENDONLY | G_REGEX_RAW, 0, NULL);
|
||||
g_assert (r != NULL);
|
||||
|
||||
g_regex_match_full (r, response, strlen (response), 0, 0, &match_info, &inner_error);
|
||||
if (!inner_error && g_match_info_matches (match_info)) {
|
||||
if (mode_out) {
|
||||
guint xmm_mode;
|
||||
|
||||
/* Number at index 1 */
|
||||
mm_get_uint_from_match_info (match_info, 1, &xmm_mode);
|
||||
if (xmm_mode >= G_N_ELEMENTS (xmm_modes)) {
|
||||
inner_error = g_error_new (MM_CORE_ERROR, MM_CORE_ERROR_FAILED, "Unsupported XACT AcT value: %u", xmm_mode);
|
||||
goto out;
|
||||
}
|
||||
mode.allowed = xmm_modes[xmm_mode];
|
||||
|
||||
/* Number at index 2 */
|
||||
if (mm_count_bits_set (mode.allowed) > 1 && mm_get_uint_from_match_info (match_info, 2, &xmm_mode)) {
|
||||
if (xmm_mode >= G_N_ELEMENTS (xmm_modes)) {
|
||||
inner_error = g_error_new (MM_CORE_ERROR, MM_CORE_ERROR_FAILED, "Unsupported XACT preferred AcT value: %u", xmm_mode);
|
||||
goto out;
|
||||
}
|
||||
mode.preferred = xmm_modes[xmm_mode];
|
||||
}
|
||||
|
||||
/* Number at index 3: ignored */
|
||||
}
|
||||
|
||||
if (bands_out) {
|
||||
gchar *bandstr;
|
||||
GArray *nums;
|
||||
|
||||
/* Bands start at index 4 */
|
||||
bandstr = mm_get_string_unquoted_from_match_info (match_info, 4);
|
||||
nums = mm_parse_uint_list (bandstr, &inner_error);
|
||||
g_free (bandstr);
|
||||
|
||||
if (inner_error)
|
||||
goto out;
|
||||
if (!nums) {
|
||||
inner_error = g_error_new (MM_CORE_ERROR, MM_CORE_ERROR_FAILED, "Invalid XACT? response");
|
||||
goto out;
|
||||
}
|
||||
|
||||
bands = g_array_sized_new (FALSE, FALSE, sizeof (MMModemBand), nums->len);
|
||||
for (i = 0; i < nums->len; i++) {
|
||||
MMModemBand band;
|
||||
|
||||
band = xact_num_to_band (g_array_index (nums, guint, i));
|
||||
if (band != MM_MODEM_BAND_UNKNOWN)
|
||||
g_array_append_val (bands, band);
|
||||
}
|
||||
g_array_unref (nums);
|
||||
|
||||
if (bands->len == 0) {
|
||||
inner_error = g_error_new (MM_CORE_ERROR, MM_CORE_ERROR_FAILED, "Missing current band list");
|
||||
goto out;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* success */
|
||||
|
||||
out:
|
||||
if (match_info)
|
||||
g_match_info_free (match_info);
|
||||
g_regex_unref (r);
|
||||
|
||||
if (inner_error) {
|
||||
if (bands)
|
||||
g_array_unref (bands);
|
||||
g_propagate_error (error, inner_error);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
if (mode_out) {
|
||||
g_assert (mode.allowed != MM_MODEM_MODE_NONE);
|
||||
mode_out->allowed = mode.allowed;
|
||||
mode_out->preferred = mode.preferred;
|
||||
}
|
||||
|
||||
if (bands_out) {
|
||||
g_assert (bands);
|
||||
*bands_out = bands;
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
@@ -25,4 +25,10 @@ gboolean mm_xmm_parse_xact_test_response (const gchar *response,
|
||||
GArray **bands_out,
|
||||
GError **error);
|
||||
|
||||
/* AT+XACT? response parser */
|
||||
gboolean mm_xmm_parse_xact_query_response (const gchar *response,
|
||||
MMModemModeCombination *mode_out,
|
||||
GArray **bands_out,
|
||||
GError **error);
|
||||
|
||||
#endif /* MM_MODEM_HELPERS_XMM_H */
|
||||
|
@@ -174,6 +174,102 @@ test_xact_test_2g_3g_4g (void)
|
||||
expected_bands, G_N_ELEMENTS (expected_bands));
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
/* Test XACT? responses */
|
||||
|
||||
static void
|
||||
validate_xact_query_response (const gchar *response,
|
||||
const MMModemModeCombination *expected_mode,
|
||||
const MMModemBand *expected_bands,
|
||||
guint n_expected_bands)
|
||||
{
|
||||
GError *error = NULL;
|
||||
GArray *bands = NULL;
|
||||
gboolean ret;
|
||||
guint i;
|
||||
|
||||
MMModemModeCombination mode = {
|
||||
.allowed = MM_MODEM_MODE_NONE,
|
||||
.preferred = MM_MODEM_MODE_NONE,
|
||||
};
|
||||
|
||||
ret = mm_xmm_parse_xact_query_response (response, &mode, &bands, &error);
|
||||
g_assert_no_error (error);
|
||||
g_assert (ret);
|
||||
|
||||
g_assert_cmpuint (mode.allowed, ==, expected_mode->allowed);
|
||||
g_assert_cmpuint (mode.preferred, ==, expected_mode->preferred);
|
||||
|
||||
g_assert_cmpuint (bands->len, ==, n_expected_bands);
|
||||
for (i = 0; i < bands->len; i++) {
|
||||
MMModemBand band;
|
||||
guint j;
|
||||
gboolean found = FALSE;
|
||||
|
||||
band = g_array_index (bands, MMModemBand, i);
|
||||
for (j = 0; !found && j < n_expected_bands; j++)
|
||||
found = (band == expected_bands[j]);
|
||||
g_assert (found);
|
||||
}
|
||||
g_array_unref (bands);
|
||||
}
|
||||
|
||||
static void
|
||||
test_xact_query_3g_only (void)
|
||||
{
|
||||
const gchar *response =
|
||||
"+XACT: "
|
||||
"1,1,,"
|
||||
"1,2,4,5,8,"
|
||||
"101,102,103,104,105,107,108,111,112,113,117,118,119,120,121,126,128,129,130,138,139,140,141,166";
|
||||
|
||||
static const MMModemModeCombination expected_mode = {
|
||||
.allowed = MM_MODEM_MODE_3G,
|
||||
.preferred = MM_MODEM_MODE_NONE
|
||||
};
|
||||
|
||||
static const MMModemBand expected_bands[] = {
|
||||
MM_MODEM_BAND_UTRAN_1, MM_MODEM_BAND_UTRAN_2, MM_MODEM_BAND_UTRAN_4, MM_MODEM_BAND_UTRAN_5, MM_MODEM_BAND_UTRAN_8,
|
||||
MM_MODEM_BAND_EUTRAN_1, MM_MODEM_BAND_EUTRAN_2, MM_MODEM_BAND_EUTRAN_3, MM_MODEM_BAND_EUTRAN_4, MM_MODEM_BAND_EUTRAN_5,
|
||||
MM_MODEM_BAND_EUTRAN_7, MM_MODEM_BAND_EUTRAN_8, MM_MODEM_BAND_EUTRAN_11, MM_MODEM_BAND_EUTRAN_12, MM_MODEM_BAND_EUTRAN_13,
|
||||
MM_MODEM_BAND_EUTRAN_17, MM_MODEM_BAND_EUTRAN_18, MM_MODEM_BAND_EUTRAN_19, MM_MODEM_BAND_EUTRAN_20, MM_MODEM_BAND_EUTRAN_21,
|
||||
MM_MODEM_BAND_EUTRAN_26, MM_MODEM_BAND_EUTRAN_28, MM_MODEM_BAND_EUTRAN_29, MM_MODEM_BAND_EUTRAN_30, MM_MODEM_BAND_EUTRAN_38,
|
||||
MM_MODEM_BAND_EUTRAN_39, MM_MODEM_BAND_EUTRAN_40, MM_MODEM_BAND_EUTRAN_41, MM_MODEM_BAND_EUTRAN_66
|
||||
};
|
||||
|
||||
validate_xact_query_response (response,
|
||||
&expected_mode,
|
||||
expected_bands, G_N_ELEMENTS (expected_bands));
|
||||
}
|
||||
|
||||
static void
|
||||
test_xact_query_3g_4g (void)
|
||||
{
|
||||
const gchar *response =
|
||||
"+XACT: "
|
||||
"4,1,2,"
|
||||
"1,2,4,5,8,"
|
||||
"101,102,103,104,105,107,108,111,112,113,117,118,119,120,121,126,128,129,130,138,139,140,141,166";
|
||||
|
||||
static const MMModemModeCombination expected_mode = {
|
||||
.allowed = MM_MODEM_MODE_3G | MM_MODEM_MODE_4G,
|
||||
.preferred = MM_MODEM_MODE_3G
|
||||
};
|
||||
|
||||
static const MMModemBand expected_bands[] = {
|
||||
MM_MODEM_BAND_UTRAN_1, MM_MODEM_BAND_UTRAN_2, MM_MODEM_BAND_UTRAN_4, MM_MODEM_BAND_UTRAN_5, MM_MODEM_BAND_UTRAN_8,
|
||||
MM_MODEM_BAND_EUTRAN_1, MM_MODEM_BAND_EUTRAN_2, MM_MODEM_BAND_EUTRAN_3, MM_MODEM_BAND_EUTRAN_4, MM_MODEM_BAND_EUTRAN_5,
|
||||
MM_MODEM_BAND_EUTRAN_7, MM_MODEM_BAND_EUTRAN_8, MM_MODEM_BAND_EUTRAN_11, MM_MODEM_BAND_EUTRAN_12, MM_MODEM_BAND_EUTRAN_13,
|
||||
MM_MODEM_BAND_EUTRAN_17, MM_MODEM_BAND_EUTRAN_18, MM_MODEM_BAND_EUTRAN_19, MM_MODEM_BAND_EUTRAN_20, MM_MODEM_BAND_EUTRAN_21,
|
||||
MM_MODEM_BAND_EUTRAN_26, MM_MODEM_BAND_EUTRAN_28, MM_MODEM_BAND_EUTRAN_29, MM_MODEM_BAND_EUTRAN_30, MM_MODEM_BAND_EUTRAN_38,
|
||||
MM_MODEM_BAND_EUTRAN_39, MM_MODEM_BAND_EUTRAN_40, MM_MODEM_BAND_EUTRAN_41, MM_MODEM_BAND_EUTRAN_66
|
||||
};
|
||||
|
||||
validate_xact_query_response (response,
|
||||
&expected_mode,
|
||||
expected_bands, G_N_ELEMENTS (expected_bands));
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
|
||||
void
|
||||
@@ -206,5 +302,8 @@ int main (int argc, char **argv)
|
||||
g_test_add_func ("/MM/xmm/xact/test/3g-4g", test_xact_test_3g_4g);
|
||||
g_test_add_func ("/MM/xmm/xact/test/2g-3g-4g", test_xact_test_2g_3g_4g);
|
||||
|
||||
g_test_add_func ("/MM/xmm/xact/query/3g-only", test_xact_query_3g_only);
|
||||
g_test_add_func ("/MM/xmm/xact/query/3g-4g", test_xact_query_3g_4g);
|
||||
|
||||
return g_test_run ();
|
||||
}
|
||||
|
Reference in New Issue
Block a user