From: Carlo Lobrano <c.lobr...@gmail.com> --- plugins/telit/mm-broadband-modem-telit.c | 86 +++++ plugins/telit/mm-modem-helpers-telit.c | 372 +++++++++++++++++++++- plugins/telit/mm-modem-helpers-telit.h | 67 ++++ plugins/telit/tests/test-mm-modem-helpers-telit.c | 150 ++++++++- 4 files changed, 671 insertions(+), 4 deletions(-)
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..f287887 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] = { + { BND_FLAG_GSM900_DCS1800, {MM_MODEM_BAND_EGSM, MM_MODEM_BAND_DCS, MM_MODEM_BAND_UNKNOWN} }, /* 0 */ + { BND_FLAG_GSM900_PCS1900, {MM_MODEM_BAND_EGSM, MM_MODEM_BAND_PCS, MM_MODEM_BAND_UNKNOWN} }, /* 1 */ + { BND_FLAG_GSM850_DCS1800, {MM_MODEM_BAND_DCS, MM_MODEM_BAND_G850, MM_MODEM_BAND_UNKNOWN} }, /* 2 */ + { BND_FLAG_GSM850_PCS1900, {MM_MODEM_BAND_PCS, MM_MODEM_BAND_G850, MM_MODEM_BAND_UNKNOWN} }, /* 3 */ + { BND_FLAG_UNKNOWN, {}}, + }; + + match_str = g_match_info_fetch_named (match_info, "Bands2G"); + + if (match_str == NULL || 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}}, + { BND_FLAG_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 != BND_FLAG_UNKNOWN; i++) { + if (bands_flag == map[i].flag) { + for (j = 0; map[i].mm_bands[j] != MM_MODEM_BAND_UNKNOWN; j++) { + if (!mm_telit_bands_contains (*bands, map[i].mm_bands[j])) { + g_array_append_val (*bands, map[i].mm_bands[j]); + } + } + + return TRUE; + } + } + + g_set_error (error, MM_CORE_ERROR, MM_CORE_ERROR_FAILED, + "No MM band found for Telit #BND flag '%d'", + bands_flag); + + return FALSE; +} + + +gboolean +mm_telit_get_band_flags_from_string (const gchar *flag_str, + GArray **band_flags, + GError **error) +{ + gchar **range; + gchar **tokens; + guint flag; + guint i; + + if (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..d0d74b5 100644 --- a/plugins/telit/mm-modem-helpers-telit.h +++ b/plugins/telit/mm-modem-helpers-telit.h @@ -18,9 +18,76 @@ #include <glib.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; + /* +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); + +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); + #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 (); } -- 2.1.4 _______________________________________________ ModemManager-devel mailing list ModemManager-devel@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/modemmanager-devel