diff options
Diffstat (limited to 'plugins/telit/mm-modem-helpers-telit.c')
-rw-r--r-- | plugins/telit/mm-modem-helpers-telit.c | 179 |
1 files changed, 159 insertions, 20 deletions
diff --git a/plugins/telit/mm-modem-helpers-telit.c b/plugins/telit/mm-modem-helpers-telit.c index b0d843b5..1d6b5194 100644 --- a/plugins/telit/mm-modem-helpers-telit.c +++ b/plugins/telit/mm-modem-helpers-telit.c @@ -182,10 +182,15 @@ initialize_telit_3g_to_mm_band_masks (void) */ #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 MM_MODEM_BAND_TELIT_4G_LAST MM_MODEM_BAND_EUTRAN_64 #define B4G_FLAG(band) (((guint64) 1) << (band - MM_MODEM_BAND_TELIT_4G_FIRST)) +#define MM_MODEM_BAND_TELIT_EXT_4G_FIRST MM_MODEM_BAND_EUTRAN_65 +#define MM_MODEM_BAND_TELIT_EXT_4G_LAST MM_MODEM_BAND_EUTRAN_71 + +#define B4G_FLAG_EXT(band) (((guint64) 1) << (band - MM_MODEM_BAND_TELIT_EXT_4G_FIRST)) + /*****************************************************************************/ /* Set current bands helpers */ @@ -195,11 +200,13 @@ mm_telit_build_bnd_request (GArray *bands_array, gboolean modem_is_3g, gboolean modem_is_4g, gboolean modem_alternate_3g_bands, + gboolean modem_ext_4g_bands, GError **error) { guint32 mask2g = 0; guint64 mask3g = 0; guint64 mask4g = 0; + guint64 mask4gext = 0; guint i; gint flag2g = -1; gint64 flag3g = -1; @@ -237,9 +244,12 @@ mm_telit_build_bnd_request (GArray *bands_array, /* Convert 4G bands into a bitmask. We use a 64bit explicit bitmask so that * all values fit correctly. */ - if (modem_is_4g && mm_common_band_is_eutran (band) && - (band >= MM_MODEM_BAND_TELIT_4G_FIRST && band <= MM_MODEM_BAND_TELIT_4G_LAST)) - mask4g += B4G_FLAG (band); + if (modem_is_4g && mm_common_band_is_eutran (band)) { + if (band >= MM_MODEM_BAND_TELIT_4G_FIRST && band <= MM_MODEM_BAND_TELIT_4G_LAST) + mask4g += B4G_FLAG (band); + else if (band >= MM_MODEM_BAND_TELIT_EXT_4G_FIRST && band <= MM_MODEM_BAND_TELIT_EXT_4G_LAST) + mask4gext += B4G_FLAG_EXT (band); + } } /* Get 2G-specific telit value */ @@ -295,7 +305,7 @@ mm_telit_build_bnd_request (GArray *bands_array, "None or invalid 3G bands combination in the provided list"); return NULL; } - if (modem_is_4g && flag4g == -1) { + if (modem_is_4g && mask4g == 0 && mask4gext == 0) { g_set_error (error, MM_CORE_ERROR, MM_CORE_ERROR_NOT_FOUND, "None or invalid 4G bands combination in the provided list"); return NULL; @@ -305,17 +315,29 @@ mm_telit_build_bnd_request (GArray *bands_array, cmd = g_strdup_printf ("#BND=%d", flag2g); else if (!modem_is_2g && modem_is_3g && !modem_is_4g) cmd = g_strdup_printf ("#BND=0,%" G_GINT64_FORMAT, flag3g); - else if (!modem_is_2g && !modem_is_3g && modem_is_4g) - cmd = g_strdup_printf ("#BND=0,0,%" G_GINT64_FORMAT, flag4g); else if (modem_is_2g && modem_is_3g && !modem_is_4g) cmd = g_strdup_printf ("#BND=%d,%" G_GINT64_FORMAT, flag2g, flag3g); - else if (!modem_is_2g && modem_is_3g && modem_is_4g) - cmd = g_strdup_printf ("#BND=0,%" G_GINT64_FORMAT ",%" G_GINT64_FORMAT, flag3g, flag4g); - else if (modem_is_2g && !modem_is_3g && modem_is_4g) - cmd = g_strdup_printf ("#BND=%d,0,%" G_GINT64_FORMAT, flag2g, flag4g); - else if (modem_is_2g && modem_is_3g && modem_is_4g) - cmd = g_strdup_printf ("#BND=%d,%" G_GINT64_FORMAT ",%" G_GINT64_FORMAT, flag2g, flag3g, flag4g); - else + else if (!modem_is_2g && !modem_is_3g && modem_is_4g) { + if (!modem_ext_4g_bands) + cmd = g_strdup_printf ("#BND=0,0,%" G_GINT64_FORMAT, flag4g); + else + cmd = g_strdup_printf ("#BND=0,0,%" G_GINT64_MODIFIER "x" ",%" G_GINT64_MODIFIER "x", mask4g, mask4gext); + } else if (!modem_is_2g && modem_is_3g && modem_is_4g) { + if (!modem_ext_4g_bands) + cmd = g_strdup_printf ("#BND=0,%" G_GINT64_FORMAT ",%" G_GINT64_FORMAT, flag3g, flag4g); + else + cmd = g_strdup_printf ("#BND=0,%" G_GINT64_FORMAT ",%" G_GINT64_MODIFIER "x" ",%" G_GINT64_MODIFIER "x", flag3g, mask4g, mask4gext); + } else if (modem_is_2g && !modem_is_3g && modem_is_4g) { + if (!modem_ext_4g_bands) + cmd = g_strdup_printf ("#BND=%d,0,%" G_GINT64_FORMAT, flag2g, flag4g); + else + cmd = g_strdup_printf ("#BND=%d,0,%" G_GINT64_MODIFIER "x" ",%" G_GINT64_MODIFIER "x", flag2g, mask4g, mask4gext); + } else if (modem_is_2g && modem_is_3g && modem_is_4g) { + if (!modem_ext_4g_bands) + cmd = g_strdup_printf ("#BND=%d,%" G_GINT64_FORMAT ",%" G_GINT64_FORMAT, flag2g, flag3g, flag4g); + else + cmd = g_strdup_printf ("#BND=%d,%" G_GINT64_FORMAT ",%" G_GINT64_MODIFIER "x" ",%" G_GINT64_MODIFIER "x", flag2g, flag3g, mask4g, mask4gext); + } else g_assert_not_reached (); return cmd; @@ -371,6 +393,49 @@ mm_telit_build_bnd_request (GArray *bands_array, * 0 = 2G band flag 0 is EGSM + DCS * 4 = 3G band flag 4 is U1900 + U850 * + * ---------------- + * + * For modems such as LN920 the #BND configuration/response for LTE bands is different + * from what is explained above: + * + * AT#BND=<GSM_band>[,<UMTS_band>[,<LTE_band>[,<LTE_band_ext>]]] + * + * <LTE_band>: hex: Indicates the LTE supported bands expressed as the sum of Band number (1+2+8 ...) calculated as shown in the table (mask of 64 bits): + * + * Band number(Hex) Band i + * 0 disable + * 1 B1 + * 2 B2 + * 4 B3 + * 8 B4 + * ... + * ... + * 80000000 B32 + * ... + * ... + * 800000000000 B48 + * + * It can take value, 0 - 87A03B0F38DF: range of the sum of Band number (1+2+4 ...) + * + * <LTE_band_ext>: hex: Indicates the LTE supported bands from B65 expressed as the sum of Band number (1+2+8 ...) calculated as shown in the table (mask of 64 bits): + * + * Band number(Hex) Band i + * 0 disable + * 2 B66 + * 40 B71 + * + * It can take value, 0 - 42: range of the sum of Band number (2+40) + * + * Note: LTE_band and LTE_band_ext cannot be 0 at the same time + * + * Example output: + * + * AT#BND=? + * #BND: (0),(0-11,17,18),(87A03B0F38DF),(42) + * + * AT#BND? + * #BND: 0,18,87A03B0F38DF,42 + * */ static gboolean @@ -532,6 +597,62 @@ out: return TRUE; } +static gboolean +telit_get_ext_4g_mm_bands (GMatchInfo *match_info, + GArray **bands, + GError **error) +{ + GError *inner_error = NULL; + MMModemBand band; + gchar *match_str = NULL; + gchar *match_str_ext = NULL; + guint64 value; + + match_str = g_match_info_fetch_named (match_info, "Bands4G"); + if (!match_str || match_str[0] == '\0') { + g_set_error (&inner_error, MM_CORE_ERROR, MM_CORE_ERROR_FAILED, + "Could not find 4G band hex mask flag from response"); + goto out; + } + + if (!mm_get_u64_from_hex_str (match_str, &value)) { + g_set_error (&inner_error, MM_CORE_ERROR, MM_CORE_ERROR_FAILED, + "Could not parse 4G band hex mask from string: '%s'", match_str); + goto out; + } + + for (band = MM_MODEM_BAND_TELIT_4G_FIRST; band <= MM_MODEM_BAND_TELIT_4G_LAST; band++) { + if ((value & B4G_FLAG (band)) && !mm_common_bands_garray_lookup (*bands, band)) + g_array_append_val (*bands, band); + } + + /* extended bands */ + match_str_ext = g_match_info_fetch_named (match_info, "Bands4GExt"); + if (match_str_ext) { + + if (!mm_get_u64_from_hex_str (match_str_ext, &value)) { + g_set_error (&inner_error, MM_CORE_ERROR, MM_CORE_ERROR_FAILED, + "Could not parse 4G ext band mask from string: '%s'", match_str_ext); + goto out; + } + + for (band = MM_MODEM_BAND_TELIT_EXT_4G_FIRST; band <= MM_MODEM_BAND_TELIT_EXT_4G_LAST; band++) { + if ((value & B4G_FLAG_EXT (band)) && !mm_common_bands_garray_lookup (*bands, band)) + g_array_append_val (*bands, band); + } + } + +out: + g_free (match_str); + g_free (match_str_ext); + + if (inner_error) { + g_propagate_error (error, inner_error); + return FALSE; + } + return TRUE; +} + typedef enum { LOAD_BANDS_TYPE_SUPPORTED, LOAD_BANDS_TYPE_CURRENT, @@ -543,6 +664,7 @@ common_parse_bnd_response (const gchar *response, gboolean modem_is_3g, gboolean modem_is_4g, gboolean modem_alternate_3g_bands, + gboolean modem_ext_4g_bands, LoadBandsType load_type, gpointer log_object, GError **error) @@ -552,12 +674,22 @@ common_parse_bnd_response (const gchar *response, 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+))?", - }; + if (!modem_ext_4g_bands) { + static const gchar *load_bands_regex[] = { + [LOAD_BANDS_TYPE_SUPPORTED] = "#BND:\\s*\\((?P<Bands2G>[0-9\\-,]*)\\)(,\\s*\\((?P<Bands3G>[0-9\\-,]*)\\))?(,\\s*\\((?P<Bands4G>[0-9\\-,]*)\\))?", + [LOAD_BANDS_TYPE_CURRENT] = "#BND:\\s*(?P<Bands2G>\\d+)(,\\s*(?P<Bands3G>\\d+))?(,\\s*(?P<Bands4G>\\d+))?", + }; + + r = g_regex_new (load_bands_regex[load_type], G_REGEX_RAW, 0, NULL); + } else { + static const gchar *load_bands_regex_hex[] = { + [LOAD_BANDS_TYPE_SUPPORTED] = "#BND:\\s*\\((?P<Bands2G>[0-9\\-,]*)\\)(,\\s*\\((?P<Bands3G>[0-9\\-,]*)\\))?(,\\s*\\((?P<Bands4G>[0-9A-F]+)\\))?(,\\s*\\((?P<Bands4GExt>[0-9A-F]+)\\))?", + [LOAD_BANDS_TYPE_CURRENT] = "#BND:\\s*(?P<Bands2G>\\d+)(,\\s*(?P<Bands3G>\\d+))?(,\\s*(?P<Bands4G>[0-9A-F]+))?(,\\s*(?P<Bands4GExt>[0-9A-F]+))?", + }; + + r = g_regex_new (load_bands_regex_hex[load_type], G_REGEX_RAW, 0, NULL); + } - r = g_regex_new (load_bands_regex[load_type], G_REGEX_RAW, 0, NULL); g_assert (r); if (!g_regex_match (r, response, 0, &match_info)) { @@ -580,7 +712,10 @@ common_parse_bnd_response (const gchar *response, if (modem_is_3g && !telit_get_3g_mm_bands (match_info, log_object, modem_alternate_3g_bands, &bands, &inner_error)) goto out; - if (modem_is_4g && !telit_get_4g_mm_bands (match_info, &bands, &inner_error)) + if (modem_is_4g && !modem_ext_4g_bands && !telit_get_4g_mm_bands (match_info, &bands, &inner_error)) + goto out; + + if (modem_is_4g && modem_ext_4g_bands && !telit_get_ext_4g_mm_bands (match_info, &bands, &inner_error)) goto out; out: @@ -602,12 +737,14 @@ mm_telit_parse_bnd_query_response (const gchar *response, gboolean modem_is_3g, gboolean modem_is_4g, gboolean modem_alternate_3g_bands, + gboolean modem_ext_4g_bands, gpointer log_object, GError **error) { return common_parse_bnd_response (response, modem_is_2g, modem_is_3g, modem_is_4g, modem_alternate_3g_bands, + modem_ext_4g_bands, LOAD_BANDS_TYPE_CURRENT, log_object, error); @@ -619,12 +756,14 @@ mm_telit_parse_bnd_test_response (const gchar *response, gboolean modem_is_3g, gboolean modem_is_4g, gboolean modem_alternate_3g_bands, + gboolean modem_ext_4g_bands, gpointer log_object, GError **error) { return common_parse_bnd_response (response, modem_is_2g, modem_is_3g, modem_is_4g, modem_alternate_3g_bands, + modem_ext_4g_bands, LOAD_BANDS_TYPE_SUPPORTED, log_object, error); |