aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--libmm-glib/mm-common-helpers.c14
-rw-r--r--libmm-glib/mm-common-helpers.h5
-rw-r--r--plugins/Makefile.am6
-rw-r--r--plugins/telit/77-mm-telit-port-types.rules6
-rw-r--r--plugins/telit/mm-broadband-modem-mbim-telit.c4
-rw-r--r--plugins/telit/mm-broadband-modem-telit.c4
-rw-r--r--plugins/telit/mm-modem-helpers-telit.c820
-rw-r--r--plugins/telit/mm-modem-helpers-telit.h98
-rw-r--r--plugins/telit/mm-shared-telit.c301
-rw-r--r--plugins/telit/mm-shared-telit.h10
-rw-r--r--plugins/telit/tests/test-mm-modem-helpers-telit.c675
11 files changed, 1061 insertions, 882 deletions
diff --git a/libmm-glib/mm-common-helpers.c b/libmm-glib/mm-common-helpers.c
index a3cd16ab..8673421d 100644
--- a/libmm-glib/mm-common-helpers.c
+++ b/libmm-glib/mm-common-helpers.c
@@ -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)
{
diff --git a/libmm-glib/mm-common-helpers.h b/libmm-glib/mm-common-helpers.h
index 71ef978a..5af58422 100644
--- a/libmm-glib/mm-common-helpers.h
+++ b/libmm-glib/mm-common-helpers.h
@@ -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);
diff --git a/plugins/Makefile.am b/plugins/Makefile.am
index d3242e0a..dd66d2f1 100644
--- a/plugins/Makefile.am
+++ b/plugins/Makefile.am
@@ -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 \
diff --git a/plugins/telit/77-mm-telit-port-types.rules b/plugins/telit/77-mm-telit-port-types.rules
index 4d48aa44..6ec5a7e7 100644
--- a/plugins/telit/77-mm-telit-port-types.rules
+++ b/plugins/telit/77-mm-telit-port-types.rules
@@ -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"
diff --git a/plugins/telit/mm-broadband-modem-mbim-telit.c b/plugins/telit/mm-broadband-modem-mbim-telit.c
index d4a80951..43bce7fa 100644
--- a/plugins/telit/mm-broadband-modem-mbim-telit.c
+++ b/plugins/telit/mm-broadband-modem-mbim-telit.c
@@ -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;
diff --git a/plugins/telit/mm-broadband-modem-telit.c b/plugins/telit/mm-broadband-modem-telit.c
index 29f4b136..d6b1ea2d 100644
--- a/plugins/telit/mm-broadband-modem-telit.c
+++ b/plugins/telit/mm-broadband-modem-telit.c
@@ -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;
diff --git a/plugins/telit/mm-modem-helpers-telit.c b/plugins/telit/mm-modem-helpers-telit.c
index c162964d..e4bacc5b 100644
--- a/plugins/telit/mm-modem-helpers-telit.c
+++ b/plugins/telit/mm-modem-helpers-telit.c
@@ -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,114 +27,298 @@
#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);
-
- 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;
+ MMModemBand band;
+
+ 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;
- /* 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 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;
}
-
- /* 4G flag correspond to the mask */
- if (flag4g != NULL) {
- if (found4g)
- *flag4g = mask4g;
- else
- *flag4g = -1;
+ 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;
}
-}
-#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+))?"
+ 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 ();
+
+ return cmd;
+}
/*****************************************************************************/
/* #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;
- }
-
- if (!g_regex_match (r, response, 0, &match_info)) {
- g_set_error (error, MM_CORE_ERROR, MM_CORE_ERROR_FAILED,
- "Could not parse response '%s'", response);
- goto end;
- }
-
- if (!g_match_info_matches (match_info)) {
- g_set_error (error, MM_CORE_ERROR, MM_CORE_ERROR_FAILED,
- "Could not find matches in response '%s'", response);
- goto end;
- }
-
- 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_3g && !mm_telit_get_3g_mm_bands (match_info, &bands, error))
- goto end;
-
- 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);
-
- g_match_info_free (match_info);
- g_regex_unref (r);
-
- return ret;
-}
-
-gboolean
-mm_telit_get_2g_mm_bands (GMatchInfo *match_info,
- GArray **bands,
- GError **error)
+static gboolean
+telit_get_2g_mm_bands (GMatchInfo *match_info,
+ GArray **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, {}},
- };
+ 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 == 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;
+ 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;
}
- flags = g_array_new (FALSE, FALSE, sizeof (guint));
+ values = mm_parse_uint_list (match_str, &inner_error);
+ if (!values)
+ goto out;
- if (!mm_telit_get_band_flags_from_string (match_str, &flags, error)) {
- ret = FALSE;
- goto end;
- }
+ for (i = 0; i < values->len; i++) {
+ guint value;
- for (i = 0; i < flags->len; i++) {
- guint flag;
+ value = g_array_index (values, guint, i);
+ if (value < G_N_ELEMENTS (telit_2g_to_mm_band_mask)) {
+ guint j;
- flag = g_array_index (flags, guint, i);
- if (!mm_telit_update_band_array (flag, map, bands, error)) {
- ret = FALSE;
- goto end;
- }
+ 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);
}
-end:
+out:
g_free (match_str);
+ g_clear_pointer (&values, g_array_unref);
- if (flags != NULL)
- g_array_free (flags, TRUE);
-
- return ret;
+ if (inner_error) {
+ g_propagate_error (error, inner_error);
+ return FALSE;
+ }
+ return TRUE;
}
-gboolean
-mm_telit_get_3g_mm_bands (GMatchInfo *match_info,
- GArray **bands,
- GError **error)
+static gboolean
+telit_get_3g_mm_bands (GMatchInfo *match_info,
+ GArray **bands,
+ 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, {}},
- };
+ 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 == 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;
+ 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;
}
- flags = g_array_new (FALSE, FALSE, sizeof (guint));
+ values = mm_parse_uint_list (match_str, &inner_error);
+ if (!values)
+ goto out;
- if (!mm_telit_get_band_flags_from_string (match_str, &flags, error)) {
- ret = FALSE;
- goto end;
- }
+ for (i = 0; i < values->len; i++) {
+ guint value;
- for (i = 0; i < flags->len; i++) {
- guint flag;
+ value = g_array_index (values, guint, i);
- flag = g_array_index (flags, guint, i);
- if (!mm_telit_update_band_array (flag, map, bands, error)) {
- ret = FALSE;
- goto end;
- }
+ 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);
}
-end:
+out:
g_free (match_str);
+ g_clear_pointer (&values, g_array_unref);
- if (flags != NULL)
- g_array_free (flags, TRUE);
-
- return ret;
+ if (inner_error) {
+ g_propagate_error (error, inner_error);
+ return FALSE;
+ }
+ return TRUE;
}
-gboolean
-mm_telit_get_4g_mm_bands (GMatchInfo *match_info,
- GArray **bands,
- GError **error)
+static gboolean
+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;
+ 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 == NULL || match_str[0] == '\0') {
- g_set_error (error, MM_CORE_ERROR, MM_CORE_ERROR_FAILED,
+ 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");
- ret = FALSE;
- goto end;
+ goto out;
}
- 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);
+ /* 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 (i = 0; value > 0; i++) {
- if (value % 2 != 0) {
- band = MM_MODEM_BAND_EUTRAN_1 + i;
+ 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);
- }
- value = value >> 1;
}
-end:
+out:
+ g_strfreev (tokens);
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;
+ if (inner_error) {
+ g_propagate_error (error, inner_error);
+ return FALSE;
}
-
- return FALSE;
+ return TRUE;
}
-gboolean
-mm_telit_update_band_array (const gint bands_flag,
- const TelitToMMBandMap *map,
- GArray **bands,
- GError **error)
+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)
{
- 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;
-}
+ 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+))?",
+ };
-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;
+ r = g_regex_new (load_bands_regex[load_type], G_REGEX_RAW, 0, NULL);
+ g_assert (r);
- 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;
+ if (!g_regex_match (r, response, 0, &match_info)) {
+ g_set_error (&inner_error, MM_CORE_ERROR, MM_CORE_ERROR_FAILED,
+ "Could not parse response '%s'", response);
+ goto out;
}
- 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;
+ if (!g_match_info_matches (match_info)) {
+ g_set_error (&inner_error, MM_CORE_ERROR, MM_CORE_ERROR_FAILED,
+ "Could not find matches in response '%s'", response);
+ goto out;
}
- 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;
+ bands = g_array_new (TRUE, TRUE, sizeof (MMModemBand));
- range = g_strsplit (tokens[i], "-", 2);
+ if (modem_is_2g && !telit_get_2g_mm_bands (match_info, &bands, &inner_error))
+ goto out;
- sscanf (range[0], "%d", &range_start);
- sscanf (range[1], "%d", &range_end);
+ if (modem_is_3g && !telit_get_3g_mm_bands (match_info, &bands, modem_alternate_3g_bands, &inner_error))
+ goto out;
- for (flag = range_start; flag <= range_end; flag++) {
- g_array_append_val (*band_flags, flag);
- }
+ if (modem_is_4g && !telit_get_4g_mm_bands (match_info, &bands, &inner_error))
+ goto out;
- g_strfreev (range);
- }
+out:
+ g_match_info_free (match_info);
+ g_regex_unref (r);
+
+ if (inner_error) {
+ g_propagate_error (error, inner_error);
+ g_clear_pointer (&bands, g_array_unref);
+ return NULL;
}
- g_strfreev (tokens);
+ return bands;
+}
- return TRUE;
+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)
+{
+ return common_parse_bnd_response (response,
+ modem_is_2g, modem_is_3g, modem_is_4g,
+ modem_alternate_3g_bands,
+ LOAD_BANDS_TYPE_CURRENT,
+ 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)
+{
+ return common_parse_bnd_response (response,
+ modem_is_2g, modem_is_3g, modem_is_4g,
+ modem_alternate_3g_bands,
+ LOAD_BANDS_TYPE_SUPPORTED,
+ error);
}
/*****************************************************************************/
diff --git a/plugins/telit/mm-modem-helpers-telit.h b/plugins/telit/mm-modem-helpers-telit.h
index 0b82c42d..491e8fa6 100644
--- a/plugins/telit/mm-modem-helpers-telit.h
+++ b/plugins/telit/mm-modem-helpers-telit.h
@@ -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 >*/
diff --git a/plugins/telit/mm-shared-telit.c b/plugins/telit/mm-shared-telit.c
index c79f7ff0..f1eb0518 100644
--- a/plugins/telit/mm-shared-telit.c
+++ b/plugins/telit/mm-shared-telit.c
@@ -32,6 +32,59 @@
#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) */
gboolean
@@ -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;
- ctx = g_task_get_task_data (task);
- response = mm_base_modem_at_command_finish (self, res, &error);
+ 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 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);
}
-void
-mm_shared_telit_modem_load_current_bands (MMIfaceModem *self,
- GAsyncReadyCallback callback,
- gpointer user_data)
+static void
+mm_shared_telit_load_current_bands_ready (MMBaseModem *self,
+ GAsyncResult *res,
+ GTask *task)
{
- GTask *task;
- LoadBandsContext *ctx;
+ const gchar *response;
+ GError *error = NULL;
+ Private *priv;
- ctx = g_slice_new0 (LoadBandsContext);
+ priv = get_private (MM_SHARED_TELIT (self));
- 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;
+ 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);
+ }
- task = g_task_new (self, NULL, callback, user_data);
- g_task_set_task_data (task, ctx, (GDestroyNotify)mm_shared_telit_load_bands_context_free);
+ g_object_unref (task);
+}
+void
+mm_shared_telit_modem_load_current_bands (MMIfaceModem *self,
+ GAsyncReadyCallback callback,
+ gpointer user_data)
+{
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;
-
- mm_telit_get_band_flag (bands_array, &flag2g, &flag3g, &flag4g);
+ GTask *task;
+ GError *error = NULL;
+ gchar *cmd;
+ Private *priv;
- is_2g = mm_iface_modem_is_2g (self);
- is_3g = mm_iface_modem_is_3g (self);
- is_4g = mm_iface_modem_is_4g (self);
+ priv = get_private (MM_SHARED_TELIT (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;
- }
+ task = g_task_new (self, NULL, callback, user_data);
- 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 (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;
}
- 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");
+ 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;
}
- 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);
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);
}
diff --git a/plugins/telit/mm-shared-telit.h b/plugins/telit/mm-shared-telit.h
index 2eb6d515..4cfaeb51 100644
--- a/plugins/telit/mm-shared-telit.h
+++ b/plugins/telit/mm-shared-telit.h
@@ -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);
diff --git a/plugins/telit/tests/test-mm-modem-helpers-telit.c b/plugins/telit/tests/test-mm-modem-helpers-telit.c
index 6103a2c9..f95a97d2 100644
--- a/plugins/telit/tests/test-mm-modem-helpers-telit.c
+++ b/plugins/telit/tests/test-mm-modem-helpers-telit.c
@@ -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;
-
- mm_bands = g_array_sized_new (FALSE, TRUE, sizeof (MMModemBand), 3);
-
- for (i = 0; i < 3; i++)
- g_array_append_val (mm_bands, i);
+#include "test-helpers.h"
- 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;
-
-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 void
-test_parse_band_flag_str (void) {
- GError *error = NULL;
- gboolean res = FALSE;
- GArray *band_flags = NULL;
- guint i, j;
-
- 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,
- &error);
- g_assert_no_error (error);
- g_assert (res);
-
- 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);
+ 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 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 }
}
-}
-
-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;
-
- 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);
-
+test_parse_supported_bands_response (void)
+{
+ guint i;
- for (j = 0; j < supported_band_mapping_tests[i].mm_bands_len; j++) {
- MMModemBand ref;
- MMModemBand cur;
+ for (i = 0; i < G_N_ELEMENTS (supported_band_mapping_tests); i++) {
+ GError *error = NULL;
+ GArray *bands = NULL;
- 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);
+ 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);
- g_array_free (bands, TRUE);
- bands = NULL;
+ 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, 2, { MM_MODEM_BAND_EGSM,
- MM_MODEM_BAND_DCS
- }
+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: 0,5", TRUE, TRUE, FALSE, 3, { MM_MODEM_BAND_EGSM,
- MM_MODEM_BAND_DCS,
- MM_MODEM_BAND_UTRAN_8
- }
+ {
+ "#BND: 2,7", TRUE, TRUE, FALSE, FALSE, 3,
+ { MM_MODEM_BAND_DCS,
+ MM_MODEM_BAND_G850,
+ MM_MODEM_BAND_UTRAN_4 }
},
- { "#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: 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: 2,7", TRUE, TRUE, FALSE, 3, { MM_MODEM_BAND_DCS,
- MM_MODEM_BAND_G850,
- MM_MODEM_BAND_UTRAN_4
- }
+ {
+ "#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: 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", FALSE, FALSE, TRUE, FALSE, 2,
+ { MM_MODEM_BAND_EUTRAN_1,
+ MM_MODEM_BAND_EUTRAN_2 }
},
- { "#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
- }
+ /* 3G alternate band settings: default */
+ {
+ "#BND: 0,12", FALSE, TRUE, FALSE, FALSE, 1,
+ { MM_MODEM_BAND_UTRAN_6 }
},
- { "#BND: 0,0,3", FALSE, FALSE, TRUE, 2, { MM_MODEM_BAND_EUTRAN_1,
- MM_MODEM_BAND_EUTRAN_2
- }
+ /* 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 }
},
- { NULL, FALSE, FALSE, FALSE, 0, {}},
+ /* 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) {
- GError* error = NULL;
- gboolean res = FALSE;
- guint i, j;
- GArray* bands = 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);
+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);
+ 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);
+ }
+}
- 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);
- }
+static void
+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;
- g_assert_cmpint (bands->len, ==, current_band_mapping_tests[i].mm_bands_len);
+ 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);
+}
- g_array_free (bands, TRUE);
- bands = NULL;
- }
+#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_common_bnd_cmd_invalid (gboolean modem_is_2g,
+ gboolean modem_is_3g,
+ gboolean modem_is_4g,
+ GArray *bands_array)
+{
+ gchar *cmd;
+ GError *error = 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);