plugins,telit: refactor #BND command support

And added support for several new things, including:
 * Setting "any" band now attempts to set all supported bands.
 * Added new 2G band value '5' (egsm+dcs+pcs+g850).
 * Setup support for two different 3G band combinations, a default one
   plus an alternate one applicable to the LM940/960 models only. The
   alternate combination is selected via udev tags.

During the refactor, the following Telit-specific helpers were also
removed and exchanged with more generic counterparts.
 * mm_telit_bands_contains() -> mm_common_bands_garray_lookup()
 * mm_telit_get_band_flags_from_string() -> mm_parse_uint_list()
This commit is contained in:
Aleksander Morgado
2019-09-17 10:52:42 +02:00
parent 40521e315f
commit be4fa661c1
11 changed files with 1109 additions and 930 deletions
+14
View File
@@ -722,6 +722,20 @@ mm_common_bands_garray_cmp (GArray *a, GArray *b)
return !different;
}
gboolean
mm_common_bands_garray_lookup (GArray *array,
MMModemBand value)
{
guint i;
for (i = 0; i < array->len; i++) {
if (value == g_array_index (array, MMModemBand, i))
return TRUE;
}
return FALSE;
}
void
mm_common_bands_garray_sort (GArray *array)
{
+3 -2
View File
@@ -103,8 +103,9 @@ GVariant *mm_common_bands_garray_to_variant (GArray *array);
GVariant *mm_common_build_bands_any (void);
GVariant *mm_common_build_bands_unknown (void);
gboolean mm_common_bands_garray_cmp (GArray *a, GArray *b);
void mm_common_bands_garray_sort (GArray *array);
gboolean mm_common_bands_garray_cmp (GArray *a, GArray *b);
void mm_common_bands_garray_sort (GArray *array);
gboolean mm_common_bands_garray_lookup (GArray *array, MMModemBand value);
gboolean mm_common_band_is_gsm (MMModemBand band);
gboolean mm_common_band_is_utran (MMModemBand band);
+5 -1
View File
@@ -901,8 +901,12 @@ noinst_PROGRAMS += test-modem-helpers-telit
test_modem_helpers_telit_SOURCES = \
telit/tests/test-mm-modem-helpers-telit.c \
$(NULL)
test_modem_helpers_telit_CPPFLAGS = $(PLUGIN_TELIT_COMPILER_FLAGS)
test_modem_helpers_telit_CPPFLAGS = \
$(PLUGIN_TELIT_COMPILER_FLAGS) \
$(TEST_COMMON_COMPILER_FLAGS) \
$(NULL)
test_modem_helpers_telit_LDADD = \
$(TEST_COMMON_LIBADD_FLAGS) \
$(builddir)/libhelpers-telit.la \
$(top_builddir)/src/libhelpers.la \
$(top_builddir)/libmm-glib/libmm-glib.la \
@@ -45,4 +45,10 @@ ATTRS{idVendor}=="1bc7", ATTRS{idProduct}=="1101", ENV{.MM_USBIFNUM}=="00", ENV{
ATTRS{idVendor}=="1bc7", ATTRS{idProduct}=="1101", ENV{.MM_USBIFNUM}=="01", ENV{ID_MM_PORT_TYPE_AT_PRIMARY}="1"
ATTRS{idVendor}=="1bc7", ATTRS{idProduct}=="1101", ENV{.MM_USBIFNUM}=="02", ENV{ID_MM_PORT_TYPE_AT_SECONDARY}="1"
# LM940/960 use alternate settings for 3G band management
ATTRS{idVendor}=="1bc7", ATTRS{idProduct}=="0x1040", ENV{ID_MM_TELIT_BND_ALTERNATE}="1"
ATTRS{idVendor}=="1bc7", ATTRS{idProduct}=="0x1041", ENV{ID_MM_TELIT_BND_ALTERNATE}="1"
ATTRS{idVendor}=="1bc7", ATTRS{idProduct}=="0x1042", ENV{ID_MM_TELIT_BND_ALTERNATE}="1"
ATTRS{idVendor}=="1bc7", ATTRS{idProduct}=="0x1043", ENV{ID_MM_TELIT_BND_ALTERNATE}="1"
LABEL="mm_telit_port_types_end"
@@ -159,9 +159,9 @@ iface_modem_init (MMIfaceModem *iface)
iface->set_current_bands = mm_shared_telit_modem_set_current_bands;
iface->set_current_bands_finish = mm_shared_telit_modem_set_current_bands_finish;
iface->load_current_bands = mm_shared_telit_modem_load_current_bands;
iface->load_current_bands_finish = mm_shared_telit_modem_load_bands_finish;
iface->load_current_bands_finish = mm_shared_telit_modem_load_current_bands_finish;
iface->load_supported_bands = mm_shared_telit_modem_load_supported_bands;
iface->load_supported_bands_finish = mm_shared_telit_modem_load_bands_finish;
iface->load_supported_bands_finish = mm_shared_telit_modem_load_supported_bands_finish;
iface->load_supported_modes = load_supported_modes;
iface->load_supported_modes_finish = load_supported_modes_finish;
iface->load_current_modes = mm_shared_telit_load_current_modes;
+2 -2
View File
@@ -1031,9 +1031,9 @@ iface_modem_init (MMIfaceModem *iface)
iface->set_current_bands = mm_shared_telit_modem_set_current_bands;
iface->set_current_bands_finish = mm_shared_telit_modem_set_current_bands_finish;
iface->load_current_bands = mm_shared_telit_modem_load_current_bands;
iface->load_current_bands_finish = mm_shared_telit_modem_load_bands_finish;
iface->load_current_bands_finish = mm_shared_telit_modem_load_current_bands_finish;
iface->load_supported_bands = mm_shared_telit_modem_load_supported_bands;
iface->load_supported_bands_finish = mm_shared_telit_modem_load_bands_finish;
iface->load_supported_bands_finish = mm_shared_telit_modem_load_supported_bands_finish;
iface->load_unlock_retries_finish = modem_load_unlock_retries_finish;
iface->load_unlock_retries = modem_load_unlock_retries;
iface->reset = modem_reset;
+496 -390
View File
@@ -10,8 +10,8 @@
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details:
*
* Copyright (C) 2015 Telit.
*
* Copyright (C) 2015-2019 Telit.
* Copyright (C) 2019 Aleksander Morgado <aleksander@aleksander.es>
*/
#include <stdlib.h>
@@ -27,115 +27,299 @@
#include "mm-modem-helpers.h"
#include "mm-modem-helpers-telit.h"
/*****************************************************************************/
/* AT#BND 2G values */
#define MM_MODEM_BAND_TELIT_2G_FIRST MM_MODEM_BAND_EGSM
#define MM_MODEM_BAND_TELIT_2G_LAST MM_MODEM_BAND_G850
#define B2G_FLAG(band) (1 << (band - MM_MODEM_BAND_TELIT_2G_FIRST))
/* Index of the array is the telit 2G band value [0-5]
* The bitmask value here is built from the 2G MMModemBand values right away. */
static const guint32 telit_2g_to_mm_band_mask[] = {
[0] = B2G_FLAG (MM_MODEM_BAND_EGSM) + B2G_FLAG (MM_MODEM_BAND_DCS),
[1] = B2G_FLAG (MM_MODEM_BAND_EGSM) + B2G_FLAG (MM_MODEM_BAND_PCS),
[2] = B2G_FLAG (MM_MODEM_BAND_DCS) + B2G_FLAG (MM_MODEM_BAND_G850),
[3] = B2G_FLAG (MM_MODEM_BAND_PCS) + B2G_FLAG (MM_MODEM_BAND_G850),
[4] = B2G_FLAG (MM_MODEM_BAND_EGSM) + B2G_FLAG (MM_MODEM_BAND_DCS) + B2G_FLAG (MM_MODEM_BAND_PCS),
[5] = B2G_FLAG (MM_MODEM_BAND_EGSM) + B2G_FLAG (MM_MODEM_BAND_DCS) + B2G_FLAG (MM_MODEM_BAND_PCS) + B2G_FLAG (MM_MODEM_BAND_G850),
};
/*****************************************************************************/
/* AT#BND 3G values */
/* NOTE: UTRAN_1 to UTRAN_9 enum values are NOT IN ORDER!
* E.g. numerically UTRAN_7 is after UTRAN_9...
*
* This array allows us to iterate them in a way which is a bit
* more friendly.
*/
static const guint band_utran_index[] = {
[MM_MODEM_BAND_UTRAN_1] = 1,
[MM_MODEM_BAND_UTRAN_2] = 2,
[MM_MODEM_BAND_UTRAN_3] = 3,
[MM_MODEM_BAND_UTRAN_4] = 4,
[MM_MODEM_BAND_UTRAN_5] = 5,
[MM_MODEM_BAND_UTRAN_6] = 6,
[MM_MODEM_BAND_UTRAN_7] = 7,
[MM_MODEM_BAND_UTRAN_8] = 8,
[MM_MODEM_BAND_UTRAN_9] = 9,
[MM_MODEM_BAND_UTRAN_10] = 10,
[MM_MODEM_BAND_UTRAN_11] = 11,
[MM_MODEM_BAND_UTRAN_12] = 12,
[MM_MODEM_BAND_UTRAN_13] = 13,
[MM_MODEM_BAND_UTRAN_14] = 14,
[MM_MODEM_BAND_UTRAN_19] = 19,
[MM_MODEM_BAND_UTRAN_20] = 20,
[MM_MODEM_BAND_UTRAN_21] = 21,
[MM_MODEM_BAND_UTRAN_22] = 22,
[MM_MODEM_BAND_UTRAN_25] = 25,
[MM_MODEM_BAND_UTRAN_26] = 26,
[MM_MODEM_BAND_UTRAN_32] = 32,
};
#define MM_MODEM_BAND_TELIT_3G_FIRST MM_MODEM_BAND_UTRAN_1
#define MM_MODEM_BAND_TELIT_3G_LAST MM_MODEM_BAND_UTRAN_19
#define B3G_NUM(band) band_utran_index[band]
#define B3G_FLAG(band) ((B3G_NUM (band) > 0) ? (1 << (B3G_NUM (band) - B3G_NUM (MM_MODEM_BAND_TELIT_3G_FIRST))) : 0)
/* Index of the arrays is the telit 3G band value.
* The bitmask value here is built from the 3G MMModemBand values right away.
*
* We have 2 different sets of bands that are different for values >=12, because
* the LM940/960 models support a different set of 3G bands.
*/
#define TELIT_3G_TO_MM_BAND_MASK_DEFAULT_N_ELEMENTS 27
static guint32 telit_3g_to_mm_band_mask_default[TELIT_3G_TO_MM_BAND_MASK_DEFAULT_N_ELEMENTS];
#define TELIT_3G_TO_MM_BAND_MASK_ALTERNATE_N_ELEMENTS 20
static guint32 telit_3g_to_mm_band_mask_alternate[TELIT_3G_TO_MM_BAND_MASK_ALTERNATE_N_ELEMENTS];
static void
initialize_telit_3g_to_mm_band_masks (void)
{
static gboolean initialized = FALSE;
/* We need to initialize the arrays in runtime because gcc < 8 doesn't like initializing
* with operations that are using the band_utran_index constant array elements */
if (initialized)
return;
telit_3g_to_mm_band_mask_default[0] = B3G_FLAG (MM_MODEM_BAND_UTRAN_1);
telit_3g_to_mm_band_mask_default[1] = B3G_FLAG (MM_MODEM_BAND_UTRAN_2);
telit_3g_to_mm_band_mask_default[2] = B3G_FLAG (MM_MODEM_BAND_UTRAN_5);
telit_3g_to_mm_band_mask_default[3] = B3G_FLAG (MM_MODEM_BAND_UTRAN_1) + B3G_FLAG (MM_MODEM_BAND_UTRAN_2) + B3G_FLAG (MM_MODEM_BAND_UTRAN_5);
telit_3g_to_mm_band_mask_default[4] = B3G_FLAG (MM_MODEM_BAND_UTRAN_2) + B3G_FLAG (MM_MODEM_BAND_UTRAN_5);
telit_3g_to_mm_band_mask_default[5] = B3G_FLAG (MM_MODEM_BAND_UTRAN_8);
telit_3g_to_mm_band_mask_default[6] = B3G_FLAG (MM_MODEM_BAND_UTRAN_1) + B3G_FLAG (MM_MODEM_BAND_UTRAN_8);
telit_3g_to_mm_band_mask_default[7] = B3G_FLAG (MM_MODEM_BAND_UTRAN_4);
telit_3g_to_mm_band_mask_default[8] = B3G_FLAG (MM_MODEM_BAND_UTRAN_1) + B3G_FLAG (MM_MODEM_BAND_UTRAN_5);
telit_3g_to_mm_band_mask_default[9] = B3G_FLAG (MM_MODEM_BAND_UTRAN_1) + B3G_FLAG (MM_MODEM_BAND_UTRAN_8) + B3G_FLAG (MM_MODEM_BAND_UTRAN_5);
telit_3g_to_mm_band_mask_default[10] = B3G_FLAG (MM_MODEM_BAND_UTRAN_2) + B3G_FLAG (MM_MODEM_BAND_UTRAN_4) + B3G_FLAG (MM_MODEM_BAND_UTRAN_5);
telit_3g_to_mm_band_mask_default[11] = B3G_FLAG (MM_MODEM_BAND_UTRAN_1) + B3G_FLAG (MM_MODEM_BAND_UTRAN_2) + B3G_FLAG (MM_MODEM_BAND_UTRAN_4) +
B3G_FLAG (MM_MODEM_BAND_UTRAN_5) + B3G_FLAG (MM_MODEM_BAND_UTRAN_8);
telit_3g_to_mm_band_mask_default[12] = B3G_FLAG (MM_MODEM_BAND_UTRAN_6);
telit_3g_to_mm_band_mask_default[13] = B3G_FLAG (MM_MODEM_BAND_UTRAN_3);
telit_3g_to_mm_band_mask_default[14] = B3G_FLAG (MM_MODEM_BAND_UTRAN_1) + B3G_FLAG (MM_MODEM_BAND_UTRAN_2) + B3G_FLAG (MM_MODEM_BAND_UTRAN_4) +
B3G_FLAG (MM_MODEM_BAND_UTRAN_5) + B3G_FLAG (MM_MODEM_BAND_UTRAN_6);
telit_3g_to_mm_band_mask_default[15] = B3G_FLAG (MM_MODEM_BAND_UTRAN_1) + B3G_FLAG (MM_MODEM_BAND_UTRAN_3) + B3G_FLAG (MM_MODEM_BAND_UTRAN_8);
telit_3g_to_mm_band_mask_default[16] = B3G_FLAG (MM_MODEM_BAND_UTRAN_5) + B3G_FLAG (MM_MODEM_BAND_UTRAN_8);
telit_3g_to_mm_band_mask_default[17] = B3G_FLAG (MM_MODEM_BAND_UTRAN_2) + B3G_FLAG (MM_MODEM_BAND_UTRAN_4) + B3G_FLAG (MM_MODEM_BAND_UTRAN_5) +
B3G_FLAG (MM_MODEM_BAND_UTRAN_6);
telit_3g_to_mm_band_mask_default[18] = B3G_FLAG (MM_MODEM_BAND_UTRAN_1) + B3G_FLAG (MM_MODEM_BAND_UTRAN_5) + B3G_FLAG (MM_MODEM_BAND_UTRAN_6) +
B3G_FLAG (MM_MODEM_BAND_UTRAN_8);
telit_3g_to_mm_band_mask_default[19] = B3G_FLAG (MM_MODEM_BAND_UTRAN_2) + B3G_FLAG (MM_MODEM_BAND_UTRAN_6);
telit_3g_to_mm_band_mask_default[20] = B3G_FLAG (MM_MODEM_BAND_UTRAN_5) + B3G_FLAG (MM_MODEM_BAND_UTRAN_6);
telit_3g_to_mm_band_mask_default[21] = B3G_FLAG (MM_MODEM_BAND_UTRAN_2) + B3G_FLAG (MM_MODEM_BAND_UTRAN_5) + B3G_FLAG (MM_MODEM_BAND_UTRAN_6);
telit_3g_to_mm_band_mask_default[22] = B3G_FLAG (MM_MODEM_BAND_UTRAN_1) + B3G_FLAG (MM_MODEM_BAND_UTRAN_3) + B3G_FLAG (MM_MODEM_BAND_UTRAN_5) +
B3G_FLAG (MM_MODEM_BAND_UTRAN_8);
telit_3g_to_mm_band_mask_default[23] = B3G_FLAG (MM_MODEM_BAND_UTRAN_1) + B3G_FLAG (MM_MODEM_BAND_UTRAN_3);
telit_3g_to_mm_band_mask_default[24] = B3G_FLAG (MM_MODEM_BAND_UTRAN_1) + B3G_FLAG (MM_MODEM_BAND_UTRAN_2) + B3G_FLAG (MM_MODEM_BAND_UTRAN_4) +
B3G_FLAG (MM_MODEM_BAND_UTRAN_5);
telit_3g_to_mm_band_mask_default[25] = B3G_FLAG (MM_MODEM_BAND_UTRAN_19);
telit_3g_to_mm_band_mask_default[26] = B3G_FLAG (MM_MODEM_BAND_UTRAN_1) + B3G_FLAG (MM_MODEM_BAND_UTRAN_5) + B3G_FLAG (MM_MODEM_BAND_UTRAN_6) +
B3G_FLAG (MM_MODEM_BAND_UTRAN_8) + B3G_FLAG (MM_MODEM_BAND_UTRAN_19);
/* Initialize alternate 3G band set */
telit_3g_to_mm_band_mask_alternate[0] = B3G_FLAG (MM_MODEM_BAND_UTRAN_1);
telit_3g_to_mm_band_mask_alternate[1] = B3G_FLAG (MM_MODEM_BAND_UTRAN_2);
telit_3g_to_mm_band_mask_alternate[2] = B3G_FLAG (MM_MODEM_BAND_UTRAN_5);
telit_3g_to_mm_band_mask_alternate[3] = B3G_FLAG (MM_MODEM_BAND_UTRAN_1) + B3G_FLAG (MM_MODEM_BAND_UTRAN_2) + B3G_FLAG (MM_MODEM_BAND_UTRAN_5);
telit_3g_to_mm_band_mask_alternate[4] = B3G_FLAG (MM_MODEM_BAND_UTRAN_2) + B3G_FLAG (MM_MODEM_BAND_UTRAN_5);
telit_3g_to_mm_band_mask_alternate[5] = B3G_FLAG (MM_MODEM_BAND_UTRAN_8);
telit_3g_to_mm_band_mask_alternate[6] = B3G_FLAG (MM_MODEM_BAND_UTRAN_1) + B3G_FLAG (MM_MODEM_BAND_UTRAN_8);
telit_3g_to_mm_band_mask_alternate[7] = B3G_FLAG (MM_MODEM_BAND_UTRAN_4);
telit_3g_to_mm_band_mask_alternate[8] = B3G_FLAG (MM_MODEM_BAND_UTRAN_1) + B3G_FLAG (MM_MODEM_BAND_UTRAN_5);
telit_3g_to_mm_band_mask_alternate[9] = B3G_FLAG (MM_MODEM_BAND_UTRAN_1) + B3G_FLAG (MM_MODEM_BAND_UTRAN_8) + B3G_FLAG (MM_MODEM_BAND_UTRAN_5);
telit_3g_to_mm_band_mask_alternate[10] = B3G_FLAG (MM_MODEM_BAND_UTRAN_2) + B3G_FLAG (MM_MODEM_BAND_UTRAN_4) + B3G_FLAG (MM_MODEM_BAND_UTRAN_5);
telit_3g_to_mm_band_mask_alternate[11] = B3G_FLAG (MM_MODEM_BAND_UTRAN_1) + B3G_FLAG (MM_MODEM_BAND_UTRAN_2) + B3G_FLAG (MM_MODEM_BAND_UTRAN_4) +
B3G_FLAG (MM_MODEM_BAND_UTRAN_5) + B3G_FLAG (MM_MODEM_BAND_UTRAN_8);
telit_3g_to_mm_band_mask_alternate[12] = B3G_FLAG (MM_MODEM_BAND_UTRAN_1) + B3G_FLAG (MM_MODEM_BAND_UTRAN_3) + B3G_FLAG (MM_MODEM_BAND_UTRAN_5) +
B3G_FLAG (MM_MODEM_BAND_UTRAN_8);
telit_3g_to_mm_band_mask_alternate[13] = B3G_FLAG (MM_MODEM_BAND_UTRAN_3);
telit_3g_to_mm_band_mask_alternate[14] = B3G_FLAG (MM_MODEM_BAND_UTRAN_1) + B3G_FLAG (MM_MODEM_BAND_UTRAN_3) + B3G_FLAG (MM_MODEM_BAND_UTRAN_5);
telit_3g_to_mm_band_mask_alternate[15] = B3G_FLAG (MM_MODEM_BAND_UTRAN_3) + B3G_FLAG (MM_MODEM_BAND_UTRAN_5);
telit_3g_to_mm_band_mask_alternate[16] = B3G_FLAG (MM_MODEM_BAND_UTRAN_1) + B3G_FLAG (MM_MODEM_BAND_UTRAN_2) + B3G_FLAG (MM_MODEM_BAND_UTRAN_3) +
B3G_FLAG (MM_MODEM_BAND_UTRAN_4) + B3G_FLAG (MM_MODEM_BAND_UTRAN_5) + B3G_FLAG (MM_MODEM_BAND_UTRAN_8);
telit_3g_to_mm_band_mask_alternate[17] = B3G_FLAG (MM_MODEM_BAND_UTRAN_1) + B3G_FLAG (MM_MODEM_BAND_UTRAN_2) + B3G_FLAG (MM_MODEM_BAND_UTRAN_8);
telit_3g_to_mm_band_mask_alternate[18] = B3G_FLAG (MM_MODEM_BAND_UTRAN_1) + B3G_FLAG (MM_MODEM_BAND_UTRAN_2) + B3G_FLAG (MM_MODEM_BAND_UTRAN_4) +
B3G_FLAG (MM_MODEM_BAND_UTRAN_5) + B3G_FLAG (MM_MODEM_BAND_UTRAN_8) + B3G_FLAG (MM_MODEM_BAND_UTRAN_9) +
B3G_FLAG (MM_MODEM_BAND_UTRAN_19);
telit_3g_to_mm_band_mask_alternate[19] = B3G_FLAG (MM_MODEM_BAND_UTRAN_1) + B3G_FLAG (MM_MODEM_BAND_UTRAN_2) + B3G_FLAG (MM_MODEM_BAND_UTRAN_4) +
B3G_FLAG (MM_MODEM_BAND_UTRAN_5) + B3G_FLAG (MM_MODEM_BAND_UTRAN_6) + B3G_FLAG (MM_MODEM_BAND_UTRAN_8) +
B3G_FLAG (MM_MODEM_BAND_UTRAN_9) + B3G_FLAG (MM_MODEM_BAND_UTRAN_19);
}
/*****************************************************************************/
/* AT#BND 4G values
*
* The Telit-specific value for 4G bands is a bitmask of the band values, given
* in hexadecimal or decimal format.
*/
#define MM_MODEM_BAND_TELIT_4G_FIRST MM_MODEM_BAND_EUTRAN_1
#define MM_MODEM_BAND_TELIT_4G_LAST MM_MODEM_BAND_EUTRAN_44
#define B4G_FLAG(band) (((guint64) 1) << (band - MM_MODEM_BAND_TELIT_4G_FIRST))
/*****************************************************************************/
/* Set current bands helpers */
void
mm_telit_get_band_flag (GArray *bands_array,
gint *flag2g,
gint *flag3g,
gint *flag4g)
gchar *
mm_telit_build_bnd_request (GArray *bands_array,
gboolean modem_is_2g,
gboolean modem_is_3g,
gboolean modem_is_4g,
gboolean modem_alternate_3g_bands,
GError **error)
{
guint mask2g = 0;
guint mask3g = 0;
guint mask4g = 0;
guint found4g = FALSE;
guint i;
guint32 mask2g = 0;
guint32 mask3g = 0;
guint64 mask4g = 0;
guint i;
gint flag2g = -1;
gint flag3g = -1;
gint flag4g = -1;
gchar *cmd;
const guint32 *telit_3g_to_mm_band_mask;
guint telit_3g_to_mm_band_mask_n_elements;
initialize_telit_3g_to_mm_band_masks ();
/* Select correct 3G band mask */
if (modem_alternate_3g_bands) {
telit_3g_to_mm_band_mask = telit_3g_to_mm_band_mask_alternate;
telit_3g_to_mm_band_mask_n_elements = G_N_ELEMENTS (telit_3g_to_mm_band_mask_alternate);
} else {
telit_3g_to_mm_band_mask = telit_3g_to_mm_band_mask_default;
telit_3g_to_mm_band_mask_n_elements = G_N_ELEMENTS (telit_3g_to_mm_band_mask_default);
}
for (i = 0; i < bands_array->len; i++) {
MMModemBand band = g_array_index (bands_array, MMModemBand, i);
MMModemBand band;
if (flag2g != NULL) {
switch (band) {
case MM_MODEM_BAND_EGSM:
case MM_MODEM_BAND_DCS:
case MM_MODEM_BAND_PCS:
case MM_MODEM_BAND_G850:
mask2g += 1 << band;
break;
default:
break;
band = g_array_index (bands_array, MMModemBand, i);
/* Convert 2G bands into a bitmask, to match against telit_2g_to_mm_band_mask. */
if (flag2g && mm_common_band_is_gsm (band) &&
(band >= MM_MODEM_BAND_TELIT_2G_FIRST) && (band <= MM_MODEM_BAND_TELIT_2G_LAST))
mask2g += B2G_FLAG (band);
/* Convert 3G bands into a bitmask, to match against telit_3g_to_mm_band_mask. */
if (flag3g && mm_common_band_is_utran (band) &&
(B3G_NUM (band) >= B3G_NUM (MM_MODEM_BAND_TELIT_3G_FIRST)) && (B3G_NUM (band) <= B3G_NUM (MM_MODEM_BAND_TELIT_3G_LAST)))
mask3g += B3G_FLAG (band);
/* Convert 4G bands into a bitmask. We use a 64bit explicit bitmask so that
* all values fit correctly. */
if (flag4g && mm_common_band_is_eutran (band) &&
(band >= MM_MODEM_BAND_TELIT_4G_FIRST && band <= MM_MODEM_BAND_TELIT_4G_LAST))
mask4g += B4G_FLAG (band);
}
/* Get 2G-specific telit value */
if (mask2g) {
for (i = 0; i < G_N_ELEMENTS (telit_2g_to_mm_band_mask); i++) {
if (mask2g == telit_2g_to_mm_band_mask[i]) {
flag2g = i;
break;
}
}
if (flag2g == -1) {
gchar *bands_str;
if (flag3g != NULL) {
switch (band) {
case MM_MODEM_BAND_UTRAN_1:
case MM_MODEM_BAND_UTRAN_2:
case MM_MODEM_BAND_UTRAN_3:
case MM_MODEM_BAND_UTRAN_4:
case MM_MODEM_BAND_UTRAN_5:
case MM_MODEM_BAND_UTRAN_6:
case MM_MODEM_BAND_UTRAN_7:
case MM_MODEM_BAND_UTRAN_8:
case MM_MODEM_BAND_UTRAN_9:
mask3g += 1 << band;
break;
default:
break;
bands_str = mm_common_build_bands_string ((const MMModemBand *)(bands_array->data), bands_array->len);
g_set_error (error, MM_CORE_ERROR, MM_CORE_ERROR_FAILED,
"Couldn't find matching 2G bands Telit value for band combination: '%s'", bands_str);
g_free (bands_str);
return NULL;
}
}
/* Get 3G-specific telit value */
if (mask3g) {
for (i = 0; i < telit_3g_to_mm_band_mask_n_elements; i++) {
if (mask3g == telit_3g_to_mm_band_mask[i]) {
flag3g = i;
break;
}
}
if (flag3g == -1) {
gchar *bands_str;
if (flag4g != NULL &&
band >= MM_MODEM_BAND_EUTRAN_1 && band <= MM_MODEM_BAND_EUTRAN_44) {
mask4g += 1 << (band - MM_MODEM_BAND_EUTRAN_1);
found4g = TRUE;
bands_str = mm_common_build_bands_string ((const MMModemBand *)(bands_array->data), bands_array->len);
g_set_error (error, MM_CORE_ERROR, MM_CORE_ERROR_FAILED,
"Couldn't find matching 3G bands Telit value for band combination: '%s'", bands_str);
g_free (bands_str);
return NULL;
}
}
/* Get 2G flag */
if (flag2g != NULL) {
if (mask2g == ((1 << MM_MODEM_BAND_EGSM) + (1 << MM_MODEM_BAND_DCS)))
*flag2g = 0;
else if (mask2g == ((1 << MM_MODEM_BAND_EGSM) + (1 << MM_MODEM_BAND_PCS)))
*flag2g = 1;
else if (mask2g == ((1 << MM_MODEM_BAND_G850) + (1 << MM_MODEM_BAND_DCS)))
*flag2g = 2;
else if (mask2g == ((1 << MM_MODEM_BAND_G850) + (1 << MM_MODEM_BAND_PCS)))
*flag2g = 3;
else
*flag2g = -1;
/* Get 4G-specific telit band bitmask */
flag4g = (mask4g != 0) ? mask4g : -1;
/* If the modem supports a given access tech, we must always give band settings
* for the specific tech */
if (modem_is_2g && flag2g == -1) {
g_set_error (error, MM_CORE_ERROR, MM_CORE_ERROR_NOT_FOUND,
"None or invalid 2G bands combination in the provided list");
return NULL;
}
if (modem_is_3g && flag3g == -1) {
g_set_error (error, MM_CORE_ERROR, MM_CORE_ERROR_NOT_FOUND,
"None or invalid 3G bands combination in the provided list");
return NULL;
}
if (modem_is_4g && flag4g == -1) {
g_set_error (error, MM_CORE_ERROR, MM_CORE_ERROR_NOT_FOUND,
"None or invalid 4G bands combination in the provided list");
return NULL;
}
/* Get 3G flag */
if (flag3g != NULL) {
if (mask3g == (1 << MM_MODEM_BAND_UTRAN_1))
*flag3g = 0;
else if (mask3g == (1 << MM_MODEM_BAND_UTRAN_2))
*flag3g = 1;
else if (mask3g == (1 << MM_MODEM_BAND_UTRAN_5))
*flag3g = 2;
else if (mask3g == ((1 << MM_MODEM_BAND_UTRAN_1) +
(1 << MM_MODEM_BAND_UTRAN_2) +
(1 << MM_MODEM_BAND_UTRAN_5)))
*flag3g = 3;
else if (mask3g == ((1 << MM_MODEM_BAND_UTRAN_2) +
(1 << MM_MODEM_BAND_UTRAN_5)))
*flag3g = 4;
else if (mask3g == (1 << MM_MODEM_BAND_UTRAN_8))
*flag3g = 5;
else if (mask3g == ((1 << MM_MODEM_BAND_UTRAN_1) +
(1 << MM_MODEM_BAND_UTRAN_8)))
*flag3g = 6;
else if (mask3g == (1 << MM_MODEM_BAND_UTRAN_4))
*flag3g = 7;
else
*flag3g = -1;
}
if (modem_is_2g && !modem_is_3g && !modem_is_4g)
cmd = g_strdup_printf ("#BND=%d", flag2g);
else if (!modem_is_2g && modem_is_3g && !modem_is_4g)
cmd = g_strdup_printf ("#BND=0,%d", flag3g);
else if (!modem_is_2g && !modem_is_3g && modem_is_4g)
cmd = g_strdup_printf ("#BND=0,0,%d", flag4g);
else if (modem_is_2g && modem_is_3g && !modem_is_4g)
cmd = g_strdup_printf ("#BND=%d,%d", flag2g, flag3g);
else if (!modem_is_2g && modem_is_3g && modem_is_4g)
cmd = g_strdup_printf ("#BND=0,%d,%d", flag3g, flag4g);
else if (modem_is_2g && !modem_is_3g && modem_is_4g)
cmd = g_strdup_printf ("#BND=%d,0,%d", flag2g, flag4g);
else if (modem_is_2g && modem_is_3g && modem_is_4g)
cmd = g_strdup_printf ("#BND=%d,%d,%d", flag2g, flag3g, flag4g);
else
g_assert_not_reached ();
/* 4G flag correspond to the mask */
if (flag4g != NULL) {
if (found4g)
*flag4g = mask4g;
else
*flag4g = -1;
}
return cmd;
}
#define SUPP_BAND_RESPONSE_REGEX "#BND:\\s*\\((?P<Bands2G>[0-9\\-,]*)\\)(,\\s*\\((?P<Bands3G>[0-9\\-,]*)\\))?(,\\s*\\((?P<Bands4G>[0-9\\-,]*)\\))?"
#define CURR_BAND_RESPONSE_REGEX "#BND:\\s*(?P<Bands2G>\\d+)(,\\s*(?P<Bands3G>\\d+))?(,\\s*(?P<Bands4G>\\d+))?"
/*****************************************************************************/
/* #BND response parser
*
@@ -187,333 +371,255 @@ mm_telit_get_band_flag (GArray *bands_array,
* 4 = 3G band flag 4 is U1900 + U850
*
*/
gboolean
mm_telit_parse_bnd_response (const gchar *response,
gboolean modem_is_2g,
gboolean modem_is_3g,
gboolean modem_is_4g,
MMTelitLoadBandsType band_type,
GArray **supported_bands,
GError **error)
{
GArray *bands = NULL;
GMatchInfo *match_info = NULL;
GRegex *r = NULL;
gboolean ret = FALSE;
switch (band_type) {
case LOAD_SUPPORTED_BANDS:
/* Parse #BND=? response */
r = g_regex_new (SUPP_BAND_RESPONSE_REGEX, G_REGEX_RAW, 0, NULL);
break;
case LOAD_CURRENT_BANDS:
/* Parse #BND? response */
r = g_regex_new (CURR_BAND_RESPONSE_REGEX, G_REGEX_RAW, 0, NULL);
default:
break;
static gboolean
telit_get_2g_mm_bands (GMatchInfo *match_info,
GArray **bands,
GError **error)
{
GError *inner_error = NULL;
GArray *values = NULL;
gchar *match_str = NULL;
guint i;
match_str = g_match_info_fetch_named (match_info, "Bands2G");
if (!match_str || match_str[0] == '\0') {
g_set_error (&inner_error, MM_CORE_ERROR, MM_CORE_ERROR_FAILED,
"Could not find 2G band values from response");
goto out;
}
values = mm_parse_uint_list (match_str, &inner_error);
if (!values)
goto out;
for (i = 0; i < values->len; i++) {
guint value;
value = g_array_index (values, guint, i);
if (value < G_N_ELEMENTS (telit_2g_to_mm_band_mask)) {
guint j;
for (j = MM_MODEM_BAND_TELIT_2G_FIRST; j <= MM_MODEM_BAND_TELIT_2G_LAST; j++) {
if ((telit_2g_to_mm_band_mask[value] & B2G_FLAG (j)) && !mm_common_bands_garray_lookup (*bands, j))
*bands = g_array_append_val (*bands, j);
}
} else
mm_dbg ("unhandled telit 2G band value configuration: %u", value);
}
out:
g_free (match_str);
g_clear_pointer (&values, g_array_unref);
if (inner_error) {
g_propagate_error (error, inner_error);
return FALSE;
}
return TRUE;
}
static gboolean
telit_get_3g_mm_bands (GMatchInfo *match_info,
GArray **bands,
gboolean modem_alternate_3g_bands,
GError **error)
{
GError *inner_error = NULL;
GArray *values = NULL;
gchar *match_str = NULL;
guint i;
const guint32 *telit_3g_to_mm_band_mask;
guint telit_3g_to_mm_band_mask_n_elements;
initialize_telit_3g_to_mm_band_masks ();
/* Select correct 3G band mask */
if (modem_alternate_3g_bands) {
telit_3g_to_mm_band_mask = telit_3g_to_mm_band_mask_alternate;
telit_3g_to_mm_band_mask_n_elements = G_N_ELEMENTS (telit_3g_to_mm_band_mask_alternate);
} else {
telit_3g_to_mm_band_mask = telit_3g_to_mm_band_mask_default;
telit_3g_to_mm_band_mask_n_elements = G_N_ELEMENTS (telit_3g_to_mm_band_mask_default);
}
match_str = g_match_info_fetch_named (match_info, "Bands3G");
if (!match_str || match_str[0] == '\0') {
g_set_error (&inner_error, MM_CORE_ERROR, MM_CORE_ERROR_FAILED,
"Could not find 3G band values from response");
goto out;
}
values = mm_parse_uint_list (match_str, &inner_error);
if (!values)
goto out;
for (i = 0; i < values->len; i++) {
guint value;
value = g_array_index (values, guint, i);
if (value < telit_3g_to_mm_band_mask_n_elements) {
guint j;
for (j = 0; j < G_N_ELEMENTS (band_utran_index); j++) {
/* ignore non-3G bands */
if (band_utran_index[j] == 0)
continue;
if ((telit_3g_to_mm_band_mask[value] & B3G_FLAG (j)) && !mm_common_bands_garray_lookup (*bands, j))
*bands = g_array_append_val (*bands, j);
}
} else
mm_dbg ("unhandled telit 3G band value configuration: %u", value);
}
out:
g_free (match_str);
g_clear_pointer (&values, g_array_unref);
if (inner_error) {
g_propagate_error (error, inner_error);
return FALSE;
}
return TRUE;
}
static gboolean
telit_get_4g_mm_bands (GMatchInfo *match_info,
GArray **bands,
GError **error)
{
GError *inner_error = NULL;
MMModemBand band;
gchar *match_str = NULL;
guint64 value;
gchar **tokens = NULL;
match_str = g_match_info_fetch_named (match_info, "Bands4G");
if (!match_str || match_str[0] == '\0') {
g_set_error (&inner_error, MM_CORE_ERROR, MM_CORE_ERROR_FAILED,
"Could not find 4G band flags from response");
goto out;
}
/* splitting will never return NULL as string is not empty */
tokens = g_strsplit (match_str, "-", -1);
/* If this is a range, get upper threshold, which contains the total supported mask */
if (!mm_get_u64_from_str (tokens[1] ? tokens[1] : tokens[0], &value)) {
g_set_error (&inner_error, MM_CORE_ERROR, MM_CORE_ERROR_FAILED,
"Could not parse 4G band mask from string: '%s'", match_str);
goto out;
}
for (band = MM_MODEM_BAND_TELIT_4G_FIRST; band <= MM_MODEM_BAND_TELIT_4G_LAST; band++) {
if ((value & B4G_FLAG (band)) && !mm_common_bands_garray_lookup (*bands, band))
g_array_append_val (*bands, band);
}
out:
g_strfreev (tokens);
g_free (match_str);
if (inner_error) {
g_propagate_error (error, inner_error);
return FALSE;
}
return TRUE;
}
typedef enum {
LOAD_BANDS_TYPE_SUPPORTED,
LOAD_BANDS_TYPE_CURRENT,
} LoadBandsType;
static GArray *
common_parse_bnd_response (const gchar *response,
gboolean modem_is_2g,
gboolean modem_is_3g,
gboolean modem_is_4g,
gboolean modem_alternate_3g_bands,
LoadBandsType load_type,
GError **error)
{
GError *inner_error = NULL;
GArray *bands = NULL;
GMatchInfo *match_info = NULL;
GRegex *r;
static const gchar *load_bands_regex[] = {
[LOAD_BANDS_TYPE_SUPPORTED] = "#BND:\\s*\\((?P<Bands2G>[0-9\\-,]*)\\)(,\\s*\\((?P<Bands3G>[0-9\\-,]*)\\))?(,\\s*\\((?P<Bands4G>[0-9\\-,]*)\\))?",
[LOAD_BANDS_TYPE_CURRENT] = "#BND:\\s*(?P<Bands2G>\\d+)(,\\s*(?P<Bands3G>\\d+))?(,\\s*(?P<Bands4G>\\d+))?",
};
r = g_regex_new (load_bands_regex[load_type], G_REGEX_RAW, 0, NULL);
g_assert (r);
if (!g_regex_match (r, response, 0, &match_info)) {
g_set_error (error, MM_CORE_ERROR, MM_CORE_ERROR_FAILED,
g_set_error (&inner_error, MM_CORE_ERROR, MM_CORE_ERROR_FAILED,
"Could not parse response '%s'", response);
goto end;
goto out;
}
if (!g_match_info_matches (match_info)) {
g_set_error (error, MM_CORE_ERROR, MM_CORE_ERROR_FAILED,
g_set_error (&inner_error, MM_CORE_ERROR, MM_CORE_ERROR_FAILED,
"Could not find matches in response '%s'", response);
goto end;
goto out;
}
bands = g_array_new (TRUE, TRUE, sizeof (MMModemBand));
if (modem_is_2g && !mm_telit_get_2g_mm_bands (match_info, &bands, error))
goto end;
if (modem_is_2g && !telit_get_2g_mm_bands (match_info, &bands, &inner_error))
goto out;
if (modem_is_3g && !mm_telit_get_3g_mm_bands (match_info, &bands, error))
goto end;
if (modem_is_3g && !telit_get_3g_mm_bands (match_info, &bands, modem_alternate_3g_bands, &inner_error))
goto out;
if (modem_is_4g && !mm_telit_get_4g_mm_bands (match_info, &bands, error))
goto end;
*supported_bands = bands;
ret = TRUE;
end:
if (!ret && bands != NULL)
g_array_free (bands, TRUE);
if (modem_is_4g && !telit_get_4g_mm_bands (match_info, &bands, &inner_error))
goto out;
out:
g_match_info_free (match_info);
g_regex_unref (r);
return ret;
if (inner_error) {
g_propagate_error (error, inner_error);
g_clear_pointer (&bands, g_array_unref);
return NULL;
}
return bands;
}
gboolean
mm_telit_get_2g_mm_bands (GMatchInfo *match_info,
GArray **bands,
GError **error)
GArray *
mm_telit_parse_bnd_query_response (const gchar *response,
gboolean modem_is_2g,
gboolean modem_is_3g,
gboolean modem_is_4g,
gboolean modem_alternate_3g_bands,
GError **error)
{
GArray *flags = NULL;
gchar *match_str = NULL;
guint i;
gboolean ret = TRUE;
TelitToMMBandMap map [5] = {
{ BND_FLAG_GSM900_DCS1800, {MM_MODEM_BAND_EGSM, MM_MODEM_BAND_DCS, MM_MODEM_BAND_UNKNOWN} }, /* 0 */
{ BND_FLAG_GSM900_PCS1900, {MM_MODEM_BAND_EGSM, MM_MODEM_BAND_PCS, MM_MODEM_BAND_UNKNOWN} }, /* 1 */
{ BND_FLAG_GSM850_DCS1800, {MM_MODEM_BAND_DCS, MM_MODEM_BAND_G850, MM_MODEM_BAND_UNKNOWN} }, /* 2 */
{ BND_FLAG_GSM850_PCS1900, {MM_MODEM_BAND_PCS, MM_MODEM_BAND_G850, MM_MODEM_BAND_UNKNOWN} }, /* 3 */
{ BND_FLAG_UNKNOWN, {}},
};
match_str = g_match_info_fetch_named (match_info, "Bands2G");
if (match_str == NULL || match_str[0] == '\0') {
g_set_error (error, MM_CORE_ERROR, MM_CORE_ERROR_FAILED,
"Could not find 2G band flags from response");
ret = FALSE;
goto end;
}
flags = g_array_new (FALSE, FALSE, sizeof (guint));
if (!mm_telit_get_band_flags_from_string (match_str, &flags, error)) {
ret = FALSE;
goto end;
}
for (i = 0; i < flags->len; i++) {
guint flag;
flag = g_array_index (flags, guint, i);
if (!mm_telit_update_band_array (flag, map, bands, error)) {
ret = FALSE;
goto end;
}
}
end:
g_free (match_str);
if (flags != NULL)
g_array_free (flags, TRUE);
return ret;
return common_parse_bnd_response (response,
modem_is_2g, modem_is_3g, modem_is_4g,
modem_alternate_3g_bands,
LOAD_BANDS_TYPE_CURRENT,
error);
}
gboolean
mm_telit_get_3g_mm_bands (GMatchInfo *match_info,
GArray **bands,
GError **error)
GArray *
mm_telit_parse_bnd_test_response (const gchar *response,
gboolean modem_is_2g,
gboolean modem_is_3g,
gboolean modem_is_4g,
gboolean modem_alternate_3g_bands,
GError **error)
{
GArray *flags = NULL;
gchar *match_str = NULL;
guint i;
gboolean ret = TRUE;
TelitToMMBandMap map [] = {
{ BND_FLAG_0, { MM_MODEM_BAND_UTRAN_1, MM_MODEM_BAND_UNKNOWN} },
{ BND_FLAG_1, { MM_MODEM_BAND_UTRAN_2, MM_MODEM_BAND_UNKNOWN} },
{ BND_FLAG_2, { MM_MODEM_BAND_UTRAN_5, MM_MODEM_BAND_UNKNOWN} },
{ BND_FLAG_3, { MM_MODEM_BAND_UTRAN_1, MM_MODEM_BAND_UTRAN_2, MM_MODEM_BAND_UTRAN_5, MM_MODEM_BAND_UNKNOWN} },
{ BND_FLAG_4, { MM_MODEM_BAND_UTRAN_2, MM_MODEM_BAND_UTRAN_5, MM_MODEM_BAND_UNKNOWN} },
{ BND_FLAG_5, { MM_MODEM_BAND_UTRAN_8, MM_MODEM_BAND_UNKNOWN} },
{ BND_FLAG_6, { MM_MODEM_BAND_UTRAN_1, MM_MODEM_BAND_UTRAN_8, MM_MODEM_BAND_UNKNOWN} },
{ BND_FLAG_7, { MM_MODEM_BAND_UTRAN_4, MM_MODEM_BAND_UNKNOWN} },
{ BND_FLAG_8, { MM_MODEM_BAND_UTRAN_1, MM_MODEM_BAND_UTRAN_5, MM_MODEM_BAND_UNKNOWN }},
{ BND_FLAG_9, { MM_MODEM_BAND_UTRAN_1, MM_MODEM_BAND_UTRAN_8, MM_MODEM_BAND_UTRAN_5, MM_MODEM_BAND_UNKNOWN }},
{ BND_FLAG_10, { MM_MODEM_BAND_UTRAN_2, MM_MODEM_BAND_UTRAN_4, MM_MODEM_BAND_UTRAN_5, MM_MODEM_BAND_UNKNOWN }},
{ BND_FLAG_12, { MM_MODEM_BAND_UTRAN_6, MM_MODEM_BAND_UNKNOWN}},
{ BND_FLAG_13, { MM_MODEM_BAND_UTRAN_3, MM_MODEM_BAND_UNKNOWN }},
{ BND_FLAG_14, { MM_MODEM_BAND_UTRAN_1, MM_MODEM_BAND_UTRAN_8, MM_MODEM_BAND_UTRAN_4, MM_MODEM_BAND_UTRAN_5, MM_MODEM_BAND_UTRAN_6, MM_MODEM_BAND_UNKNOWN }},
{ BND_FLAG_15, { MM_MODEM_BAND_UTRAN_1, MM_MODEM_BAND_UTRAN_8, MM_MODEM_BAND_UTRAN_3, MM_MODEM_BAND_UNKNOWN }},
{ BND_FLAG_16, { MM_MODEM_BAND_UTRAN_8, MM_MODEM_BAND_UTRAN_5, MM_MODEM_BAND_UNKNOWN }},
{ BND_FLAG_17, { MM_MODEM_BAND_UTRAN_2, MM_MODEM_BAND_UTRAN_4, MM_MODEM_BAND_UTRAN_5, MM_MODEM_BAND_UTRAN_6, MM_MODEM_BAND_UNKNOWN }},
{ BND_FLAG_18, { MM_MODEM_BAND_UTRAN_1, MM_MODEM_BAND_UTRAN_2, MM_MODEM_BAND_UTRAN_5, MM_MODEM_BAND_UTRAN_6, MM_MODEM_BAND_UNKNOWN}},
{ BND_FLAG_19, { MM_MODEM_BAND_UTRAN_2, MM_MODEM_BAND_UTRAN_6, MM_MODEM_BAND_UNKNOWN }},
{ BND_FLAG_20, { MM_MODEM_BAND_UTRAN_5, MM_MODEM_BAND_UTRAN_6, MM_MODEM_BAND_UNKNOWN}},
{ BND_FLAG_21, { MM_MODEM_BAND_UTRAN_2, MM_MODEM_BAND_UTRAN_5, MM_MODEM_BAND_UTRAN_6, MM_MODEM_BAND_UNKNOWN}},
{ BND_FLAG_UNKNOWN, {}},
};
match_str = g_match_info_fetch_named (match_info, "Bands3G");
if (match_str == NULL || match_str[0] == '\0') {
g_set_error (error, MM_CORE_ERROR, MM_CORE_ERROR_FAILED,
"Could not find 3G band flags from response");
ret = FALSE;
goto end;
}
flags = g_array_new (FALSE, FALSE, sizeof (guint));
if (!mm_telit_get_band_flags_from_string (match_str, &flags, error)) {
ret = FALSE;
goto end;
}
for (i = 0; i < flags->len; i++) {
guint flag;
flag = g_array_index (flags, guint, i);
if (!mm_telit_update_band_array (flag, map, bands, error)) {
ret = FALSE;
goto end;
}
}
end:
g_free (match_str);
if (flags != NULL)
g_array_free (flags, TRUE);
return ret;
}
gboolean
mm_telit_get_4g_mm_bands (GMatchInfo *match_info,
GArray **bands,
GError **error)
{
MMModemBand band;
gboolean ret = TRUE;
gchar *match_str = NULL;
guint i;
guint value;
gchar **tokens;
match_str = g_match_info_fetch_named (match_info, "Bands4G");
if (match_str == NULL || match_str[0] == '\0') {
g_set_error (error, MM_CORE_ERROR, MM_CORE_ERROR_FAILED,
"Could not find 4G band flags from response");
ret = FALSE;
goto end;
}
if (strstr (match_str, "-")) {
tokens = g_strsplit (match_str, "-", -1);
if (tokens == NULL) {
g_set_error (error, MM_CORE_ERROR, MM_CORE_ERROR_FAILED,
"Could not get 4G band ranges from string '%s'",
match_str);
ret = FALSE;
goto end;
}
sscanf (tokens[1], "%d", &value);
g_strfreev (tokens);
} else {
sscanf (match_str, "%d", &value);
}
for (i = 0; value > 0; i++) {
if (value % 2 != 0) {
band = MM_MODEM_BAND_EUTRAN_1 + i;
g_array_append_val (*bands, band);
}
value = value >> 1;
}
end:
g_free (match_str);
return ret;
}
gboolean
mm_telit_bands_contains (GArray *mm_bands, const MMModemBand mm_band)
{
guint i;
for (i = 0; i < mm_bands->len; i++) {
if (mm_band == g_array_index (mm_bands, MMModemBand, i))
return TRUE;
}
return FALSE;
}
gboolean
mm_telit_update_band_array (const gint bands_flag,
const TelitToMMBandMap *map,
GArray **bands,
GError **error)
{
guint i;
guint j;
for (i = 0; map[i].flag != BND_FLAG_UNKNOWN; i++) {
if (bands_flag == map[i].flag) {
for (j = 0; map[i].mm_bands[j] != MM_MODEM_BAND_UNKNOWN; j++) {
if (!mm_telit_bands_contains (*bands, map[i].mm_bands[j])) {
g_array_append_val (*bands, map[i].mm_bands[j]);
}
}
return TRUE;
}
}
g_set_error (error, MM_CORE_ERROR, MM_CORE_ERROR_FAILED,
"No MM band found for Telit #BND flag '%d'",
bands_flag);
return FALSE;
}
gboolean
mm_telit_get_band_flags_from_string (const gchar *flag_str,
GArray **band_flags,
GError **error)
{
gchar **range;
gchar **tokens;
guint flag;
guint i;
if (flag_str == NULL || flag_str[0] == '\0') {
g_set_error (error, MM_CORE_ERROR, MM_CORE_ERROR_FAILED,
"String is empty, no band flags to parse");
return FALSE;
}
tokens = g_strsplit (flag_str, ",", -1);
if (!tokens) {
g_set_error (error, MM_CORE_ERROR, MM_CORE_ERROR_FAILED,
"Could not get the list of flags");
return FALSE;
}
for (i = 0; tokens[i]; i++) {
/* check whether tokens[i] defines a
* single band value or a range of bands */
if (!strstr (tokens[i], "-")) {
sscanf (tokens[i], "%d", &flag);
g_array_append_val (*band_flags, flag);
} else {
gint range_start;
gint range_end;
range = g_strsplit (tokens[i], "-", 2);
sscanf (range[0], "%d", &range_start);
sscanf (range[1], "%d", &range_end);
for (flag = range_start; flag <= range_end; flag++) {
g_array_append_val (*band_flags, flag);
}
g_strfreev (range);
}
}
g_strfreev (tokens);
return TRUE;
return common_parse_bnd_response (response,
modem_is_2g, modem_is_3g, modem_is_4g,
modem_alternate_3g_bands,
LOAD_BANDS_TYPE_SUPPORTED,
error);
}
/*****************************************************************************/
+21 -77
View File
@@ -10,8 +10,8 @@
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details:
*
* Copyright (C) 2015 Telit.
*
* Copyright (C) 2015-2019 Telit.
* Copyright (C) 2019 Aleksander Morgado <aleksander@aleksander.es>
*/
#ifndef MM_MODEM_HELPERS_TELIT_H
#define MM_MODEM_HELPERS_TELIT_H
@@ -19,81 +19,25 @@
#include <glib.h>
#include "ModemManager.h"
#define MAX_BANDS_LIST_LEN 20
#define BND_FLAG_UNKNOWN -1
/* AT#BND 2G flags */
typedef enum {
BND_FLAG_GSM900_DCS1800,
BND_FLAG_GSM900_PCS1900,
BND_FLAG_GSM850_DCS1800,
BND_FLAG_GSM850_PCS1900,
} BndFlag2G;
/* AT#BND 3G flags */
typedef enum {
BND_FLAG_0, /* B1 (2100 MHz) */
BND_FLAG_1, /* B2 (1900 MHz) */
BND_FLAG_2, /* B5 (850 MHz) */
BND_FLAG_3, /* B1 (2100 MHz) + B2 (1900 MHz) + B5 (850 MHz) */
BND_FLAG_4, /* B2 (1900 MHz) + B5 (850 MHz) */
BND_FLAG_5, /* B8 (900 MHz) */
BND_FLAG_6, /* B1 (2100 MHz) + B8 (900 MHz) */
BND_FLAG_7, /* B4 (1700 MHz) */
BND_FLAG_8, /* B1 (2100 MHz) + B5 (850 MHz) */
BND_FLAG_9, /* B1 (2100 MHz) + B8 (900 MHz) + B5 (850 MHz) */
BND_FLAG_10, /* B2 (1900 MHz) + B4 (1700 MHz) + B5 (850 MHz) */
BND_FLAG_12, /* B6 (800 MHz) */
BND_FLAG_13, /* B3 (1800 MHz) */
BND_FLAG_14, /* B1 (2100 MHz) + B2 (1900 MHz) + B4 (1700 MHz) + B5 (850 MHz) + B6 (800MHz) */
BND_FLAG_15, /* B1 (2100 MHz) + B8 (900 MHz) + B3 (1800 MHz) */
BND_FLAG_16, /* B8 (900 MHz) + B5 (850 MHz) */
BND_FLAG_17, /* B2 (1900 MHz) + B4 (1700 MHz) + B5 (850 MHz) + B6 (800 MHz) */
BND_FLAG_18, /* B1 (2100 MHz) + B2 (1900 MHz) + B5 (850 MHz) + B6 (800 MHz) */
BND_FLAG_19, /* B2 (1900 MHz) + B6 (800 MHz) */
BND_FLAG_20, /* B5 (850 MHz) + B6 (800 MHz) */
BND_FLAG_21, /* B2 (1900 MHz) + B5 (850 MHz) + B6 (800 MHz) */
} BndFlag3G;
typedef struct {
gint flag;
MMModemBand mm_bands[MAX_BANDS_LIST_LEN];
} TelitToMMBandMap;
typedef enum {
LOAD_SUPPORTED_BANDS,
LOAD_CURRENT_BANDS
} MMTelitLoadBandsType;
/* #BND response parser */
gboolean
mm_telit_parse_bnd_response (const gchar *response,
gboolean modem_is_2g,
gboolean modem_is_3g,
gboolean modem_is_4g,
MMTelitLoadBandsType band_type,
GArray **supported_bands,
GError **error);
gboolean mm_telit_bands_contains (GArray *mm_bands, const MMModemBand mm_band);
gboolean mm_telit_update_band_array (const gint bands_flag,
const TelitToMMBandMap *map,
GArray **bands,
GError **error);
gboolean mm_telit_get_band_flags_from_string (const gchar *flag_str, GArray **band_flags, GError **error);
gboolean mm_telit_get_2g_mm_bands(GMatchInfo *match_info, GArray **bands, GError **error);
gboolean mm_telit_get_3g_mm_bands(GMatchInfo *match_info, GArray **bands, GError **error);
gboolean mm_telit_get_4g_mm_bands(GMatchInfo *match_info, GArray **bands, GError **error);
gboolean mm_telit_update_2g_bands(gchar *band_list, GMatchInfo **match_info, GArray **bands, GError **error);
gboolean mm_telit_update_3g_bands(gchar *band_list, GMatchInfo **match_info, GArray **bands, GError **error);
gboolean mm_telit_update_4g_bands(GArray** bands, GMatchInfo *match_info, GError **error);
void mm_telit_get_band_flag (GArray *bands_array, gint *flag_2g, gint *flag_3g, gint *flag_4g);
/* #BND response parsers and request builder */
GArray *mm_telit_parse_bnd_query_response (const gchar *response,
gboolean modem_is_2g,
gboolean modem_is_3g,
gboolean modem_is_4g,
gboolean modem_alternate_3g_bands,
GError **error);
GArray *mm_telit_parse_bnd_test_response (const gchar *response,
gboolean modem_is_2g,
gboolean modem_is_3g,
gboolean modem_is_4g,
gboolean modem_alternate_3g_bands,
GError **error);
gchar *mm_telit_build_bnd_request (GArray *bands_array,
gboolean modem_is_2g,
gboolean modem_is_3g,
gboolean modem_is_4g,
gboolean modem_alternate_3g_bands,
GError **error);
/* #QSS? response parser */
typedef enum { /*< underscore_name=mm_telit_qss_status >*/
+168 -149
View File
@@ -31,6 +31,59 @@
#include "mm-modem-helpers-telit.h"
#include "mm-shared-telit.h"
/*****************************************************************************/
/* Private data context */
#define PRIVATE_TAG "shared-telit-private-tag"
static GQuark private_quark;
typedef struct {
gboolean alternate_3g_bands;
GArray *supported_bands;
} Private;
static void
private_free (Private *priv)
{
if (priv->supported_bands)
g_array_unref (priv->supported_bands);
g_slice_free (Private, priv);
}
static void
initialize_alternate_3g_band (MMSharedTelit *self,
Private *priv)
{
MMPort *primary;
MMKernelDevice *port;
primary = MM_PORT (mm_base_modem_peek_port_primary (MM_BASE_MODEM (self)));
port = mm_port_peek_kernel_device (primary);
/* Lookup for the tag specifying that we're using the alternate 3G band mapping */
priv->alternate_3g_bands = mm_kernel_device_get_global_property_as_boolean (port, "ID_MM_TELIT_BND_ALTERNATE");
if (priv->alternate_3g_bands)
mm_dbg ("Telit modem using alternate 3G band mask setup");
}
static Private *
get_private (MMSharedTelit *self)
{
Private *priv;
if (G_UNLIKELY (!private_quark))
private_quark = g_quark_from_static_string (PRIVATE_TAG);
priv = g_object_get_qdata (G_OBJECT (self), private_quark);
if (!priv) {
priv = g_slice_new0 (Private);
initialize_alternate_3g_band (self, priv);
g_object_set_qdata_full (G_OBJECT (self), private_quark, priv, (GDestroyNotify)private_free);
}
return priv;
}
/*****************************************************************************/
/* Load current mode (Modem interface) */
@@ -114,126 +167,133 @@ mm_shared_telit_load_current_modes (MMIfaceModem *self,
/*****************************************************************************/
/* Load supported bands (Modem interface) */
typedef struct {
gboolean mm_modem_is_2g;
gboolean mm_modem_is_3g;
gboolean mm_modem_is_4g;
MMTelitLoadBandsType band_type;
} LoadBandsContext;
static void
mm_shared_telit_load_bands_context_free (LoadBandsContext *ctx)
GArray *
mm_shared_telit_modem_load_supported_bands_finish (MMIfaceModem *self,
GAsyncResult *res,
GError **error)
{
g_slice_free (LoadBandsContext, ctx);
return g_task_propagate_pointer (G_TASK (res), error);
}
static void
mm_shared_telit_load_bands_ready (MMBaseModem *self,
GAsyncResult *res,
GTask *task)
mm_shared_telit_load_supported_bands_ready (MMBaseModem *self,
GAsyncResult *res,
GTask *task)
{
const gchar *response;
GError *error = NULL;
GArray *bands = NULL;
LoadBandsContext *ctx;
GError *error = NULL;
Private *priv;
priv = get_private (MM_SHARED_TELIT (self));
ctx = g_task_get_task_data (task);
response = mm_base_modem_at_command_finish (self, res, &error);
if (!response)
g_task_return_error (task, error);
else if (!mm_telit_parse_bnd_response (response,
ctx->mm_modem_is_2g,
ctx->mm_modem_is_3g,
ctx->mm_modem_is_4g,
ctx->band_type,
&bands,
&error))
g_task_return_error (task, error);
else
g_task_return_pointer (task, bands, (GDestroyNotify)g_array_unref);
else {
GArray *bands;
bands = mm_telit_parse_bnd_test_response (response,
mm_iface_modem_is_2g (MM_IFACE_MODEM (self)),
mm_iface_modem_is_3g (MM_IFACE_MODEM (self)),
mm_iface_modem_is_4g (MM_IFACE_MODEM (self)),
priv->alternate_3g_bands,
&error);
if (!bands)
g_task_return_error (task, error);
else {
/* Store supported bands to be able to build ANY when setting */
priv->supported_bands = g_array_ref (bands);
g_task_return_pointer (task, bands, (GDestroyNotify)g_array_unref);
}
}
g_object_unref (task);
}
void
mm_shared_telit_modem_load_supported_bands (MMIfaceModem *self,
GAsyncReadyCallback callback,
gpointer user_data)
mm_shared_telit_modem_load_supported_bands (MMIfaceModem *self,
GAsyncReadyCallback callback,
gpointer user_data)
{
GTask *task;
LoadBandsContext *ctx;
ctx = g_slice_new0 (LoadBandsContext);
ctx->mm_modem_is_2g = mm_iface_modem_is_2g (self);
ctx->mm_modem_is_3g = mm_iface_modem_is_3g (self);
ctx->mm_modem_is_4g = mm_iface_modem_is_4g (self);
ctx->band_type = LOAD_SUPPORTED_BANDS;
task = g_task_new (self, NULL, callback, user_data);
g_task_set_task_data (task, ctx, (GDestroyNotify)mm_shared_telit_load_bands_context_free);
mm_base_modem_at_command (MM_BASE_MODEM (self),
"#BND=?",
3,
FALSE,
(GAsyncReadyCallback) mm_shared_telit_load_bands_ready,
task);
TRUE,
(GAsyncReadyCallback) mm_shared_telit_load_supported_bands_ready,
g_task_new (self, NULL, callback, user_data));
}
/*****************************************************************************/
/* Load current bands (Modem interface) */
GArray *
mm_shared_telit_modem_load_bands_finish (MMIfaceModem *self,
GAsyncResult *res,
GError **error)
mm_shared_telit_modem_load_current_bands_finish (MMIfaceModem *self,
GAsyncResult *res,
GError **error)
{
return (GArray *) g_task_propagate_pointer (G_TASK (res), error);
return g_task_propagate_pointer (G_TASK (res), error);
}
static void
mm_shared_telit_load_current_bands_ready (MMBaseModem *self,
GAsyncResult *res,
GTask *task)
{
const gchar *response;
GError *error = NULL;
Private *priv;
priv = get_private (MM_SHARED_TELIT (self));
response = mm_base_modem_at_command_finish (self, res, &error);
if (!response)
g_task_return_error (task, error);
else {
GArray *bands;
bands = mm_telit_parse_bnd_query_response (response,
mm_iface_modem_is_2g (MM_IFACE_MODEM (self)),
mm_iface_modem_is_3g (MM_IFACE_MODEM (self)),
mm_iface_modem_is_4g (MM_IFACE_MODEM (self)),
priv->alternate_3g_bands,
&error);
if (!bands)
g_task_return_error (task, error);
else
g_task_return_pointer (task, bands, (GDestroyNotify)g_array_unref);
}
g_object_unref (task);
}
void
mm_shared_telit_modem_load_current_bands (MMIfaceModem *self,
GAsyncReadyCallback callback,
gpointer user_data)
mm_shared_telit_modem_load_current_bands (MMIfaceModem *self,
GAsyncReadyCallback callback,
gpointer user_data)
{
GTask *task;
LoadBandsContext *ctx;
ctx = g_slice_new0 (LoadBandsContext);
ctx->mm_modem_is_2g = mm_iface_modem_is_2g (self);
ctx->mm_modem_is_3g = mm_iface_modem_is_3g (self);
ctx->mm_modem_is_4g = mm_iface_modem_is_4g (self);
ctx->band_type = LOAD_CURRENT_BANDS;
task = g_task_new (self, NULL, callback, user_data);
g_task_set_task_data (task, ctx, (GDestroyNotify)mm_shared_telit_load_bands_context_free);
mm_base_modem_at_command (MM_BASE_MODEM (self),
"#BND?",
3,
FALSE,
(GAsyncReadyCallback) mm_shared_telit_load_bands_ready,
task);
(GAsyncReadyCallback) mm_shared_telit_load_current_bands_ready,
g_task_new (self, NULL, callback, user_data));
}
/*****************************************************************************/
/* Set current bands (Modem interface) */
gboolean
mm_shared_telit_modem_set_current_bands_finish (MMIfaceModem *self,
GAsyncResult *res,
GError **error)
mm_shared_telit_modem_set_current_bands_finish (MMIfaceModem *self,
GAsyncResult *res,
GError **error)
{
return g_task_propagate_boolean (G_TASK (res), error);
}
static void
mm_shared_telit_modem_set_current_bands_ready (MMBaseModem *self,
GAsyncResult *res,
GTask *task)
set_current_bands_ready (MMBaseModem *self,
GAsyncResult *res,
GTask *task)
{
GError *error = NULL;
@@ -247,88 +307,47 @@ mm_shared_telit_modem_set_current_bands_ready (MMBaseModem *self,
}
void
mm_shared_telit_modem_set_current_bands (MMIfaceModem *self,
GArray *bands_array,
GAsyncReadyCallback callback,
gpointer user_data)
mm_shared_telit_modem_set_current_bands (MMIfaceModem *self,
GArray *bands_array,
GAsyncReadyCallback callback,
gpointer user_data)
{
gchar *cmd;
gint flag2g;
gint flag3g;
gint flag4g;
gboolean is_2g;
gboolean is_3g;
gboolean is_4g;
GTask *task;
GTask *task;
GError *error = NULL;
gchar *cmd;
Private *priv;
mm_telit_get_band_flag (bands_array, &flag2g, &flag3g, &flag4g);
priv = get_private (MM_SHARED_TELIT (self));
is_2g = mm_iface_modem_is_2g (self);
is_3g = mm_iface_modem_is_3g (self);
is_4g = mm_iface_modem_is_4g (self);
if (is_2g && flag2g == -1) {
g_task_report_new_error (self,
callback,
user_data,
mm_shared_telit_modem_set_current_bands,
MM_CORE_ERROR,
MM_CORE_ERROR_NOT_FOUND,
"None or invalid 2G bands combination in the provided list");
return;
}
if (is_3g && flag3g == -1) {
g_task_report_new_error (self,
callback,
user_data,
mm_shared_telit_modem_set_current_bands,
MM_CORE_ERROR,
MM_CORE_ERROR_NOT_FOUND,
"None or invalid 3G bands combination in the provided list");
return;
}
if (is_4g && flag4g == -1) {
g_task_report_new_error (self,
callback,
user_data,
mm_shared_telit_modem_set_current_bands,
MM_CORE_ERROR,
MM_CORE_ERROR_NOT_FOUND,
"None or invalid 4G bands combination in the provided list");
return;
}
cmd = NULL;
if (is_2g && !is_3g && !is_4g)
cmd = g_strdup_printf ("AT#BND=%d", flag2g);
else if (is_2g && is_3g && !is_4g)
cmd = g_strdup_printf ("AT#BND=%d,%d", flag2g, flag3g);
else if (is_2g && is_3g && is_4g)
cmd = g_strdup_printf ("AT#BND=%d,%d,%d", flag2g, flag3g, flag4g);
else if (!is_2g && !is_3g && is_4g)
cmd = g_strdup_printf ("AT#BND=0,0,%d", flag4g);
else if (!is_2g && is_3g && is_4g)
cmd = g_strdup_printf ("AT#BND=0,%d,%d", flag3g, flag4g);
else if (is_2g && !is_3g && is_4g)
cmd = g_strdup_printf ("AT#BND=%d,0,%d", flag2g, flag4g);
else {
g_task_report_new_error (self,
callback,
user_data,
mm_shared_telit_modem_set_current_bands,
MM_CORE_ERROR,
MM_CORE_ERROR_FAILED,
"Unexpected error: could not compose AT#BND command");
return;
}
task = g_task_new (self, NULL, callback, user_data);
if (bands_array->len == 1 && g_array_index (bands_array, MMModemBand, 0) == MM_MODEM_BAND_ANY) {
if (!priv->supported_bands) {
g_task_return_new_error (task, MM_CORE_ERROR, MM_CORE_ERROR_FAILED,
"Couldn't build ANY band settings: unknown supported bands");
g_object_unref (task);
return;
}
bands_array = priv->supported_bands;
}
cmd = mm_telit_build_bnd_request (bands_array,
mm_iface_modem_is_2g (self),
mm_iface_modem_is_3g (self),
mm_iface_modem_is_4g (self),
priv->alternate_3g_bands,
&error);
if (!cmd) {
g_task_return_error (task, error);
g_object_unref (task);
return;
}
mm_base_modem_at_command (MM_BASE_MODEM (self),
cmd,
20,
FALSE,
(GAsyncReadyCallback)mm_shared_telit_modem_set_current_bands_ready,
(GAsyncReadyCallback)set_current_bands_ready,
task);
g_free (cmd);
}
+7 -3
View File
@@ -66,14 +66,18 @@ void mm_shared_telit_modem_load_supported_bands (MMIfaceModem *self,
GAsyncReadyCallback callback,
gpointer user_data);
GArray * mm_shared_telit_modem_load_bands_finish (MMIfaceModem *self,
GAsyncResult *res,
GError **error);
GArray * mm_shared_telit_modem_load_supported_bands_finish (MMIfaceModem *self,
GAsyncResult *res,
GError **error);
void mm_shared_telit_modem_load_current_bands (MMIfaceModem *self,
GAsyncReadyCallback callback,
gpointer user_data);
GArray * mm_shared_telit_modem_load_current_bands_finish (MMIfaceModem *self,
GAsyncResult *res,
GError **error);
gboolean mm_shared_telit_modem_set_current_bands_finish (MMIfaceModem *self,
GAsyncResult *res,
GError **error);
+385 -304
View File
@@ -10,7 +10,8 @@
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details:
*
* Copyright (C) 2015 Telit
* Copyright (C) 2015-2019 Telit
* Copyright (C) 2019 Aleksander Morgado <aleksander@aleksander.es>
*
*/
#include <stdio.h>
@@ -22,429 +23,489 @@
#define _LIBMM_INSIDE_MM
#include <libmm-glib.h>
#include "mm-log.h"
#include "mm-modem-helpers.h"
#include "mm-modem-helpers-telit.h"
static void
test_mm_bands_contains (void) {
GArray* mm_bands;
guint i = 1;
#include "test-helpers.h"
mm_bands = g_array_sized_new (FALSE, TRUE, sizeof (MMModemBand), 3);
/******************************************************************************/
for (i = 0; i < 3; i++)
g_array_append_val (mm_bands, i);
g_assert (mm_telit_bands_contains (mm_bands, 2));
g_assert (mm_telit_bands_contains (mm_bands, 2));
g_assert (!mm_telit_bands_contains (mm_bands, 3));
g_array_free (mm_bands, TRUE);
}
#define MAX_BANDS_LIST_LEN 17
typedef struct {
gchar* band_flag_str;
guint band_flags_len;
guint band_flags [MAX_BANDS_LIST_LEN];
} BNDFlagsTest;
gchar *response;
gboolean modem_is_2g;
gboolean modem_is_3g;
gboolean modem_is_4g;
gboolean modem_alternate_3g_bands;
guint mm_bands_len;
MMModemBand mm_bands [MAX_BANDS_LIST_LEN];
} BndResponseTest;
static BNDFlagsTest band_flag_test[] = {
{"0-3", 4, {0, 1, 2, 3} },
{"0,3", 2, {0, 3} },
{"0,2-3,5-7,9", 7, {0, 2, 3, 5, 6, 7, 9} },
{ NULL, 0, {}},
static BndResponseTest supported_band_mapping_tests [] = {
{
"#BND: (0-3)", TRUE, FALSE, FALSE, FALSE, 4,
{ MM_MODEM_BAND_EGSM,
MM_MODEM_BAND_DCS,
MM_MODEM_BAND_PCS,
MM_MODEM_BAND_G850 }
},
{
"#BND: (0-3),(0,2,5,6)", TRUE, TRUE, FALSE, FALSE, 7,
{ MM_MODEM_BAND_EGSM,
MM_MODEM_BAND_DCS,
MM_MODEM_BAND_PCS,
MM_MODEM_BAND_G850,
MM_MODEM_BAND_UTRAN_1,
MM_MODEM_BAND_UTRAN_5,
MM_MODEM_BAND_UTRAN_8 }
},
{
"#BND: (0,3),(0,2,5,6)", TRUE, TRUE, FALSE, FALSE, 7,
{ MM_MODEM_BAND_EGSM,
MM_MODEM_BAND_DCS,
MM_MODEM_BAND_PCS,
MM_MODEM_BAND_G850,
MM_MODEM_BAND_UTRAN_1,
MM_MODEM_BAND_UTRAN_5,
MM_MODEM_BAND_UTRAN_8 }
},
{
"#BND: (0,2),(0,2,5,6)", TRUE, TRUE, FALSE, FALSE, 6,
{ MM_MODEM_BAND_EGSM,
MM_MODEM_BAND_DCS,
MM_MODEM_BAND_G850,
MM_MODEM_BAND_UTRAN_1,
MM_MODEM_BAND_UTRAN_5,
MM_MODEM_BAND_UTRAN_8 }
},
{
"#BND: (0,2),(0-4,5,6)", TRUE, TRUE, FALSE, FALSE, 7,
{ MM_MODEM_BAND_EGSM,
MM_MODEM_BAND_DCS,
MM_MODEM_BAND_G850,
MM_MODEM_BAND_UTRAN_1,
MM_MODEM_BAND_UTRAN_2,
MM_MODEM_BAND_UTRAN_5,
MM_MODEM_BAND_UTRAN_8 }
},
{
"#BND: (0-3),(0,2,5,6),(1-1)", TRUE, TRUE, TRUE, FALSE, 8,
{ MM_MODEM_BAND_EGSM,
MM_MODEM_BAND_DCS,
MM_MODEM_BAND_PCS,
MM_MODEM_BAND_G850,
MM_MODEM_BAND_UTRAN_1,
MM_MODEM_BAND_UTRAN_5,
MM_MODEM_BAND_UTRAN_8,
MM_MODEM_BAND_EUTRAN_1 }
},
{
"#BND: (0),(0),(1-3)", TRUE, TRUE, TRUE, FALSE, 5,
{ MM_MODEM_BAND_EGSM,
MM_MODEM_BAND_DCS,
MM_MODEM_BAND_UTRAN_1,
MM_MODEM_BAND_EUTRAN_1,
MM_MODEM_BAND_EUTRAN_2 }
},
{
"#BND: (0),(0),(1-3)", FALSE, FALSE, TRUE, FALSE, 2,
{ MM_MODEM_BAND_EUTRAN_1,
MM_MODEM_BAND_EUTRAN_2 }
},
/* 3G alternate band settings: default */
{
"#BND: (0),(0,2,5,6,12,25)", FALSE, TRUE, FALSE, FALSE, 5,
{ MM_MODEM_BAND_UTRAN_1,
MM_MODEM_BAND_UTRAN_5,
MM_MODEM_BAND_UTRAN_8,
MM_MODEM_BAND_UTRAN_6,
MM_MODEM_BAND_UTRAN_19 }
},
/* 3G alternate band settings: alternate */
{
"#BND: (0),(0,2,5,6,12,13)", FALSE, TRUE, FALSE, TRUE, 4,
{ MM_MODEM_BAND_UTRAN_1,
MM_MODEM_BAND_UTRAN_3,
MM_MODEM_BAND_UTRAN_5,
MM_MODEM_BAND_UTRAN_8 }
},
/* ME910 (2G+4G device)
* 168695967: 0xA0E189F: 0000 1010 0000 1110 0001 1000 1001 1111
*/
{
"#BND: (0-5),(0),(1-168695967)", TRUE, FALSE, TRUE, FALSE, 17,
{ MM_MODEM_BAND_EGSM,
MM_MODEM_BAND_DCS,
MM_MODEM_BAND_PCS,
MM_MODEM_BAND_G850,
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_8,
MM_MODEM_BAND_EUTRAN_12,
MM_MODEM_BAND_EUTRAN_13,
MM_MODEM_BAND_EUTRAN_18,
MM_MODEM_BAND_EUTRAN_19,
MM_MODEM_BAND_EUTRAN_20,
MM_MODEM_BAND_EUTRAN_26,
MM_MODEM_BAND_EUTRAN_28 }
}
};
static void
test_parse_band_flag_str (void) {
GError *error = NULL;
gboolean res = FALSE;
GArray *band_flags = NULL;
guint i, j;
test_parse_supported_bands_response (void)
{
guint i;
for (i = 0; band_flag_test[i].band_flag_str != NULL; i++) {
band_flags = g_array_new (FALSE, FALSE, sizeof (guint));
res = mm_telit_get_band_flags_from_string (band_flag_test[i].band_flag_str,
&band_flags,
for (i = 0; i < G_N_ELEMENTS (supported_band_mapping_tests); i++) {
GError *error = NULL;
GArray *bands = NULL;
bands = mm_telit_parse_bnd_test_response (supported_band_mapping_tests[i].response,
supported_band_mapping_tests[i].modem_is_2g,
supported_band_mapping_tests[i].modem_is_3g,
supported_band_mapping_tests[i].modem_is_4g,
supported_band_mapping_tests[i].modem_alternate_3g_bands,
&error);
g_assert_no_error (error);
g_assert (bands);
mm_test_helpers_compare_bands (bands,
supported_band_mapping_tests[i].mm_bands,
supported_band_mapping_tests[i].mm_bands_len);
g_array_unref (bands);
}
}
static BndResponseTest current_band_mapping_tests [] = {
{
"#BND: 0", TRUE, FALSE, FALSE, FALSE, 2,
{ MM_MODEM_BAND_EGSM,
MM_MODEM_BAND_DCS }
},
{
"#BND: 0,5", TRUE, TRUE, FALSE, FALSE, 3,
{ MM_MODEM_BAND_EGSM,
MM_MODEM_BAND_DCS,
MM_MODEM_BAND_UTRAN_8 }
},
{
"#BND: 1,3", TRUE, TRUE, FALSE, FALSE, 5,
{ MM_MODEM_BAND_EGSM,
MM_MODEM_BAND_PCS,
MM_MODEM_BAND_UTRAN_1,
MM_MODEM_BAND_UTRAN_2,
MM_MODEM_BAND_UTRAN_5 }
},
{
"#BND: 2,7", TRUE, TRUE, FALSE, FALSE, 3,
{ MM_MODEM_BAND_DCS,
MM_MODEM_BAND_G850,
MM_MODEM_BAND_UTRAN_4 }
},
{
"#BND: 3,0,1", TRUE, TRUE, TRUE, FALSE, 4,
{ MM_MODEM_BAND_PCS,
MM_MODEM_BAND_G850,
MM_MODEM_BAND_UTRAN_1,
MM_MODEM_BAND_EUTRAN_1 }
},
{
"#BND: 0,0,3", TRUE, FALSE, TRUE, FALSE, 4,
{ MM_MODEM_BAND_EGSM,
MM_MODEM_BAND_DCS,
MM_MODEM_BAND_EUTRAN_1,
MM_MODEM_BAND_EUTRAN_2 }
},
{
"#BND: 0,0,3", FALSE, FALSE, TRUE, FALSE, 2,
{ MM_MODEM_BAND_EUTRAN_1,
MM_MODEM_BAND_EUTRAN_2 }
},
/* 3G alternate band settings: default */
{
"#BND: 0,12", FALSE, TRUE, FALSE, FALSE, 1,
{ MM_MODEM_BAND_UTRAN_6 }
},
/* 3G alternate band settings: alternate */
{
"#BND: 0,12", FALSE, TRUE, FALSE, TRUE, 4,
{ MM_MODEM_BAND_UTRAN_1,
MM_MODEM_BAND_UTRAN_3,
MM_MODEM_BAND_UTRAN_5,
MM_MODEM_BAND_UTRAN_8 }
},
/* ME910 (2G+4G device)
* 168695967: 0xA0E189F: 0000 1010 0000 1110 0001 1000 1001 1111
*/
{
"#BND: 5,0,168695967", TRUE, FALSE, TRUE, FALSE, 17,
{ MM_MODEM_BAND_EGSM,
MM_MODEM_BAND_DCS,
MM_MODEM_BAND_PCS,
MM_MODEM_BAND_G850,
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_8,
MM_MODEM_BAND_EUTRAN_12,
MM_MODEM_BAND_EUTRAN_13,
MM_MODEM_BAND_EUTRAN_18,
MM_MODEM_BAND_EUTRAN_19,
MM_MODEM_BAND_EUTRAN_20,
MM_MODEM_BAND_EUTRAN_26,
MM_MODEM_BAND_EUTRAN_28 }
}
};
static void
test_parse_current_bands_response (void)
{
guint i;
for (i = 0; i < G_N_ELEMENTS (current_band_mapping_tests); i++) {
GError *error = NULL;
GArray *bands = NULL;
bands = mm_telit_parse_bnd_query_response (current_band_mapping_tests[i].response,
current_band_mapping_tests[i].modem_is_2g,
current_band_mapping_tests[i].modem_is_3g,
current_band_mapping_tests[i].modem_is_4g,
current_band_mapping_tests[i].modem_alternate_3g_bands,
&error);
g_assert_no_error (error);
g_assert (res);
g_assert (bands);
for (j = 0; j < band_flag_test[i].band_flags_len; j++) {
guint ref;
guint cur;
ref = band_flag_test[i].band_flags[j];
cur = g_array_index (band_flags, guint, j);
g_assert (ref == cur);
}
g_array_free (band_flags, TRUE);
mm_test_helpers_compare_bands (bands,
current_band_mapping_tests[i].mm_bands,
current_band_mapping_tests[i].mm_bands_len);
g_array_unref (bands);
}
}
typedef struct {
gchar* response;
gboolean modem_is_2g;
gboolean modem_is_3g;
gboolean modem_is_4g;
guint mm_bands_len;
MMModemBand mm_bands [MAX_BANDS_LIST_LEN];
} BNDResponseTest;
static BNDResponseTest supported_band_mapping_tests [] = {
{ "#BND: (0-3)", TRUE, FALSE, FALSE, 4, { MM_MODEM_BAND_EGSM,
MM_MODEM_BAND_DCS,
MM_MODEM_BAND_PCS,
MM_MODEM_BAND_G850} },
{ "#BND: (0-3),(0,2,5,6)", TRUE, TRUE, FALSE, 7, { MM_MODEM_BAND_EGSM,
MM_MODEM_BAND_DCS,
MM_MODEM_BAND_PCS,
MM_MODEM_BAND_G850,
MM_MODEM_BAND_UTRAN_1,
MM_MODEM_BAND_UTRAN_5,
MM_MODEM_BAND_UTRAN_8 } },
{ "#BND: (0,3),(0,2,5,6)", TRUE, TRUE, FALSE, 7, { MM_MODEM_BAND_EGSM,
MM_MODEM_BAND_DCS,
MM_MODEM_BAND_PCS,
MM_MODEM_BAND_G850,
MM_MODEM_BAND_UTRAN_1,
MM_MODEM_BAND_UTRAN_5,
MM_MODEM_BAND_UTRAN_8} },
{ "#BND: (0,2),(0,2,5,6)", TRUE, TRUE, FALSE, 6, { MM_MODEM_BAND_EGSM,
MM_MODEM_BAND_DCS,
MM_MODEM_BAND_G850,
MM_MODEM_BAND_UTRAN_1,
MM_MODEM_BAND_UTRAN_5,
MM_MODEM_BAND_UTRAN_8} },
{ "#BND: (0,2),(0-4,5,6)", TRUE, TRUE, FALSE, 7, { MM_MODEM_BAND_EGSM,
MM_MODEM_BAND_DCS,
MM_MODEM_BAND_G850,
MM_MODEM_BAND_UTRAN_1,
MM_MODEM_BAND_UTRAN_2,
MM_MODEM_BAND_UTRAN_5,
MM_MODEM_BAND_UTRAN_8} },
{ "#BND: (0-3),(0,2,5,6),(1-1)", TRUE, TRUE, TRUE, 8, { MM_MODEM_BAND_EGSM,
MM_MODEM_BAND_DCS,
MM_MODEM_BAND_PCS,
MM_MODEM_BAND_G850,
MM_MODEM_BAND_UTRAN_1,
MM_MODEM_BAND_UTRAN_5,
MM_MODEM_BAND_UTRAN_8,
MM_MODEM_BAND_EUTRAN_1} },
{ "#BND: (0),(0),(1-3)", TRUE, TRUE, TRUE, 5, { MM_MODEM_BAND_EGSM,
MM_MODEM_BAND_DCS,
MM_MODEM_BAND_UTRAN_1,
MM_MODEM_BAND_EUTRAN_1,
MM_MODEM_BAND_EUTRAN_2} },
{ "#BND: (0),(0),(1-3)", FALSE, FALSE, TRUE, 2, { MM_MODEM_BAND_EUTRAN_1,
MM_MODEM_BAND_EUTRAN_2} },
{ NULL, FALSE, FALSE, FALSE, 0, {}},
};
/******************************************************************************/
static void
test_parse_supported_bands_response (void) {
GError* error = NULL;
gboolean res = FALSE;
guint i, j;
GArray* bands = NULL;
test_common_bnd_cmd (const gchar *expected_cmd,
gboolean modem_is_2g,
gboolean modem_is_3g,
gboolean modem_is_4g,
gboolean modem_alternate_3g_bands,
GArray *bands_array)
{
gchar *cmd;
GError *error = NULL;
for (i = 0; supported_band_mapping_tests[i].response != NULL; i++) {
res = mm_telit_parse_bnd_response (supported_band_mapping_tests[i].response,
supported_band_mapping_tests[i].modem_is_2g,
supported_band_mapping_tests[i].modem_is_3g,
supported_band_mapping_tests[i].modem_is_4g,
LOAD_SUPPORTED_BANDS,
&bands,
&error);
g_assert_no_error (error);
g_assert (res);
for (j = 0; j < supported_band_mapping_tests[i].mm_bands_len; j++) {
MMModemBand ref;
MMModemBand cur;
ref = supported_band_mapping_tests[i].mm_bands[j];
cur = g_array_index (bands, MMModemBand, j);
g_assert_cmpint (cur, ==, ref);
}
g_assert_cmpint (bands->len, ==, supported_band_mapping_tests[i].mm_bands_len);
g_array_free (bands, TRUE);
bands = NULL;
}
cmd = mm_telit_build_bnd_request (bands_array,
modem_is_2g, modem_is_3g, modem_is_4g,
modem_alternate_3g_bands,
&error);
g_assert_no_error (error);
g_assert_cmpstr (cmd, ==, expected_cmd);
g_free (cmd);
}
static BNDResponseTest current_band_mapping_tests [] = {
{ "#BND: 0", TRUE, FALSE, FALSE, 2, { MM_MODEM_BAND_EGSM,
MM_MODEM_BAND_DCS
}
},
{ "#BND: 0,5", TRUE, TRUE, FALSE, 3, { MM_MODEM_BAND_EGSM,
MM_MODEM_BAND_DCS,
MM_MODEM_BAND_UTRAN_8
}
},
{ "#BND: 1,3", TRUE, TRUE, FALSE, 5, { MM_MODEM_BAND_EGSM,
MM_MODEM_BAND_PCS,
MM_MODEM_BAND_UTRAN_1,
MM_MODEM_BAND_UTRAN_2,
MM_MODEM_BAND_UTRAN_5,
}
},
{ "#BND: 2,7", TRUE, TRUE, FALSE, 3, { MM_MODEM_BAND_DCS,
MM_MODEM_BAND_G850,
MM_MODEM_BAND_UTRAN_4
}
},
{ "#BND: 3,0,1", TRUE, TRUE, TRUE, 4, { MM_MODEM_BAND_PCS,
MM_MODEM_BAND_G850,
MM_MODEM_BAND_UTRAN_1,
MM_MODEM_BAND_EUTRAN_1
}
},
{ "#BND: 0,0,3", TRUE, FALSE, TRUE, 4, { MM_MODEM_BAND_EGSM,
MM_MODEM_BAND_DCS,
MM_MODEM_BAND_EUTRAN_1,
MM_MODEM_BAND_EUTRAN_2
}
},
{ "#BND: 0,0,3", FALSE, FALSE, TRUE, 2, { MM_MODEM_BAND_EUTRAN_1,
MM_MODEM_BAND_EUTRAN_2
}
},
{ NULL, FALSE, FALSE, FALSE, 0, {}},
};
#define test_common_bnd_cmd_2g(EXPECTED_CMD, BANDS_ARRAY) test_common_bnd_cmd (EXPECTED_CMD, TRUE, FALSE, FALSE, FALSE, BANDS_ARRAY)
#define test_common_bnd_cmd_3g(EXPECTED_CMD, ALTERNATE, BANDS_ARRAY) test_common_bnd_cmd (EXPECTED_CMD, FALSE, TRUE, FALSE, ALTERNATE, BANDS_ARRAY)
#define test_common_bnd_cmd_4g(EXPECTED_CMD, BANDS_ARRAY) test_common_bnd_cmd (EXPECTED_CMD, FALSE, FALSE, TRUE, FALSE, BANDS_ARRAY)
static void
test_parse_current_bands_response (void) {
GError* error = NULL;
gboolean res = FALSE;
guint i, j;
GArray* bands = NULL;
test_common_bnd_cmd_invalid (gboolean modem_is_2g,
gboolean modem_is_3g,
gboolean modem_is_4g,
GArray *bands_array)
{
gchar *cmd;
GError *error = NULL;
for (i = 0; current_band_mapping_tests[i].response != NULL; i++) {
res = mm_telit_parse_bnd_response (current_band_mapping_tests[i].response,
current_band_mapping_tests[i].modem_is_2g,
current_band_mapping_tests[i].modem_is_3g,
current_band_mapping_tests[i].modem_is_4g,
LOAD_CURRENT_BANDS,
&bands,
&error);
g_assert_no_error (error);
g_assert (res);
for (j = 0; j < current_band_mapping_tests[i].mm_bands_len; j++) {
MMModemBand ref;
MMModemBand cur;
ref = current_band_mapping_tests[i].mm_bands[j];
cur = g_array_index (bands, MMModemBand, j);
g_assert_cmpint (cur, ==, ref);
}
g_assert_cmpint (bands->len, ==, current_band_mapping_tests[i].mm_bands_len);
g_array_free (bands, TRUE);
bands = NULL;
}
cmd = mm_telit_build_bnd_request (bands_array,
modem_is_2g, modem_is_3g, modem_is_4g,
FALSE,
&error);
g_assert_error (error, MM_CORE_ERROR, MM_CORE_ERROR_FAILED);
g_assert (!cmd);
}
#define test_common_bnd_cmd_2g_invalid(BANDS_ARRAY) test_common_bnd_cmd_invalid (TRUE, FALSE, FALSE, BANDS_ARRAY)
#define test_common_bnd_cmd_3g_invalid(BANDS_ARRAY) test_common_bnd_cmd_invalid (FALSE, TRUE, FALSE, BANDS_ARRAY)
#define test_common_bnd_cmd_4g_invalid(BANDS_ARRAY) test_common_bnd_cmd_invalid (FALSE, FALSE, TRUE, BANDS_ARRAY)
static void
test_telit_get_2g_bnd_flag (void)
{
GArray *bands_array;
gint flag2g;
MMModemBand egsm = MM_MODEM_BAND_EGSM;
MMModemBand dcs = MM_MODEM_BAND_DCS;
MMModemBand pcs = MM_MODEM_BAND_PCS;
MMModemBand g850 = MM_MODEM_BAND_G850;
GArray *bands_array;
MMModemBand egsm = MM_MODEM_BAND_EGSM;
MMModemBand dcs = MM_MODEM_BAND_DCS;
MMModemBand pcs = MM_MODEM_BAND_PCS;
MMModemBand g850 = MM_MODEM_BAND_G850;
/* Test Flag 0 */
bands_array = g_array_sized_new (FALSE, FALSE, sizeof (MMModemBand), 2);
g_array_append_val (bands_array, egsm);
g_array_append_val (bands_array, dcs);
mm_telit_get_band_flag (bands_array, &flag2g, NULL, NULL);
g_assert_cmpuint (flag2g, ==, 0);
g_array_free (bands_array, TRUE);
test_common_bnd_cmd_2g ("#BND=0", bands_array);
g_array_unref (bands_array);
/* Test flag 1 */
bands_array = g_array_sized_new (FALSE, FALSE, sizeof (MMModemBand), 2);
g_array_append_val (bands_array, egsm);
g_array_append_val (bands_array, pcs);
mm_telit_get_band_flag (bands_array, &flag2g, NULL, NULL);
g_assert_cmpuint (flag2g, ==, 1);
g_array_free (bands_array, TRUE);
test_common_bnd_cmd_2g ("#BND=1", bands_array);
g_array_unref (bands_array);
/* Test flag 2 */
bands_array = g_array_sized_new (FALSE, FALSE, sizeof (MMModemBand), 2);
g_array_append_val (bands_array, g850);
g_array_append_val (bands_array, dcs);
mm_telit_get_band_flag (bands_array, &flag2g, NULL, NULL);
g_assert_cmpuint (flag2g, ==, 2);
g_array_free (bands_array, TRUE);
test_common_bnd_cmd_2g ("#BND=2", bands_array);
g_array_unref (bands_array);
/* Test flag 3 */
bands_array = g_array_sized_new (FALSE, FALSE, sizeof (MMModemBand), 2);
g_array_append_val (bands_array, g850);
g_array_append_val (bands_array, pcs);
mm_telit_get_band_flag (bands_array, &flag2g, NULL, NULL);
g_assert_cmpuint (flag2g, ==, 3);
g_array_free (bands_array, TRUE);
test_common_bnd_cmd_2g ("#BND=3", bands_array);
g_array_unref (bands_array);
/* Test invalid band array */
bands_array = g_array_sized_new (FALSE, FALSE, sizeof (MMModemBand), 2);
g_array_append_val (bands_array, g850);
g_array_append_val (bands_array, egsm);
mm_telit_get_band_flag (bands_array, &flag2g, NULL, NULL);
g_assert_cmpuint (flag2g, ==, -1);
g_array_free (bands_array, TRUE);
test_common_bnd_cmd_2g_invalid (bands_array);
g_array_unref (bands_array);
}
static void
test_telit_get_3g_bnd_flag (void)
{
GArray *bands_array;
MMModemBand u2100 = MM_MODEM_BAND_UTRAN_1;
MMModemBand u1900 = MM_MODEM_BAND_UTRAN_2;
MMModemBand u850 = MM_MODEM_BAND_UTRAN_5;
MMModemBand u900 = MM_MODEM_BAND_UTRAN_8;
MMModemBand u17iv = MM_MODEM_BAND_UTRAN_4;
MMModemBand u17ix = MM_MODEM_BAND_UTRAN_9;
gint flag;
GArray *bands_array;
MMModemBand u2100 = MM_MODEM_BAND_UTRAN_1;
MMModemBand u1900 = MM_MODEM_BAND_UTRAN_2;
MMModemBand u1800 = MM_MODEM_BAND_UTRAN_3;
MMModemBand u850 = MM_MODEM_BAND_UTRAN_5;
MMModemBand u800 = MM_MODEM_BAND_UTRAN_6;
MMModemBand u900 = MM_MODEM_BAND_UTRAN_8;
MMModemBand u17iv = MM_MODEM_BAND_UTRAN_4;
MMModemBand u17ix = MM_MODEM_BAND_UTRAN_9;
/* Test flag 0 */
flag = -1;
bands_array = g_array_sized_new (FALSE, FALSE, sizeof (MMModemBand), 1);
g_array_append_val (bands_array, u2100);
mm_telit_get_band_flag (bands_array, NULL, &flag, NULL);
g_assert_cmpint (flag, ==, 0);
g_array_free (bands_array, TRUE);
test_common_bnd_cmd_3g ("#BND=0,0", FALSE, bands_array);
test_common_bnd_cmd_3g ("#BND=0,0", TRUE, bands_array);
g_array_unref (bands_array);
/* Test flag 1 */
flag = -1;
bands_array = g_array_sized_new (FALSE, FALSE, sizeof (MMModemBand), 1);
g_array_append_val (bands_array, u1900);
mm_telit_get_band_flag (bands_array, NULL, &flag, NULL);
g_assert_cmpint (flag, ==, 1);
g_array_free (bands_array, TRUE);
test_common_bnd_cmd_3g ("#BND=0,1", FALSE, bands_array);
test_common_bnd_cmd_3g ("#BND=0,1", TRUE, bands_array);
g_array_unref (bands_array);
/* Test flag 2 */
flag = -1;
bands_array = g_array_sized_new (FALSE, FALSE, sizeof (MMModemBand), 1);
g_array_append_val (bands_array, u850);
mm_telit_get_band_flag (bands_array, NULL, &flag, NULL);
g_assert_cmpint (flag, ==, 2);
g_array_free (bands_array, TRUE);
test_common_bnd_cmd_3g ("#BND=0,2", FALSE, bands_array);
test_common_bnd_cmd_3g ("#BND=0,2", TRUE, bands_array);
g_array_unref (bands_array);
/* Test flag 3 */
flag = -1;
bands_array = g_array_sized_new (FALSE, FALSE, sizeof (MMModemBand), 3);
g_array_append_val (bands_array, u2100);
g_array_append_val (bands_array, u1900);
g_array_append_val (bands_array, u850);
mm_telit_get_band_flag (bands_array, NULL, &flag, NULL);
g_assert_cmpint (flag, ==, 3);
g_array_free (bands_array, TRUE);
test_common_bnd_cmd_3g ("#BND=0,3", FALSE, bands_array);
test_common_bnd_cmd_3g ("#BND=0,3", TRUE, bands_array);
g_array_unref (bands_array);
/* Test flag 4 */
flag = -1;
bands_array = g_array_sized_new (FALSE, FALSE, sizeof (MMModemBand), 2);
g_array_append_val (bands_array, u1900);
g_array_append_val (bands_array, u850);
mm_telit_get_band_flag (bands_array, NULL, &flag, NULL);
g_assert_cmpint (flag, ==, 4);
g_array_free (bands_array, TRUE);
test_common_bnd_cmd_3g ("#BND=0,4", FALSE, bands_array);
test_common_bnd_cmd_3g ("#BND=0,4", TRUE, bands_array);
g_array_unref (bands_array);
/* Test flag 5 */
flag = -1;
bands_array = g_array_sized_new (FALSE, FALSE, sizeof (MMModemBand), 1);
g_array_append_val (bands_array, u900);
mm_telit_get_band_flag (bands_array, NULL, &flag, NULL);
g_assert_cmpint (flag, ==, 5);
g_array_free (bands_array, TRUE);
test_common_bnd_cmd_3g ("#BND=0,5", FALSE, bands_array);
test_common_bnd_cmd_3g ("#BND=0,5", TRUE, bands_array);
g_array_unref (bands_array);
/* Test flag 6 */
flag = -1;
bands_array = g_array_sized_new (FALSE, FALSE, sizeof (MMModemBand), 2);
g_array_append_val (bands_array, u2100);
g_array_append_val (bands_array, u900);
mm_telit_get_band_flag (bands_array, NULL, &flag, NULL);
g_assert_cmpint (flag, ==, 6);
g_array_free (bands_array, TRUE);
test_common_bnd_cmd_3g ("#BND=0,6", FALSE, bands_array);
test_common_bnd_cmd_3g ("#BND=0,6", TRUE, bands_array);
g_array_unref (bands_array);
/* Test flag 7 */
flag = -1;
bands_array = g_array_sized_new (FALSE, FALSE, sizeof (MMModemBand), 1);
g_array_append_val (bands_array, u17iv);
test_common_bnd_cmd_3g ("#BND=0,7", FALSE, bands_array);
test_common_bnd_cmd_3g ("#BND=0,7", TRUE, bands_array);
g_array_unref (bands_array);
mm_telit_get_band_flag (bands_array, NULL, &flag, NULL);
g_assert_cmpint (flag, ==, 7);
g_array_free (bands_array, TRUE);
/* Test flag 12 in default */
bands_array = g_array_sized_new (FALSE, FALSE, sizeof (MMModemBand), 1);
g_array_append_val (bands_array, u800);
test_common_bnd_cmd_3g ("#BND=0,12", FALSE, bands_array);
g_array_unref (bands_array);
/* Test flag 12 in alternate */
bands_array = g_array_sized_new (FALSE, FALSE, sizeof (MMModemBand), 4);
g_array_append_val (bands_array, u2100);
g_array_append_val (bands_array, u1800);
g_array_append_val (bands_array, u850);
g_array_append_val (bands_array, u900);
test_common_bnd_cmd_3g ("#BND=0,12", TRUE, bands_array);
g_array_unref (bands_array);
/* Test invalid band array */
flag = -1;
bands_array = g_array_sized_new (FALSE, FALSE, sizeof (MMModemBand), 1);
g_array_append_val (bands_array, u17ix);
mm_telit_get_band_flag (bands_array, NULL, &flag, NULL);
g_assert_cmpint (flag, ==, -1);
g_array_free (bands_array, TRUE);
test_common_bnd_cmd_3g_invalid (bands_array);
g_array_unref (bands_array);
}
static void
test_telit_get_4g_bnd_flag (void)
{
GArray *bands_array;
MMModemBand eutran_i = MM_MODEM_BAND_EUTRAN_1;
MMModemBand eutran_ii = MM_MODEM_BAND_EUTRAN_2;
MMModemBand egsm = MM_MODEM_BAND_EGSM;
gint flag = -1;
GArray *bands_array;
MMModemBand eutran_i = MM_MODEM_BAND_EUTRAN_1;
MMModemBand eutran_ii = MM_MODEM_BAND_EUTRAN_2;
MMModemBand egsm = MM_MODEM_BAND_EGSM;
/* Test flag 1 */
bands_array = g_array_sized_new (FALSE, FALSE, sizeof (MMModemBand), 1);
g_array_append_val (bands_array, eutran_i);
mm_telit_get_band_flag (bands_array, NULL, NULL, &flag);
g_assert_cmpint (flag, ==, 1);
g_array_free (bands_array, TRUE);
test_common_bnd_cmd_4g ("#BND=0,0,1", bands_array);
g_array_unref (bands_array);
/* Test flag 3 */
bands_array = g_array_sized_new (FALSE, FALSE, sizeof (MMModemBand), 2);
g_array_append_val (bands_array, eutran_i);
g_array_append_val (bands_array, eutran_ii);
mm_telit_get_band_flag (bands_array, NULL, NULL, &flag);
g_assert_cmpint (flag, ==, 3);
g_array_free (bands_array, TRUE);
test_common_bnd_cmd_4g ("#BND=0,0,3", bands_array);
g_array_unref (bands_array);
/* Test invalid bands array */
bands_array = g_array_sized_new (FALSE, FALSE, sizeof (MMModemBand), 1);
g_array_append_val (bands_array, egsm);
mm_telit_get_band_flag (bands_array, NULL, NULL, &flag);
g_assert_cmpint (flag, ==, -1);
g_array_free (bands_array, TRUE);
test_common_bnd_cmd_4g_invalid (bands_array);
g_array_unref (bands_array);
}
/******************************************************************************/
typedef struct {
const char* response;
MMTelitQssStatus expected_qss;
@@ -483,14 +544,34 @@ test_telit_parse_qss_query (void)
}
}
/******************************************************************************/
void
_mm_log (const char *loc,
const char *func,
guint32 level,
const char *fmt,
...)
{
#if defined ENABLE_TEST_MESSAGE_TRACES
/* Dummy log function */
va_list args;
gchar *msg;
va_start (args, fmt);
msg = g_strdup_vprintf (fmt, args);
va_end (args);
g_print ("%s\n", msg);
g_free (msg);
#endif
}
int main (int argc, char **argv)
{
setlocale (LC_ALL, "");
g_test_init (&argc, &argv, NULL);
g_test_add_func ("/MM/telit/bands/supported/bands_contains", test_mm_bands_contains);
g_test_add_func ("/MM/telit/bands/supported/parse_band_flag", test_parse_band_flag_str);
g_test_add_func ("/MM/telit/bands/supported/parse_bands_response", test_parse_supported_bands_response);
g_test_add_func ("/MM/telit/bands/current/parse_bands_response", test_parse_current_bands_response);
g_test_add_func ("/MM/telit/bands/current/set_bands/2g", test_telit_get_2g_bnd_flag);