telit: add load_current_bands interface

This commit is contained in:
Carlo Lobrano
2016-02-15 12:10:57 +01:00
committed by Aleksander Morgado
parent c533e56e1e
commit beeabdea2f
4 changed files with 221 additions and 66 deletions

View File

@@ -43,26 +43,28 @@ G_DEFINE_TYPE_EXTENDED (MMBroadbandModemTelit, mm_broadband_modem_telit, MM_TYPE
G_IMPLEMENT_INTERFACE (MM_TYPE_IFACE_MODEM_3GPP, iface_modem_3gpp_init)); G_IMPLEMENT_INTERFACE (MM_TYPE_IFACE_MODEM_3GPP, iface_modem_3gpp_init));
/*****************************************************************************/ /*****************************************************************************/
/* Load supported bands (Modem interface) */ /* Load current bands (Modem interface) */
typedef struct { typedef struct {
MMIfaceModem *self; MMIfaceModem *self;
GSimpleAsyncResult *result; GSimpleAsyncResult *result;
gboolean mm_modem_is_2g; gboolean mm_modem_is_2g;
gboolean mm_modem_is_3g; gboolean mm_modem_is_3g;
gboolean mm_modem_is_4g; gboolean mm_modem_is_4g;
} LoadSupportedBandsContext; MMTelitLoadBandsType band_type;
} LoadBandsContext;
static void static void
load_supported_bands_context_complete_and_free (LoadSupportedBandsContext *ctx) load_bands_context_complete_and_free (LoadBandsContext *ctx)
{ {
g_simple_async_result_complete (ctx->result); g_simple_async_result_complete (ctx->result);
g_object_unref (ctx->result); g_object_unref (ctx->result);
g_object_unref (ctx->self); g_object_unref (ctx->self);
g_slice_free (LoadSupportedBandsContext, ctx); g_slice_free (LoadBandsContext, ctx);
} }
static GArray * static GArray *
modem_load_supported_bands_finish (MMIfaceModem *self, modem_load_bands_finish (MMIfaceModem *self,
GAsyncResult *res, GAsyncResult *res,
GError **error) GError **error)
{ {
@@ -74,9 +76,9 @@ modem_load_supported_bands_finish (MMIfaceModem *self,
} }
static void static void
load_supported_bands_ready (MMBaseModem *self, load_bands_ready (MMBaseModem *self,
GAsyncResult *res, GAsyncResult *res,
LoadSupportedBandsContext *ctx) LoadBandsContext *ctx)
{ {
const gchar *response; const gchar *response;
GError *error = NULL; GError *error = NULL;
@@ -86,32 +88,66 @@ load_supported_bands_ready (MMBaseModem *self,
if (!response) if (!response)
g_simple_async_result_take_error (ctx->result, error); g_simple_async_result_take_error (ctx->result, error);
else if (!mm_telit_parse_supported_bands_response (response, else if (!mm_telit_parse_bnd_response (response,
ctx->mm_modem_is_2g, ctx->mm_modem_is_2g,
ctx->mm_modem_is_3g, ctx->mm_modem_is_3g,
ctx->mm_modem_is_4g, ctx->mm_modem_is_4g,
ctx->band_type,
&bands, &bands,
&error)) &error))
g_simple_async_result_take_error (ctx->result, error); g_simple_async_result_take_error (ctx->result, error);
else else
g_simple_async_result_set_op_res_gpointer (ctx->result, bands, (GDestroyNotify)g_array_unref); g_simple_async_result_set_op_res_gpointer (ctx->result, bands, (GDestroyNotify)g_array_unref);
load_supported_bands_context_complete_and_free(ctx); load_bands_context_complete_and_free(ctx);
} }
static void
modem_load_current_bands (MMIfaceModem *self,
GAsyncReadyCallback callback,
gpointer user_data)
{
LoadBandsContext *ctx;
ctx = g_slice_new0 (LoadBandsContext);
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->band_type = LOAD_CURRENT_BANDS;
ctx->result = g_simple_async_result_new (G_OBJECT (self),
callback,
user_data,
modem_load_current_bands);
mm_base_modem_at_command (MM_BASE_MODEM (self),
"#BND?",
3,
FALSE,
(GAsyncReadyCallback) load_bands_ready,
ctx);
}
/*****************************************************************************/
/* Load supported bands (Modem interface) */
static void static void
modem_load_supported_bands (MMIfaceModem *self, modem_load_supported_bands (MMIfaceModem *self,
GAsyncReadyCallback callback, GAsyncReadyCallback callback,
gpointer user_data) gpointer user_data)
{ {
LoadSupportedBandsContext *ctx; LoadBandsContext *ctx;
ctx = g_slice_new0 (LoadSupportedBandsContext); ctx = g_slice_new0 (LoadBandsContext);
ctx->self = g_object_ref (self); ctx->self = g_object_ref (self);
ctx->mm_modem_is_2g = mm_iface_modem_is_2g (ctx->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_3g = mm_iface_modem_is_3g (ctx->self);
ctx->mm_modem_is_4g = mm_iface_modem_is_4g (ctx->self); ctx->mm_modem_is_4g = mm_iface_modem_is_4g (ctx->self);
ctx->band_type = LOAD_SUPPORTED_BANDS;
ctx->result = g_simple_async_result_new (G_OBJECT (self), ctx->result = g_simple_async_result_new (G_OBJECT (self),
callback, callback,
@@ -122,7 +158,7 @@ modem_load_supported_bands (MMIfaceModem *self,
"#BND=?", "#BND=?",
3, 3,
FALSE, FALSE,
(GAsyncReadyCallback) load_supported_bands_ready, (GAsyncReadyCallback) load_bands_ready,
ctx); ctx);
} }
@@ -783,8 +819,10 @@ iface_modem_init (MMIfaceModem *iface)
{ {
iface_modem_parent = g_type_interface_peek_parent (iface); iface_modem_parent = g_type_interface_peek_parent (iface);
iface->load_current_bands = modem_load_current_bands;
iface->load_current_bands_finish = modem_load_bands_finish;
iface->load_supported_bands = modem_load_supported_bands; iface->load_supported_bands = modem_load_supported_bands;
iface->load_supported_bands_finish = modem_load_supported_bands_finish; iface->load_supported_bands_finish = modem_load_bands_finish;
iface->load_unlock_retries_finish = modem_load_unlock_retries_finish; iface->load_unlock_retries_finish = modem_load_unlock_retries_finish;
iface->load_unlock_retries = modem_load_unlock_retries; iface->load_unlock_retries = modem_load_unlock_retries;
iface->reset = modem_reset; iface->reset = modem_reset;

View File

@@ -77,12 +77,16 @@ mm_telit_parse_csim_response (const guint step,
return retries; return retries;
} }
#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+)\\)"
#define CURR_BAND_RESPONSE_REGEX "#BND:\\s*(?P<Bands2G>\\d+),\\s*(?P<Bands3G>\\d+)"
#define CURR_BAND_4G_MODEM_RESPONSE_REGEX "#BND:\\s*(?P<Bands2G>\\d+),\\s*(?P<Bands3G>\\d+),\\s*(?P<Bands4G>\\d+)"
/*****************************************************************************/ /*****************************************************************************/
/* #BND=? response parser /* #BND response parser
* *
* Example:
* AT#BND=? * AT#BND=?
* #BND: <2G band flags>,<3G band flags>[, <4G band flags>] * #BND: <2G band flags range>,<3G band flags range>[, <4G band flags range>]
* *
* where "band flags" is a list of numbers definining the supported bands. * 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. * Note that the one Telit band flag may represent more than one MM band.
@@ -113,16 +117,28 @@ mm_telit_parse_csim_response (const guint step,
* (2-4106) * (2-4106)
* 2 = 2^1 --> lower supported band B2 * 2 = 2^1 --> lower supported band B2
* 4106 = 2^1 + 2^3 + 2^12 --> the supported bands are B2, B4, B13 * 4106 = 2^1 + 2^3 + 2^12 --> the supported bands are B2, B4, B13
*
*
* AT#BND?
* #BND: <2G band flags>,<3G band flags>[, <4G band flags>]
*
* where "band flags" is a number definining the current bands.
* Note that the one Telit band flag may represent more than one MM band.
*
* e.g.
*
* #BND: 0,4
*
* 0 = 2G band flag 0 is EGSM + DCS
* 4 = 3G band flag 4 is U1900 + U850
*
*/ */
#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 gboolean
mm_telit_parse_supported_bands_response (const gchar *response, mm_telit_parse_bnd_response (const gchar *response,
const gboolean modem_is_2g, gboolean modem_is_2g,
const gboolean modem_is_3g, gboolean modem_is_3g,
const gboolean modem_is_4g, gboolean modem_is_4g,
MMTelitLoadBandsType band_type,
GArray **supported_bands, GArray **supported_bands,
GError **error) GError **error)
{ {
@@ -131,11 +147,25 @@ mm_telit_parse_supported_bands_response (const gchar *response,
GRegex *r = NULL; GRegex *r = NULL;
gboolean ret = FALSE; gboolean ret = FALSE;
switch (band_type) {
case LOAD_SUPPORTED_BANDS:
/* Parse #BND=? response */ /* Parse #BND=? response */
if (modem_is_4g) if (modem_is_4g)
r = g_regex_new (SUPP_BAND_4G_MODEM_RESPONSE_REGEX, G_REGEX_RAW, 0, NULL); r = g_regex_new (SUPP_BAND_4G_MODEM_RESPONSE_REGEX, G_REGEX_RAW, 0, NULL);
else else
r = g_regex_new (SUPP_BAND_RESPONSE_REGEX, G_REGEX_RAW, 0, NULL); r = g_regex_new (SUPP_BAND_RESPONSE_REGEX, G_REGEX_RAW, 0, NULL);
break;
case LOAD_CURRENT_BANDS:
/* Parse #BND? response */
if (modem_is_4g)
r = g_regex_new (CURR_BAND_4G_MODEM_RESPONSE_REGEX, G_REGEX_RAW, 0, NULL);
else
r = g_regex_new (CURR_BAND_RESPONSE_REGEX, G_REGEX_RAW, 0, NULL);
break;
default:
break;
}
if (!g_regex_match (r, response, 0, &match_info)) { if (!g_regex_match (r, response, 0, &match_info)) {
g_set_error (error, MM_CORE_ERROR, MM_CORE_ERROR_FAILED, g_set_error (error, MM_CORE_ERROR, MM_CORE_ERROR_FAILED,
@@ -310,7 +340,7 @@ mm_telit_get_4g_mm_bands(GMatchInfo *match_info,
gboolean ret = TRUE; gboolean ret = TRUE;
gchar *match_str = NULL; gchar *match_str = NULL;
guint i; guint i;
guint max_value; guint value;
gchar **tokens; gchar **tokens;
match_str = g_match_info_fetch_named (match_info, "Bands4G"); match_str = g_match_info_fetch_named (match_info, "Bands4G");
@@ -322,6 +352,7 @@ mm_telit_get_4g_mm_bands(GMatchInfo *match_info,
goto end; goto end;
} }
if (strstr(match_str, "-")) {
tokens = g_strsplit (match_str, "-", -1); tokens = g_strsplit (match_str, "-", -1);
if (tokens == NULL) { if (tokens == NULL) {
g_set_error (error, MM_CORE_ERROR, MM_CORE_ERROR_FAILED, g_set_error (error, MM_CORE_ERROR, MM_CORE_ERROR_FAILED,
@@ -330,17 +361,19 @@ mm_telit_get_4g_mm_bands(GMatchInfo *match_info,
ret = FALSE; ret = FALSE;
goto end; goto end;
} }
sscanf (tokens[1], "%d", &value);
} else {
sscanf (match_str, "%d", &value);
}
sscanf (tokens[1], "%d", &max_value);
for (i = 0; max_value > 0; i++) { for (i = 0; value > 0; i++) {
if (max_value % 2 != 0) { if (value % 2 != 0) {
band = MM_MODEM_BAND_EUTRAN_I + i; band = MM_MODEM_BAND_EUTRAN_I + i;
g_array_append_val (*bands, band); g_array_append_val (*bands, band);
} }
max_value = max_value >> 1; value = value >> 1;
} }
end: end:
if (match_str != NULL) if (match_str != NULL)
g_free (match_str); g_free (match_str);

View File

@@ -65,15 +65,22 @@ gint mm_telit_parse_csim_response (const guint step,
const gchar *response, const gchar *response,
GError **error); GError **error);
/* #BND=? response parser */ typedef enum {
LOAD_SUPPORTED_BANDS,
LOAD_CURRENT_BANDS
} MMTelitLoadBandsType;
/* #BND response parser */
gboolean gboolean
mm_telit_parse_supported_bands_response (const gchar *response, mm_telit_parse_bnd_response (const gchar *response,
const gboolean modem_is_2g, gboolean modem_is_2g,
const gboolean modem_is_3g, gboolean modem_is_3g,
const gboolean modem_is_4g, gboolean modem_is_4g,
MMTelitLoadBandsType band_type,
GArray **supported_bands, GArray **supported_bands,
GError **error); GError **error);
gboolean mm_telit_bands_contains (GArray *mm_bands, const MMModemBand mm_band); gboolean mm_telit_bands_contains (GArray *mm_bands, const MMModemBand mm_band);
gboolean mm_telit_update_band_array (const gint bands_flag, gboolean mm_telit_update_band_array (const gint bands_flag,

View File

@@ -213,10 +213,11 @@ test_parse_supported_bands_response (void) {
GArray* bands = NULL; GArray* bands = NULL;
for (i = 0; supported_band_mapping_tests[i].response != NULL; i++) { for (i = 0; supported_band_mapping_tests[i].response != NULL; i++) {
res = mm_telit_parse_supported_bands_response (supported_band_mapping_tests[i].response, res = mm_telit_parse_bnd_response (supported_band_mapping_tests[i].response,
supported_band_mapping_tests[i].modem_is_2g, supported_band_mapping_tests[i].modem_is_2g,
supported_band_mapping_tests[i].modem_is_3g, supported_band_mapping_tests[i].modem_is_3g,
supported_band_mapping_tests[i].modem_is_4g, supported_band_mapping_tests[i].modem_is_4g,
LOAD_SUPPORTED_BANDS,
&bands, &bands,
&error); &error);
g_assert_no_error (error); g_assert_no_error (error);
@@ -239,6 +240,81 @@ test_parse_supported_bands_response (void) {
} }
} }
static BNDResponseTest current_band_mapping_tests [] = {
{ "#BND: 0,5", TRUE, TRUE, FALSE, 3, { MM_MODEM_BAND_EGSM,
MM_MODEM_BAND_DCS,
MM_MODEM_BAND_U900
}
},
{ "#BND: 1,3", TRUE, TRUE, FALSE, 5, { MM_MODEM_BAND_EGSM,
MM_MODEM_BAND_PCS,
MM_MODEM_BAND_U2100,
MM_MODEM_BAND_U1900,
MM_MODEM_BAND_U850,
}
},
{ "#BND: 2,7", TRUE, TRUE, FALSE, 3, { MM_MODEM_BAND_DCS,
MM_MODEM_BAND_G850,
MM_MODEM_BAND_U17IV
},
},
{ "#BND: 3,0,1", TRUE, TRUE, TRUE, 4, { MM_MODEM_BAND_PCS,
MM_MODEM_BAND_G850,
MM_MODEM_BAND_U2100,
MM_MODEM_BAND_EUTRAN_I
}
},
{ "#BND: 0,0,3", TRUE, FALSE, TRUE, 4, { MM_MODEM_BAND_EGSM,
MM_MODEM_BAND_DCS,
MM_MODEM_BAND_EUTRAN_I,
MM_MODEM_BAND_EUTRAN_II
}
},
{ "#BND: 0,0,3", FALSE, FALSE, TRUE, 2, { MM_MODEM_BAND_EUTRAN_I,
MM_MODEM_BAND_EUTRAN_II
}
},
{ NULL, FALSE, FALSE, FALSE, 0, {}},
};
static void
test_parse_current_bands_response (void) {
GError* error = NULL;
gboolean res = FALSE;
guint i, j;
GArray* bands = NULL;
for (i = 0; current_band_mapping_tests[i].response != NULL; i++) {
res = mm_telit_parse_bnd_response (current_band_mapping_tests[i].response,
current_band_mapping_tests[i].modem_is_2g,
current_band_mapping_tests[i].modem_is_3g,
current_band_mapping_tests[i].modem_is_4g,
LOAD_CURRENT_BANDS,
&bands,
&error);
g_assert_no_error (error);
g_assert_true (res);
for (j = 0; j < current_band_mapping_tests[i].mm_bands_len; j++) {
MMModemBand ref;
MMModemBand cur;
ref = current_band_mapping_tests[i].mm_bands[j];
cur = g_array_index (bands, MMModemBand, j);
g_assert_cmpint (cur, ==, ref);
}
g_assert_cmpint (bands->len, ==, current_band_mapping_tests[i].mm_bands_len);
g_array_free (bands, FALSE);
bands = NULL;
}
}
int main (int argc, char **argv) int main (int argc, char **argv)
{ {
setlocale (LC_ALL, ""); setlocale (LC_ALL, "");
@@ -250,5 +326,6 @@ int main (int argc, char **argv)
g_test_add_func ("/MM/telit/bands/supported/bands_contains", test_mm_bands_contains); 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_band_flag", test_parse_band_flag_str);
g_test_add_func ("/MM/telit/bands/supported/parse_bands_response", test_parse_supported_bands_response); g_test_add_func ("/MM/telit/bands/supported/parse_bands_response", test_parse_supported_bands_response);
g_test_add_func ("/MM/telit/bands/current/parse_bands_response", test_parse_current_bands_response);
return g_test_run (); return g_test_run ();
} }