summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAleksander Morgado <aleksander@aleksander.es>2018-08-08 14:05:24 +0200
committerAleksander Morgado <aleksander@aleksander.es>2018-08-10 15:11:46 +0200
commit152c5886f787e81a5f695dad9c1b0f2db06d6802 (patch)
tree6997ee02adbdf5795b3416df62326e1d26412b4b
parent6d04913df0c7314176c722a2f48d395e57a56b49 (diff)
downloadModemManager-152c5886f787e81a5f695dad9c1b0f2db06d6802.tar.gz
xmm: new common XACT? parser for Intel XMM based devices
-rw-r--r--plugins/xmm/mm-modem-helpers-xmm.c120
-rw-r--r--plugins/xmm/mm-modem-helpers-xmm.h6
-rw-r--r--plugins/xmm/tests/test-modem-helpers-xmm.c99
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 ();
}