[PATCH] [Telit plugin] add load_supported_bands interface

c.lobrano at gmail.com c.lobrano at gmail.com
Sat Jan 23 03:02:19 PST 2016


Hi,

sure, I'll fix what suggested and propose a new patch

thanks,
Carlo

On sab, gen 23, 2016 at 12:07 , Aleksander Morgado 
<aleksander at aleksander.es> wrote:
> On 18/01/16 14:30, Carlo Lobrano wrote:
>>  ---
>>   plugins/telit/77-mm-telit-port-types.rules        |   4 +
>>   plugins/telit/mm-broadband-modem-telit.c          |  86 +++++
>>   plugins/telit/mm-modem-helpers-telit.c            | 372 
>> +++++++++++++++++++++-
>>   plugins/telit/mm-modem-helpers-telit.h            |  58 ++++
>>   plugins/telit/tests/test-mm-modem-helpers-telit.c | 150 ++++++++-
>>   5 files changed, 666 insertions(+), 4 deletions(-)
>> 
>>  diff --git a/plugins/telit/77-mm-telit-port-types.rules 
>> b/plugins/telit/77-mm-telit-port-types.rules
>>  index 1efb0e1..b7aa70e 100644
>>  --- a/plugins/telit/77-mm-telit-port-types.rules
>>  +++ b/plugins/telit/77-mm-telit-port-types.rules
>>  @@ -44,6 +44,10 @@ ATTRS{idVendor}=="1bc7", 
>> ATTRS{idProduct}=="1011", ENV{ID_MM_TELIT_TAGGED}="1"
>>   # HE910, UE910, UL865 (dynamic port identification supported)
>>   ATTRS{idVendor}=="1bc7", ATTRS{idProduct}=="0021", 
>> ENV{ID_MM_TELIT_TAGGED}="1", ENV{ID_MM_TELIT_PORTS_TAGGED}="1"
>> 
>>  +# LE910 V2
>>  +ATTRS{idVendor}=="1bc7", ATTRS{idProduct}=="0036", 
>> ENV{ID_MM_TELIT_TAGGED}="1", ENV{ID_MM_TELIT_PORTS_TAGGED}="1"
>>  +
> 
> 
> Could this change go in a separate patch? Is it adding support for a
> fully new modem?
> 
> 
>>  +
>>   # NOTE: Qualcomm Gobi-based devices like the LE920 should not be 
>> handled
>>   # by this plugin, but by the Gobi plugin.
>> 
>>  diff --git a/plugins/telit/mm-broadband-modem-telit.c 
>> b/plugins/telit/mm-broadband-modem-telit.c
>>  index b4f481b..2e09ac7 100644
>>  --- a/plugins/telit/mm-broadband-modem-telit.c
>>  +++ b/plugins/telit/mm-broadband-modem-telit.c
>>  @@ -41,6 +41,90 @@ G_DEFINE_TYPE_EXTENDED (MMBroadbandModemTelit, 
>> mm_broadband_modem_telit, MM_TYPE
>>                           G_IMPLEMENT_INTERFACE 
>> (MM_TYPE_IFACE_MODEM_3GPP, iface_modem_3gpp_init));
>> 
>>   
>> /*****************************************************************************/
>>  +/* Load supported bands (Modem interface) */
>>  +typedef struct {
>>  +    MMIfaceModem *self;
>>  +    GSimpleAsyncResult *result;
>>  +    gboolean mm_modem_is_2g;
>>  +    gboolean mm_modem_is_3g;
>>  +    gboolean mm_modem_is_4g;
>>  +} LoadSupportedBandsContext;
>>  +
>>  +static void
>>  +load_supported_bands_context_complete_and_free 
>> (LoadSupportedBandsContext *ctx)
>>  +{
>>  +    g_simple_async_result_complete (ctx->result);
>>  +    g_object_unref (ctx->result);
>>  +    g_object_unref (ctx->self);
>>  +    g_slice_free (LoadSupportedBandsContext, ctx);
>>  +}
>>  +
>>  +static GArray *
>>  +modem_load_supported_bands_finish (MMIfaceModem *self,
>>  +                                   GAsyncResult *res,
>>  +                                   GError **error)
>>  +{
>>  +    if (g_simple_async_result_propagate_error 
>> (G_SIMPLE_ASYNC_RESULT (res), error))
>>  +        return NULL;
>>  +
>>  +    return (GArray *) g_array_ref 
>> (g_simple_async_result_get_op_res_gpointer (
>>  +                                       G_SIMPLE_ASYNC_RESULT 
>> (res)));
>>  +}
>>  +
>>  +static void
>>  +load_supported_bands_ready (MMBaseModem *self,
>>  +                            GAsyncResult *res,
>>  +                            LoadSupportedBandsContext *ctx)
>>  +{
>>  +    const gchar *response;
>>  +    GError *error = NULL;
>>  +    GArray *bands = NULL;
>>  +
>>  +    response = mm_base_modem_at_command_finish (MM_BASE_MODEM 
>> (self), res, &error);
>>  +
>>  +    if (!response)
>>  +        g_simple_async_result_take_error (ctx->result, error);
>>  +    else if (!mm_telit_parse_supported_bands_response (response,
>>  +                                                       
>> ctx->mm_modem_is_2g,
>>  +                                                       
>> ctx->mm_modem_is_3g,
>>  +                                                       
>> ctx->mm_modem_is_4g,
>>  +                                                       &bands,
>>  +                                                       &error))
>>  +        g_simple_async_result_take_error (ctx->result, error);
>>  +    else
>>  +        g_simple_async_result_set_op_res_gpointer (ctx->result, 
>> bands, (GDestroyNotify)g_array_unref);
>>  +
>>  +    load_supported_bands_context_complete_and_free(ctx);
>>  +}
>>  +
>>  +static void
>>  +modem_load_supported_bands (MMIfaceModem *self,
>>  +                            GAsyncReadyCallback callback,
>>  +                            gpointer user_data)
>>  +{
>>  +    LoadSupportedBandsContext *ctx;
>>  +
>>  +    ctx = g_slice_new0(LoadSupportedBandsContext);
>>  +
>>  +    ctx->self = g_object_ref (self);
>>  +    ctx->mm_modem_is_2g = mm_iface_modem_is_2g (ctx->self);
>>  +    ctx->mm_modem_is_3g = mm_iface_modem_is_3g (ctx->self);
>>  +    ctx->mm_modem_is_4g = mm_iface_modem_is_4g (ctx->self);
>>  +
>>  +    ctx->result = g_simple_async_result_new (G_OBJECT (self),
>>  +                                             callback,
>>  +                                             user_data,
>>  +                                             
>> modem_load_supported_bands);
>>  +
>>  +    mm_base_modem_at_command (MM_BASE_MODEM (self),
>>  +                              "#BND=?",
>>  +                              3,
>>  +                              FALSE,
>>  +                              (GAsyncReadyCallback) 
>> load_supported_bands_ready,
>>  +                              ctx);
>>  +}
>>  +
>>  
>> +/*****************************************************************************/
>>   /* Load unlock retries (Modem interface) */
>> 
>>   #define CSIM_QUERY_PIN_RETRIES_STR  "+CSIM=10,0020000100"
>>  @@ -517,6 +601,8 @@ mm_broadband_modem_telit_init 
>> (MMBroadbandModemTelit *self)
>>   static void
>>   iface_modem_init (MMIfaceModem *iface)
>>   {
>>  +    iface->load_supported_bands = modem_load_supported_bands;
>>  +    iface->load_supported_bands_finish = 
>> 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 5344600..d27f2cd 100644
>>  --- a/plugins/telit/mm-modem-helpers-telit.c
>>  +++ b/plugins/telit/mm-modem-helpers-telit.c
>>  @@ -26,6 +26,9 @@
>>   #include "mm-modem-helpers.h"
>>   #include "mm-modem-helpers-telit.h"
>> 
>>  +#define EMPTY_STRING ""
>>  +
>>  +
>>   
>> /*****************************************************************************/
>>   /* +CSIM response parser */
>> 
>>  @@ -36,7 +39,7 @@ mm_telit_parse_csim_response (const guint step,
>>   {
>>       GRegex *r = NULL;
>>       GMatchInfo *match_info = NULL;
>>  -    gchar* retries_hex_str;
>>  +    gchar *retries_hex_str;
>>       guint retries;
>> 
>>       r = g_regex_new ("\\+CSIM:\\s*[0-9]+,\\s*.*63C(.*)\"", 
>> G_REGEX_RAW, 0, NULL);
>>  @@ -76,3 +79,370 @@ mm_telit_parse_csim_response (const guint step,
>> 
>>       return retries;
>>   }
>>  +
>>  
>> +/*****************************************************************************/
>>  +/* #BND=? response parser
>>  + *
>>  + * Example:
>>  + *  AT#BND=?
>>  + *      #BND: <2G band flags>,<3G band flags>[, <4G band flags>]
>>  + *
>>  + *  where "band flags" is a list of numbers definining the 
>> supported bands.
>>  + *  Note that the one Telit band flag may represent more than one 
>> MM band.
>>  + *
>>  + *  e.g.
>>  + *
>>  + *  #BND: (0-2),(3,4)
>>  + *
>>  + *  (0,2) = 2G band flag 0 is EGSM + DCS
>>  + *        = 2G band flag 1 is EGSM + PCS
>>  + *        = 2G band flag 2 is DCS + G850
>>  + *  (3,4) = 3G band flag 3 is U2100 + U1900 + U850
>>  + *        = 3G band flag 4 is U1900 + U850
>>  + *
>>  + * Modems that supports 4G bands, return a range value(X-Y) where
>>  + * X: represent the lower supported band, such as X = 2^(B-1), 
>> being B = B1, B2,..., B32
>>  + * Y: is a 32 bit number resulting from a mask of all the 
>> supported bands:
>>  + *      1 - B1
>>  + *      2 - B2
>>  + *      4 - B3
>>  + *      8 - B4
>>  + *      ...
>>  + *      i - B(2exp(i-1))
>>  + *      ...
>>  + *      2147483648 - B32
>>  + *
>>  + *   e.g.
>>  + *      (2-4106)
>>  + *       2 = 2^1 --> lower supported band B2
>>  + *       4106 = 2^1 + 2^3 + 2^12 --> the supported bands are B2, 
>> B4, B13
>>  + */
>>  +
>>  +#define SUPP_BAND_RESPONSE_REGEX          
>> "#BND:\\s*\\((?P<Bands2G>.*)\\),\\s*\\((?P<Bands3G>.*)\\)"
>>  +#define SUPP_BAND_4G_MODEM_RESPONSE_REGEX 
>> "#BND:\\s*\\((?P<Bands2G>.*)\\),\\s*\\((?P<Bands3G>.*)\\),\\s*\\((?P<Bands4G>\\d+-\\d+)\\)"
>>  +
>>  +gboolean
>>  +mm_telit_parse_supported_bands_response (const gchar *response,
>>  +                                         const gboolean 
>> modem_is_2g,
>>  +                                         const gboolean 
>> modem_is_3g,
>>  +                                         const gboolean 
>> modem_is_4g,
>>  +                                         GArray **supported_bands,
>>  +                                         GError **error)
>>  +{
>>  +    GArray *bands = NULL;
>>  +    GMatchInfo *match_info = NULL;
>>  +    GRegex *r = NULL;
>>  +    gboolean ret = FALSE;
>>  +
>>  +    /* Parse #BND=? response */
>>  +    if (modem_is_4g)
>>  +        r = g_regex_new (SUPP_BAND_4G_MODEM_RESPONSE_REGEX, 
>> G_REGEX_RAW, 0, NULL);
>>  +    else
>>  +        r = g_regex_new (SUPP_BAND_RESPONSE_REGEX, G_REGEX_RAW, 0, 
>> NULL);
>>  +
>>  +    if (!g_regex_match (r, response, 0, &match_info)) {
>>  +        g_set_error (error, MM_CORE_ERROR, MM_CORE_ERROR_FAILED,
>>  +                     "Could not parse reponse '%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);
>>  +
>>  +    if(match_info)
>>  +        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)
>>  +{
>>  +    GArray *flags = NULL;
>>  +    gchar *match_str = NULL;
>>  +    guint i;
>>  +    gboolean ret = TRUE;
>>  +
>>  +    TelitToMMBandMap map [5] = {
>>  +        { FLAG_GSM900_DCS1800, {MM_MODEM_BAND_EGSM, 
>> MM_MODEM_BAND_DCS, MM_MODEM_BAND_UNKNOWN} }, /* 0 */
>>  +        { FLAG_GSM900_PCS1900, {MM_MODEM_BAND_EGSM, 
>> MM_MODEM_BAND_PCS, MM_MODEM_BAND_UNKNOWN} }, /* 1 */
>>  +        { FLAG_GSM850_DCS1800, {MM_MODEM_BAND_DCS, 
>> MM_MODEM_BAND_G850, MM_MODEM_BAND_UNKNOWN} }, /* 2 */
>>  +        { FLAG_GSM850_PCS1900, {MM_MODEM_BAND_PCS, 
>> MM_MODEM_BAND_G850, MM_MODEM_BAND_UNKNOWN} }, /* 3 */
>>  +        { FLAG_BAND_UNKNOWN, {}},
>>  +    };
>>  +
>>  +    match_str = g_match_info_fetch_named (match_info, "Bands2G");
>>  +
>>  +    if (match_str == NULL || g_strcmp0(match_str, EMPTY_STRING) == 
>> 0) {
>>  +        g_set_error (error, MM_CORE_ERROR, MM_CORE_ERROR_FAILED,
>>  +                     "Could not find 2G band flags from response");
>>  +        ret = FALSE;
>>  +        goto end;
>>  +    }
>>  +
>>  +    flags = g_array_new (FALSE, FALSE, sizeof(guint));
>>  +
>>  +    if (!mm_telit_get_band_flags_from_string (match_str, &flags, 
>> error)) {
>>  +        ret = FALSE;
>>  +        goto end;
>>  +    }
>>  +
>>  +    for (i = 0; i < flags->len; i++) {
>>  +        guint flag = g_array_index (flags, guint, i);
>>  +        if (!mm_telit_update_band_array (flag, map, bands, error)) 
>> {
>>  +            ret = FALSE;
>>  +            goto end;
>>  +        }
>>  +    }
>>  +
>>  +end:
>>  +    if (match_str != NULL)
>>  +        g_free (match_str);
>>  +
>>  +    if (flags != NULL)
>>  +        g_array_free (flags, TRUE);
>>  +
>>  +    return ret;
>>  +}
>>  +
>>  +gboolean
>>  +mm_telit_get_3g_mm_bands (GMatchInfo *match_info,
>>  +                          GArray **bands,
>>  +                          GError **error)
>>  +{
>>  +    GArray *flags = NULL;
>>  +    gchar *match_str = NULL;
>>  +    guint i;
>>  +    gboolean ret = TRUE;
>>  +
>>  +    TelitToMMBandMap map [] = {
>>  +        { BND_FLAG_0, { MM_MODEM_BAND_U2100, 
>> MM_MODEM_BAND_UNKNOWN} },
>>  +        { BND_FLAG_1, { MM_MODEM_BAND_U1900, 
>> MM_MODEM_BAND_UNKNOWN} },
>>  +        { BND_FLAG_2, { MM_MODEM_BAND_U850, MM_MODEM_BAND_UNKNOWN} 
>> },
>>  +        { BND_FLAG_3, { MM_MODEM_BAND_U2100, MM_MODEM_BAND_U1900, 
>> MM_MODEM_BAND_U850, MM_MODEM_BAND_UNKNOWN} },
>>  +        { BND_FLAG_4, { MM_MODEM_BAND_U1900, MM_MODEM_BAND_U850, 
>> MM_MODEM_BAND_UNKNOWN} },
>>  +        { BND_FLAG_5, { MM_MODEM_BAND_U900, MM_MODEM_BAND_UNKNOWN} 
>> },
>>  +        { BND_FLAG_6, { MM_MODEM_BAND_U2100, MM_MODEM_BAND_U900, 
>> MM_MODEM_BAND_UNKNOWN} },
>>  +        { BND_FLAG_7, { MM_MODEM_BAND_U17IV, 
>> MM_MODEM_BAND_UNKNOWN} },
>>  +        { BND_FLAG_8, { MM_MODEM_BAND_U2100, MM_MODEM_BAND_U850, 
>> MM_MODEM_BAND_UNKNOWN }},
>>  +        { BND_FLAG_9, { MM_MODEM_BAND_U2100, MM_MODEM_BAND_U900, 
>> MM_MODEM_BAND_U850, MM_MODEM_BAND_UNKNOWN }},
>>  +        { BND_FLAG_10, { MM_MODEM_BAND_U1900, MM_MODEM_BAND_U17IV, 
>> MM_MODEM_BAND_U850, MM_MODEM_BAND_UNKNOWN }},
>>  +        { BND_FLAG_12, { MM_MODEM_BAND_U800, 
>> MM_MODEM_BAND_UNKNOWN}},
>>  +        { BND_FLAG_13, { MM_MODEM_BAND_U1800, 
>> MM_MODEM_BAND_UNKNOWN }},
>>  +        { BND_FLAG_14, { MM_MODEM_BAND_U2100, MM_MODEM_BAND_U900, 
>> MM_MODEM_BAND_U17IV, MM_MODEM_BAND_U850, MM_MODEM_BAND_U800, 
>> MM_MODEM_BAND_UNKNOWN }},
>>  +        { BND_FLAG_15, { MM_MODEM_BAND_U2100, MM_MODEM_BAND_U900, 
>> MM_MODEM_BAND_U1800, MM_MODEM_BAND_UNKNOWN }},
>>  +        { BND_FLAG_16, { MM_MODEM_BAND_U900, MM_MODEM_BAND_U850, 
>> MM_MODEM_BAND_UNKNOWN }},
>>  +        { BND_FLAG_17, { MM_MODEM_BAND_U1900, MM_MODEM_BAND_U17IV, 
>> MM_MODEM_BAND_U850, MM_MODEM_BAND_U800, MM_MODEM_BAND_UNKNOWN }},
>>  +        { BND_FLAG_18, { MM_MODEM_BAND_U2100, MM_MODEM_BAND_U1900, 
>> MM_MODEM_BAND_U850, MM_MODEM_BAND_U800, MM_MODEM_BAND_UNKNOWN}},
>>  +        { BND_FLAG_19, { MM_MODEM_BAND_U1900, MM_MODEM_BAND_U800, 
>> MM_MODEM_BAND_UNKNOWN }},
>>  +        { BND_FLAG_20, { MM_MODEM_BAND_U850, MM_MODEM_BAND_U800, 
>> MM_MODEM_BAND_UNKNOWN}},
>>  +        { BND_FLAG_21, { MM_MODEM_BAND_U1900, MM_MODEM_BAND_U850, 
>> MM_MODEM_BAND_U800, MM_MODEM_BAND_UNKNOWN}},
>>  +        { FLAG_BAND_UNKNOWN, {}},
>>  +    };
>>  +
>>  +
>>  +    match_str = g_match_info_fetch_named (match_info, "Bands3G");
>>  +
>>  +    if (match_str == NULL || g_strcmp0(match_str, EMPTY_STRING) == 
>> 0) {
>>  +        g_set_error (error, MM_CORE_ERROR, MM_CORE_ERROR_FAILED,
>>  +                     "Could not find 3G band flags from response");
>>  +        ret = FALSE;
>>  +        goto end;
>>  +    }
>>  +
>>  +    flags = g_array_new (FALSE, FALSE, sizeof(guint));
>>  +
>>  +    if (!mm_telit_get_band_flags_from_string (match_str, &flags, 
>> error)) {
>>  +        ret = FALSE;
>>  +        goto end;
>>  +    }
>>  +
>>  +    for (i = 0; i < flags->len; i++) {
>>  +        guint flag = g_array_index (flags, guint, i);
>>  +        if (!mm_telit_update_band_array (flag, map, bands, error)) 
>> {
>>  +            ret = FALSE;
>>  +            goto end;
>>  +        }
>>  +    }
>>  +
>>  +end:
>>  +    if (match_str != NULL)
>>  +        g_free (match_str);
>>  +
>>  +    if (flags != NULL)
>>  +        g_array_free (flags, TRUE);
>>  +
>>  +    return ret;
>>  +}
>>  +
>>  +gboolean
>>  +mm_telit_get_4g_mm_bands(GMatchInfo *match_info,
>>  +                         GArray **bands,
>>  +                         GError **error)
>>  +{
>>  +    GArray *flags = NULL;
>>  +    MMModemBand band;
>>  +    gboolean ret = TRUE;
>>  +    gchar *match_str = NULL;
>>  +    guint i;
>>  +    guint max_value;
>>  +
>>  +    gchar **tokens;
>>  +
>>  +    match_str = g_match_info_fetch_named (match_info, "Bands4G");
>>  +
>>  +    if (match_str == NULL || g_strcmp0(match_str, EMPTY_STRING) == 
>> 0) {
>>  +        g_set_error (error, MM_CORE_ERROR, MM_CORE_ERROR_FAILED,
>>  +                     "Could not find 4G band flags from response");
>>  +        ret = FALSE;
>>  +        goto end;
>>  +    }
>>  +
>>  +    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", &max_value);
>>  +
>>  +    for(i = 0; max_value > 0; i++) {
>>  +        if (max_value % 2 != 0) {
>>  +            band = MM_MODEM_BAND_EUTRAN_I + i;
>>  +            g_array_append_val(*bands, band);
>>  +        }
>>  +        max_value = max_value >> 1;
>>  +    }
>>  +
>>  +end:
>>  +    if (match_str != NULL)
>>  +        g_free (match_str);
>>  +
>>  +    if (flags != NULL)
>>  +        g_array_free (flags, TRUE);
>>  +
>>  +    return ret;
>>  +}
>>  +gboolean
>>  +mm_telit_bands_contains (GArray *mm_bands, const MMModemBand 
>> mm_band)
>>  +{
>>  +    guint i;
>>  +
>>  +    for (i = 0; i < mm_bands->len; i++) {
>>  +        if (mm_band == g_array_index (mm_bands, MMModemBand, i))
>>  +            return TRUE;
>>  +    }
>>  +
>>  +    return FALSE;
>>  +}
>>  +
>>  +gboolean
>>  +mm_telit_update_band_array (const gint bands_flag,
>>  +                            const TelitToMMBandMap *map,
>>  +                            GArray **bands,
>>  +                            GError **error)
>>  +{
>>  +    guint i;
>>  +    guint j;
>>  +
>>  +    for (i = 0; map[i].flag != FLAG_BAND_UNKNOWN; i++) {
>>  +        if (bands_flag == map[i].flag) {
>>  +            for (j = 0; map[i].mm_bands[j] != 
>> MM_MODEM_BAND_UNKNOWN; j++) {
>>  +                if (!mm_telit_bands_contains (*bands, 
>> map[i].mm_bands[j])) {
>>  +                    g_array_append_val (*bands, 
>> map[i].mm_bands[j]);
>>  +                }
>>  +            }
>>  +
>>  +            return TRUE;
>>  +        }
>>  +    }
>>  +
>>  +    g_set_error (error, MM_CORE_ERROR, MM_CORE_ERROR_FAILED,
>>  +                 "No MM band found for Telit #BND flag '%d'",
>>  +                 bands_flag);
>>  +
>>  +    return FALSE;
>>  +}
>>  +
>>  +
>>  +gboolean
>>  +mm_telit_get_band_flags_from_string (const gchar *flag_str,
>>  +                                     GArray **band_flags,
>>  +                                     GError **error)
>>  +{
>>  +    gchar **range;
>>  +    gchar **tokens;
>>  +    guint flag;
>>  +    guint i;
>>  +
>>  +    if (g_strcmp0(flag_str, "") == 0) {
>>  +        g_set_error (error, MM_CORE_ERROR, MM_CORE_ERROR_FAILED,
>>  +                     "String is empty, no band flags to parse");
>>  +        return FALSE;
>>  +    }
>>  +
>>  +    tokens = g_strsplit (flag_str, ",", -1);
>>  +    if (!tokens) {
>>  +        g_set_error (error, MM_CORE_ERROR, MM_CORE_ERROR_FAILED,
>>  +                     "Could not get the list of flags");
>>  +        return FALSE;
>>  +    }
>>  +
>>  +    for (i = 0; tokens[i]; i++) {
>>  +        /* check whether tokens[i] defines a
>>  +         * single band value or a range of bands */
>>  +        if (!strstr(tokens[i], "-")) {
>>  +            sscanf(tokens[i], "%d", &flag);
>>  +            g_array_append_val (*band_flags, flag);
>>  +        } else {
>>  +            gint range_start;
>>  +            gint range_end;
>>  +
>>  +            range = g_strsplit(tokens[i], "-", 2);
>>  +
>>  +            sscanf(range[0], "%d", &range_start);
>>  +            sscanf(range[1], "%d", &range_end);
>>  +
>>  +            for (flag=range_start; flag <= range_end; flag++) {
>>  +                g_array_append_val (*band_flags, flag);
>>  +            }
>>  +
>>  +            g_strfreev (range);
>>  +        }
>>  +    }
>>  +
>>  +    g_strfreev (tokens);
>>  +
>>  +    return TRUE;
>>  +}
>>  +
>>  +
>>  +
>>  diff --git a/plugins/telit/mm-modem-helpers-telit.h 
>> b/plugins/telit/mm-modem-helpers-telit.h
>>  index 112e04b..c5d997b 100644
>>  --- a/plugins/telit/mm-modem-helpers-telit.h
>>  +++ b/plugins/telit/mm-modem-helpers-telit.h
>>  @@ -18,9 +18,67 @@
>> 
>>   #include <glib.h>
>> 
>>  +#define MAX_BANDS_LIST_LEN 20
>>  +
>>  +/* 2G #BND flags */
>>  +#define FLAG_BAND_UNKNOWN    -1
>>  +#define FLAG_GSM900_DCS1800  0
>>  +#define FLAG_GSM900_PCS1900  1
>>  +#define FLAG_GSM850_DCS1800  2
>>  +#define FLAG_GSM850_PCS1900  3
>>  +
>>  +/* 3G #BND flags */
>>  +#define BND_FLAG_0   0       /* B1 (2100 MHz) */
>>  +#define BND_FLAG_1   1       /* B2 (1900 MHz) */
>>  +#define BND_FLAG_2   2       /* B5 (850 MHz) */
>>  +#define BND_FLAG_3   3       /* B1 (2100 MHz) + B2 (1900 MHz) + B5 
>> (850 MHz) */
>>  +#define BND_FLAG_4   4       /* B2 (1900 MHz) + B5 (850 MHz) */
>>  +#define BND_FLAG_5   5       /* B8 (900 MHz) */
>>  +#define BND_FLAG_6   6       /* B1 (2100 MHz) + B8 (900 MHz) */
>>  +#define BND_FLAG_7   7       /* B4 (1700 MHz) */
>>  +#define BND_FLAG_8   8       /* B1 (2100 MHz) + B5 (850 MHz) */
>>  +#define BND_FLAG_9   9       /* B1 (2100 MHz) + B8 (900 MHz) + B5 
>> (850 MHz) */
>>  +#define BND_FLAG_10  10      /* B2 (1900 MHz) + B4 (1700 MHz) + B5 
>> (850 MHz) */
>>  +#define BND_FLAG_12  12      /* B6 (800 MHz) */
>>  +#define BND_FLAG_13  13      /* B3 (1800 MHz) */
>>  +#define BND_FLAG_14  14      /* B1 (2100 MHz) + B2 (1900 MHz) + B4 
>> (1700 MHz) + B5 (850 MHz) + B6 (800MHz) */
>>  +#define BND_FLAG_15  15      /* B1 (2100 MHz) + B8 (900 MHz) + B3 
>> (1800 MHz) */
>>  +#define BND_FLAG_16  16      /* B8 (900 MHz) + B5 (850 MHz) */
>>  +#define BND_FLAG_17  17      /* B2 (1900 MHz) + B4 (1700 MHz) + B5 
>> (850 MHz) + B6 (800 MHz) */
>>  +#define BND_FLAG_18  18      /* B1 (2100 MHz) + B2 (1900 MHz) + B5 
>> (850 MHz) + B6 (800 MHz) */
>>  +#define BND_FLAG_19  19      /* B2 (1900 MHz) + B6 (800 MHz) */
>>  +#define BND_FLAG_20  20      /* B5 (850 MHz) + B6 (800 MHz) */
>>  +#define BND_FLAG_21  21      /* B2 (1900 MHz) + B5 (850 MHz) + B6 
>> (800 MHz) */
>>  +
> 
> A pair of enums maybe, instead of defines?
> 
>>  +typedef struct {
>>  +    gint flag;
>>  +    MMModemBand mm_bands[MAX_BANDS_LIST_LEN];
>>  +} TelitToMMBandMap;
>>  +
>>   /* +CSIM response parser */
>>   gint mm_telit_parse_csim_response (const guint step,
>>                                      const gchar *response,
>>                                      GError **error);
>> 
>>  +/* #BND=? response parser */
>>  +gboolean
>>  +mm_telit_parse_supported_bands_response (const gchar *response,
>>  +                                         const gboolean 
>> modem_is_2g,
>>  +                                         const gboolean 
>> modem_is_3g,
>>  +                                         const gboolean 
>> modem_is_4g,
>>  +                                         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);
>>  +
>>   #endif  /* MM_MODEM_HELPERS_TELIT_H */
>>  diff --git a/plugins/telit/tests/test-mm-modem-helpers-telit.c 
>> b/plugins/telit/tests/test-mm-modem-helpers-telit.c
>>  index afe9f82..7084779 100644
>>  --- a/plugins/telit/tests/test-mm-modem-helpers-telit.c
>>  +++ b/plugins/telit/tests/test-mm-modem-helpers-telit.c
>>  @@ -22,7 +22,6 @@
>>   #define _LIBMM_INSIDE_MM
>>   #include <libmm-glib.h>
>> 
>>  -#include "mm-log.h"
>>   #include "mm-modem-helpers.h"
>>   #include "mm-modem-helpers-telit.h"
>> 
>>  @@ -63,7 +62,7 @@ static CSIMResponseTest 
>> invalid_csim_response_test_list [] = {
>>   };
>> 
>>   static void
>>  -test_parse_csim_response (void)
>>  +test_mm_telit_parse_csim_response (void)
>>   {
>>       const gint step = 1;
>>       guint i;
>>  @@ -92,6 +91,148 @@ test_parse_csim_response (void)
>>       }
>>   }
>> 
>>  +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);
>>  +
>>  +    g_assert_true (mm_telit_bands_contains (mm_bands, 2));
>>  +    g_assert_true (mm_telit_bands_contains (mm_bands, 2));
>>  +    g_assert_false (mm_telit_bands_contains (mm_bands, 3));
>>  +
>>  +    g_array_free (mm_bands, TRUE);
>>  +}
>>  +
>>  +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", 2, {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_true (res);
>>  +
>>  +        for (j = 0; j < band_flag_test[i].band_flags_len; j++) {
>>  +            guint ref = band_flag_test[i].band_flags[j];
>>  +            guint cur = g_array_index (band_flags, guint, j);
>>  +
>>  +            g_assert_true (ref == cur);
>>  +        }
>>  +
>>  +        g_array_free (band_flags, TRUE);
>>  +    }
>>  +}
>>  +
>>  +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),(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_U2100,
>>  +                                                      
>> MM_MODEM_BAND_U850,
>>  +                                                      
>> MM_MODEM_BAND_U900} },
>>  +    { "#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_U2100,
>>  +                                                       
>> MM_MODEM_BAND_U850,
>>  +                                                       
>> MM_MODEM_BAND_U900} },
>>  +    { "#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_U2100,
>>  +                                                       
>> MM_MODEM_BAND_U850,
>>  +                                                       
>> MM_MODEM_BAND_U900} },
>>  +    { "#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_U2100,
>>  +                                                       
>> MM_MODEM_BAND_U1900,
>>  +                                                       
>> MM_MODEM_BAND_U850,
>>  +                                                       
>> MM_MODEM_BAND_U900} },
>>  +    { "#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_U2100,
>>  +                                                         
>> MM_MODEM_BAND_U850,
>>  +                                                         
>> MM_MODEM_BAND_U900,
>>  +                                                         
>> MM_MODEM_BAND_EUTRAN_I} },
>>  +    { "#BND: (0),(0),(1-3)", TRUE, TRUE, TRUE, 5, { 
>> MM_MODEM_BAND_EGSM,
>>  +                                                    
>> MM_MODEM_BAND_DCS,
>>  +                                                    
>> MM_MODEM_BAND_U2100,
>>  +                                                    
>> MM_MODEM_BAND_EUTRAN_I,
>>  +                                                    
>> MM_MODEM_BAND_EUTRAN_II} },
>>  +    { "#BND: (0),(0),(1-3)", FALSE, FALSE, TRUE, 2, { 
>> MM_MODEM_BAND_EUTRAN_I,
>>  +                                                      
>> MM_MODEM_BAND_EUTRAN_II} },
>>  +    { 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_supported_bands_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,
>>  +                                                       &bands,
>>  +                                                       &error);
>>  +        g_assert_no_error (error);
>>  +        g_assert_true (res);
>>  +
>>  +
>>  +        for (j = 0; j < 
>> supported_band_mapping_tests[i].mm_bands_len; j++) {
>>  +            MMModemBand ref = 
>> supported_band_mapping_tests[i].mm_bands[j];
>>  +            MMModemBand cur = g_array_index (bands, MMModemBand, 
>> j);
>>  +            g_assert_cmpint (cur, ==, ref);
>>  +        }
>>  +
>>  +        g_assert_cmpint(bands->len, ==, 
>> supported_band_mapping_tests[i].mm_bands_len);
>>  +
>>  +        g_array_free (bands, FALSE);
>>  +        bands = NULL;
>>  +    }
>>  +}
>>  +
>>   int main (int argc, char **argv)
>>   {
>>       setlocale (LC_ALL, "");
>>  @@ -99,6 +240,9 @@ int main (int argc, char **argv)
>>       g_type_init ();
>>       g_test_init (&argc, &argv, NULL);
>> 
>>  -    g_test_add_func ("/MM/telit/csim", test_parse_csim_response);
>>  +    g_test_add_func ("/MM/telit/csim", 
>> test_mm_telit_parse_csim_response);
>>  +    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);
>>       return g_test_run ();
>>   }
>> 
> 
> The code looks pretty good to me.
> 
> Could you do these minor updates (split udev tag into its own patch, 
> and
> the enums)? Thanks!
> 
> --
> Aleksander
> https://aleksander.es
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.freedesktop.org/archives/modemmanager-devel/attachments/20160123/df2c58bf/attachment-0001.html>


More information about the ModemManager-devel mailing list