aboutsummaryrefslogtreecommitdiff
path: root/plugins/telit/mm-modem-helpers-telit.c
diff options
context:
space:
mode:
Diffstat (limited to 'plugins/telit/mm-modem-helpers-telit.c')
-rw-r--r--plugins/telit/mm-modem-helpers-telit.c820
1 files changed, 463 insertions, 357 deletions
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);
}
/*****************************************************************************/