diff options
author | Aleksander Morgado <aleksander@aleksander.es> | 2018-08-08 14:05:24 +0200 |
---|---|---|
committer | Aleksander Morgado <aleksander@aleksander.es> | 2018-08-10 15:11:46 +0200 |
commit | 152c5886f787e81a5f695dad9c1b0f2db06d6802 (patch) | |
tree | 6997ee02adbdf5795b3416df62326e1d26412b4b | |
parent | 6d04913df0c7314176c722a2f48d395e57a56b49 (diff) | |
download | ModemManager-152c5886f787e81a5f695dad9c1b0f2db06d6802.tar.gz |
xmm: new common XACT? parser for Intel XMM based devices
-rw-r--r-- | plugins/xmm/mm-modem-helpers-xmm.c | 120 | ||||
-rw-r--r-- | plugins/xmm/mm-modem-helpers-xmm.h | 6 | ||||
-rw-r--r-- | plugins/xmm/tests/test-modem-helpers-xmm.c | 99 |
3 files changed, 225 insertions, 0 deletions
diff --git a/plugins/xmm/mm-modem-helpers-xmm.c b/plugins/xmm/mm-modem-helpers-xmm.c index e403cb35c..41e53baaf 100644 --- a/plugins/xmm/mm-modem-helpers-xmm.c +++ b/plugins/xmm/mm-modem-helpers-xmm.c @@ -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; +} diff --git a/plugins/xmm/mm-modem-helpers-xmm.h b/plugins/xmm/mm-modem-helpers-xmm.h index 46cb9b5ed..7c82fa11e 100644 --- a/plugins/xmm/mm-modem-helpers-xmm.h +++ b/plugins/xmm/mm-modem-helpers-xmm.h @@ -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 */ diff --git a/plugins/xmm/tests/test-modem-helpers-xmm.c b/plugins/xmm/tests/test-modem-helpers-xmm.c index c402c23ca..11611dec1 100644 --- a/plugins/xmm/tests/test-modem-helpers-xmm.c +++ b/plugins/xmm/tests/test-modem-helpers-xmm.c @@ -175,6 +175,102 @@ test_xact_test_2g_3g_4g (void) } /*****************************************************************************/ +/* 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 _mm_log (const char *loc, @@ -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 (); } |