diff options
Diffstat (limited to 'plugins')
-rw-r--r-- | plugins/xmm/mm-modem-helpers-xmm.c | 102 | ||||
-rw-r--r-- | plugins/xmm/mm-modem-helpers-xmm.h | 5 | ||||
-rw-r--r-- | plugins/xmm/tests/test-modem-helpers-xmm.c | 239 |
3 files changed, 346 insertions, 0 deletions
diff --git a/plugins/xmm/mm-modem-helpers-xmm.c b/plugins/xmm/mm-modem-helpers-xmm.c index 41e53baaf..0dc48f000 100644 --- a/plugins/xmm/mm-modem-helpers-xmm.c +++ b/plugins/xmm/mm-modem-helpers-xmm.c @@ -141,6 +141,18 @@ xact_num_to_band (guint num) return MM_MODEM_BAND_UNKNOWN; } +static guint +xact_band_to_num (MMModemBand band) +{ + guint i; + + for (i = 0; i < G_N_ELEMENTS (xact_band_config); i++) { + if (band == xact_band_config[i].band) + return xact_band_config[i].num; + } + return 0; +} + /*****************************************************************************/ /* XACT=? response parser */ @@ -458,3 +470,93 @@ out: return TRUE; } + +/*****************************************************************************/ +/* AT+XACT=X command builder */ + +static gboolean +append_rat_value (GString *str, + MMModemMode mode, + GError **error) +{ + guint i; + + for (i = 0; i < G_N_ELEMENTS (xmm_modes); i++) { + if (xmm_modes[i] == mode) { + g_string_append_printf (str, "%u", i); + return TRUE; + } + } + + g_set_error (error, MM_CORE_ERROR, MM_CORE_ERROR_FAILED, + "No AcT value matches requested mode"); + return FALSE; +} + +gchar * +mm_xmm_build_xact_set_command (const MMModemModeCombination *mode, + const GArray *bands, + GError **error) +{ + GString *command; + + /* At least one required */ + g_assert (mode || bands); + + /* Build command */ + command = g_string_new ("+XACT="); + + /* Mode is optional. If not given, we set all fields as empty */ + if (mode) { + /* Allowed mask */ + if (!append_rat_value (command, mode->allowed, error)) { + g_string_free (command, TRUE); + return NULL; + } + + /* Preferred */ + if (mode->preferred != MM_MODEM_MODE_NONE) { + g_string_append (command, ","); + if (!append_rat_value (command, mode->preferred, error)) { + g_string_free (command, TRUE); + return NULL; + } + /* We never set <PreferredAct2> because that is anyway not part of + * ModemManager's API. In modems with triple GSM/UMTS/LTE mode, the + * <PreferredAct2> is always the highest of the remaining ones. E.g. + * if "2G+3G+4G allowed with 2G preferred", the second preferred one + * would be 4G, not 3G. */ + g_string_append (command, ","); + } else + g_string_append (command, ",,"); + } else + g_string_append (command, ",,"); + + if (bands) { + g_string_append (command, ","); + /* Automatic band selection */ + if (bands->len == 1 && g_array_index (bands, MMModemBand, 0) == MM_MODEM_BAND_ANY) + g_string_append (command, "0"); + else { + guint i; + + for (i = 0; i < bands->len; i++) { + MMModemBand band; + guint num; + + band = g_array_index (bands, MMModemBand, i); + num = xact_band_to_num (band); + if (!num) { + g_set_error (error, MM_CORE_ERROR, MM_CORE_ERROR_UNSUPPORTED, + "Band unsupported by this plugin: %s", mm_modem_band_get_string (band)); + g_string_free (command, TRUE); + return NULL; + } + + g_string_append_printf (command, "%s%u", i == 0 ? "" : ",", num); + } + } + } + + return g_string_free (command, FALSE); +} diff --git a/plugins/xmm/mm-modem-helpers-xmm.h b/plugins/xmm/mm-modem-helpers-xmm.h index 7c82fa11e..11c954836 100644 --- a/plugins/xmm/mm-modem-helpers-xmm.h +++ b/plugins/xmm/mm-modem-helpers-xmm.h @@ -31,4 +31,9 @@ gboolean mm_xmm_parse_xact_query_response (const gchar *response, GArray **bands_out, GError **error); +/* AT+XACT=X command builder */ +gchar *mm_xmm_build_xact_set_command (const MMModemModeCombination *mode, + const GArray *bands, + 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 11611dec1..f560401a7 100644 --- a/plugins/xmm/tests/test-modem-helpers-xmm.c +++ b/plugins/xmm/tests/test-modem-helpers-xmm.c @@ -272,6 +272,243 @@ test_xact_query_3g_4g (void) /*****************************************************************************/ +#define XACT_SET_TEST_MAX_BANDS 6 + +typedef struct { + MMModemMode allowed; + MMModemMode preferred; + MMModemBand bands[XACT_SET_TEST_MAX_BANDS]; + const gchar *expected_command; +} XactSetTest; + +static const XactSetTest set_tests[] = { + { + /* 2G-only, no explicit bands */ + .allowed = MM_MODEM_MODE_2G, + .preferred = MM_MODEM_MODE_NONE, + .bands = { [0] = MM_MODEM_BAND_UNKNOWN }, + .expected_command = "+XACT=0,," + }, + { + /* 3G-only, no explicit bands */ + .allowed = MM_MODEM_MODE_3G, + .preferred = MM_MODEM_MODE_NONE, + .bands = { [0] = MM_MODEM_BAND_UNKNOWN }, + .expected_command = "+XACT=1,," + }, + { + /* 4G-only, no explicit bands */ + .allowed = MM_MODEM_MODE_4G, + .preferred = MM_MODEM_MODE_NONE, + .bands = { [0] = MM_MODEM_BAND_UNKNOWN }, + .expected_command = "+XACT=2,," + }, + { + /* 2G+3G, none preferred, no explicit bands */ + .allowed = MM_MODEM_MODE_2G | MM_MODEM_MODE_3G, + .preferred = MM_MODEM_MODE_NONE, + .bands = { [0] = MM_MODEM_BAND_UNKNOWN }, + .expected_command = "+XACT=3,," + }, + { + /* 2G+3G, 2G preferred, no explicit bands */ + .allowed = MM_MODEM_MODE_2G | MM_MODEM_MODE_3G, + .preferred = MM_MODEM_MODE_2G, + .bands = { [0] = MM_MODEM_BAND_UNKNOWN }, + .expected_command = "+XACT=3,0," + }, + { + /* 2G+3G, 3G preferred, no explicit bands */ + .allowed = MM_MODEM_MODE_2G | MM_MODEM_MODE_3G, + .preferred = MM_MODEM_MODE_3G, + .bands = { [0] = MM_MODEM_BAND_UNKNOWN }, + .expected_command = "+XACT=3,1," + }, + { + /* 3G+4G, none preferred, no explicit bands */ + .allowed = MM_MODEM_MODE_3G | MM_MODEM_MODE_4G, + .preferred = MM_MODEM_MODE_NONE, + .bands = { [0] = MM_MODEM_BAND_UNKNOWN }, + .expected_command = "+XACT=4,," + }, + { + /* 3G+4G, 3G preferred, no explicit bands */ + .allowed = MM_MODEM_MODE_3G | MM_MODEM_MODE_4G, + .preferred = MM_MODEM_MODE_3G, + .bands = { [0] = MM_MODEM_BAND_UNKNOWN }, + .expected_command = "+XACT=4,1," + }, + { + /* 3G+4G, 4G preferred, no explicit bands */ + .allowed = MM_MODEM_MODE_3G | MM_MODEM_MODE_4G, + .preferred = MM_MODEM_MODE_4G, + .bands = { [0] = MM_MODEM_BAND_UNKNOWN }, + .expected_command = "+XACT=4,2," + }, + { + /* 2G+4G, none preferred, no explicit bands */ + .allowed = MM_MODEM_MODE_2G | MM_MODEM_MODE_4G, + .preferred = MM_MODEM_MODE_NONE, + .bands = { [0] = MM_MODEM_BAND_UNKNOWN }, + .expected_command = "+XACT=5,," + }, + { + /* 2G+4G, 2G preferred, no explicit bands */ + .allowed = MM_MODEM_MODE_2G | MM_MODEM_MODE_4G, + .preferred = MM_MODEM_MODE_2G, + .bands = { [0] = MM_MODEM_BAND_UNKNOWN }, + .expected_command = "+XACT=5,0," + }, + { + /* 2G+4G, 4G preferred, no explicit bands */ + .allowed = MM_MODEM_MODE_2G | MM_MODEM_MODE_4G, + .preferred = MM_MODEM_MODE_4G, + .bands = { [0] = MM_MODEM_BAND_UNKNOWN }, + .expected_command = "+XACT=5,2," + }, + { + /* 2G+3G+4G, none preferred, no explicit bands */ + .allowed = MM_MODEM_MODE_2G | MM_MODEM_MODE_3G | MM_MODEM_MODE_4G, + .preferred = MM_MODEM_MODE_NONE, + .bands = { [0] = MM_MODEM_BAND_UNKNOWN }, + .expected_command = "+XACT=6,," + }, + { + /* 2G+3G+4G, 2G preferred, no explicit bands */ + .allowed = MM_MODEM_MODE_2G | MM_MODEM_MODE_3G | MM_MODEM_MODE_4G, + .preferred = MM_MODEM_MODE_2G, + .bands = { [0] = MM_MODEM_BAND_UNKNOWN }, + .expected_command = "+XACT=6,0," + }, + { + /* 2G+3G+4G, 3G preferred, no explicit bands */ + .allowed = MM_MODEM_MODE_2G | MM_MODEM_MODE_3G | MM_MODEM_MODE_4G, + .preferred = MM_MODEM_MODE_3G, + .bands = { [0] = MM_MODEM_BAND_UNKNOWN }, + .expected_command = "+XACT=6,1," + }, + { + /* 2G+3G+4G, 4G preferred, no explicit bands */ + .allowed = MM_MODEM_MODE_2G | MM_MODEM_MODE_3G | MM_MODEM_MODE_4G, + .preferred = MM_MODEM_MODE_4G, + .bands = { [0] = MM_MODEM_BAND_UNKNOWN }, + .expected_command = "+XACT=6,2," + }, + { + /* 2G bands, no explicit modes */ + .allowed = MM_MODEM_MODE_NONE, + .preferred = MM_MODEM_MODE_NONE, + .bands = { [0] = MM_MODEM_BAND_EGSM, + [1] = MM_MODEM_BAND_DCS, + [2] = MM_MODEM_BAND_UNKNOWN }, + .expected_command = "+XACT=,,,900,1800" + }, + { + /* 3G bands, no explicit modes */ + .allowed = MM_MODEM_MODE_NONE, + .preferred = MM_MODEM_MODE_NONE, + .bands = { [0] = MM_MODEM_BAND_UTRAN_1, + [1] = MM_MODEM_BAND_UTRAN_2, + [2] = MM_MODEM_BAND_UNKNOWN }, + .expected_command = "+XACT=,,,1,2" + }, + { + /* 4G bands, no explicit modes */ + .allowed = MM_MODEM_MODE_NONE, + .preferred = MM_MODEM_MODE_NONE, + .bands = { [0] = MM_MODEM_BAND_EUTRAN_1, + [1] = MM_MODEM_BAND_EUTRAN_2, + [2] = MM_MODEM_BAND_UNKNOWN }, + .expected_command = "+XACT=,,,101,102" + }, + { + /* 2G, 3G and 4G bands, no explicit modes */ + .allowed = MM_MODEM_MODE_NONE, + .preferred = MM_MODEM_MODE_NONE, + .bands = { [0] = MM_MODEM_BAND_EGSM, + [1] = MM_MODEM_BAND_DCS, + [2] = MM_MODEM_BAND_UTRAN_1, + [3] = MM_MODEM_BAND_UTRAN_2, + [4] = MM_MODEM_BAND_EUTRAN_1, + [5] = MM_MODEM_BAND_EUTRAN_2 }, + .expected_command = "+XACT=,,,900,1800,1,2,101,102" + }, + { + /* Auto bands, no explicit modes */ + .allowed = MM_MODEM_MODE_NONE, + .preferred = MM_MODEM_MODE_NONE, + .bands = { [0] = MM_MODEM_BAND_ANY, + [1] = MM_MODEM_BAND_UNKNOWN }, + .expected_command = "+XACT=,,,0" + }, + + { + /* 2G+3G+4G with 4G preferred, and 2G+3G+4G bands */ + .allowed = MM_MODEM_MODE_2G | MM_MODEM_MODE_3G | MM_MODEM_MODE_4G, + .preferred = MM_MODEM_MODE_4G, + .bands = { [0] = MM_MODEM_BAND_EGSM, + [1] = MM_MODEM_BAND_DCS, + [2] = MM_MODEM_BAND_UTRAN_1, + [3] = MM_MODEM_BAND_UTRAN_2, + [4] = MM_MODEM_BAND_EUTRAN_1, + [5] = MM_MODEM_BAND_EUTRAN_2 }, + .expected_command = "+XACT=6,2,,900,1800,1,2,101,102" + }, +}; + +static void +validate_xact_set_command (const MMModemMode allowed, + const MMModemMode preferred, + const MMModemBand *bands, + guint n_bands, + const gchar *expected_command) +{ + gchar *command; + MMModemModeCombination mode; + GArray *bandsarray = NULL; + GError *error = NULL; + + if (n_bands) + bandsarray = g_array_append_vals (g_array_sized_new (FALSE, FALSE, sizeof (MMModemBand), n_bands), bands, n_bands); + + mode.allowed = allowed; + mode.preferred = preferred; + + command = mm_xmm_build_xact_set_command ((mode.allowed != MM_MODEM_MODE_NONE) ? &mode : NULL, bandsarray, &error); + g_assert_no_error (error); + g_assert (command); + + g_assert_cmpstr (command, == , expected_command); + + g_free (command); + if (bandsarray) + g_array_unref (bandsarray); +} + +static void +test_xact_set (void) +{ + guint i; + + for (i = 0; i < G_N_ELEMENTS (set_tests); i++) { + guint n_bands = 0; + guint j; + + for (j = 0; j < XACT_SET_TEST_MAX_BANDS; j++) { + if (set_tests[i].bands[j] != MM_MODEM_BAND_UNKNOWN) + n_bands++; + } + + validate_xact_set_command (set_tests[i].allowed, + set_tests[i].preferred, + set_tests[i].bands, + n_bands, + set_tests[i].expected_command); + } +} + +/*****************************************************************************/ + void _mm_log (const char *loc, const char *func, @@ -305,5 +542,7 @@ int main (int argc, char **argv) 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); + g_test_add_func ("/MM/xmm/xact/set", test_xact_set); + return g_test_run (); } |