diff options
-rw-r--r-- | plugins/ublox/mm-broadband-bearer-ublox.c | 6 | ||||
-rw-r--r-- | plugins/ublox/mm-broadband-modem-ublox.c | 285 | ||||
-rw-r--r-- | plugins/ublox/mm-modem-helpers-ublox.c | 823 | ||||
-rw-r--r-- | plugins/ublox/mm-modem-helpers-ublox.h | 37 | ||||
-rw-r--r-- | plugins/ublox/tests/test-modem-helpers-ublox.c | 42 |
5 files changed, 924 insertions, 269 deletions
diff --git a/plugins/ublox/mm-broadband-bearer-ublox.c b/plugins/ublox/mm-broadband-bearer-ublox.c index 10d29818..78e9e053 100644 --- a/plugins/ublox/mm-broadband-bearer-ublox.c +++ b/plugins/ublox/mm-broadband-bearer-ublox.c @@ -44,12 +44,6 @@ enum { static GParamSpec *properties[PROP_LAST]; -typedef enum { - FEATURE_SUPPORT_UNKNOWN, - FEATURE_SUPPORTED, - FEATURE_UNSUPPORTED, -} FeatureSupport; - struct _MMBroadbandBearerUbloxPrivate { MMUbloxUsbProfile profile; MMUbloxNetworkingMode mode; diff --git a/plugins/ublox/mm-broadband-modem-ublox.c b/plugins/ublox/mm-broadband-modem-ublox.c index 83352fa8..9c6c55e2 100644 --- a/plugins/ublox/mm-broadband-modem-ublox.c +++ b/plugins/ublox/mm-broadband-modem-ublox.c @@ -44,11 +44,6 @@ G_DEFINE_TYPE_EXTENDED (MMBroadbandModemUblox, mm_broadband_modem_ublox, MM_TYPE G_IMPLEMENT_INTERFACE (MM_TYPE_IFACE_MODEM, iface_modem_init) G_IMPLEMENT_INTERFACE (MM_TYPE_IFACE_MODEM_VOICE, iface_modem_voice_init)) -typedef enum { - FEATURE_SUPPORT_UNKNOWN, - FEATURE_SUPPORTED, - FEATURE_UNSUPPORTED, -} FeatureSupport; struct _MMBroadbandModemUbloxPrivate { /* USB profile in use */ @@ -64,8 +59,11 @@ struct _MMBroadbandModemUbloxPrivate { /* Mode combination to apply if "any" requested */ MMModemMode any_allowed; - /* Band management */ - FeatureSupport uact; + /* AT command configuration */ + UbloxSupportConfig support_config; + + /* Operator ID for manual registration */ + gchar *operator_id; /* Regex to ignore */ GRegex *pbready_regex; @@ -73,7 +71,6 @@ struct _MMBroadbandModemUbloxPrivate { /*****************************************************************************/ -static gboolean acquire_power_operation (MMBroadbandModemUblox *self, GError **error) { @@ -105,59 +102,27 @@ load_supported_bands_finish (MMIfaceModem *self, } static void -uact_test_ready (MMBaseModem *_self, - GAsyncResult *res, - GTask *task) +load_supported_bands (MMIfaceModem *_self, + GAsyncReadyCallback callback, + gpointer user_data) { - MMBroadbandModemUblox *self = MM_BROADBAND_MODEM_UBLOX (_self); - const gchar *response; - GError *error = NULL; - GArray *bands = NULL; - GArray *bands_2g = NULL; - GArray *bands_3g = NULL; - GArray *bands_4g = NULL; - - response = mm_base_modem_at_command_finish (_self, res, NULL); - if (!response) { - /* Flag as unsupported */ - self->priv->uact = FEATURE_UNSUPPORTED; - - /* The list of supported tasks we give here must include not only the bands - * allowed in the current AcT, but the whole list of bands allowed in all - * AcTs. This is because the list of supported bands is loaded only once - * during modem initialization. Not ideal, but the current API is like that. - * - * So, we give a predefined list of supported bands and we filter them in the - * same way we filter the allowed AcTs. - */ - bands = mm_ublox_get_supported_bands (mm_iface_modem_get_model (MM_IFACE_MODEM (self)), &error); - goto out; - } + MMBroadbandModemUblox *self = MM_BROADBAND_MODEM_UBLOX (_self); + GTask *task; + GError *error = NULL; + GArray *bands = NULL; + const gchar *model; - /* Flag as supported */ - self->priv->uact = FEATURE_SUPPORTED; + model = mm_iface_modem_get_model (_self); - /* Parse UACT=? test response */ - if (!mm_ublox_parse_uact_test (response, &bands_2g, &bands_3g, &bands_4g, &error)) - goto out; + task = g_task_new (_self, NULL, callback, user_data); + + bands = mm_ublox_get_supported_bands (model, &error); - /* Build a combined array */ - bands = g_array_new (FALSE, FALSE, sizeof (MMModemBand)); - if (bands_2g) { - bands = g_array_append_vals (bands, bands_2g->data, bands_2g->len); - g_array_unref (bands_2g); - } - if (bands_3g) { - bands = g_array_append_vals (bands, bands_3g->data, bands_3g->len); - g_array_unref (bands_3g); - } - if (bands_4g) { - bands = g_array_append_vals (bands, bands_4g->data, bands_4g->len); - g_array_unref (bands_4g); + if (!mm_ublox_get_support_config (model, &self->priv->support_config, &error)) { + g_assert (error); + g_task_return_error (task, error); } - g_assert (bands->len > 0); - -out: + if (!bands) { g_assert (error); g_task_return_error (task, error); @@ -166,25 +131,6 @@ out: g_object_unref (task); } -static void -load_supported_bands (MMIfaceModem *self, - GAsyncReadyCallback callback, - gpointer user_data) -{ - GTask *task; - - task = g_task_new (self, NULL, callback, user_data); - - /* See if AT+UACT is supported to query bands */ - mm_base_modem_at_command ( - MM_BASE_MODEM (self), - "+UACT=?", - 3, - TRUE, /* allow cached */ - (GAsyncReadyCallback) uact_test_ready, - task); -} - /*****************************************************************************/ /* Load current bands (Modem interface) */ @@ -195,15 +141,17 @@ load_current_bands_finish (MMIfaceModem *_self, { MMBroadbandModemUblox *self = MM_BROADBAND_MODEM_UBLOX (_self); const gchar *response; + const gchar *model; response = mm_base_modem_at_command_finish (MM_BASE_MODEM (self), res, error); + model = mm_iface_modem_get_model (_self); if (!response) return NULL; - if (self->priv->uact == FEATURE_SUPPORTED) + if (self->priv->support_config.uact == FEATURE_SUPPORTED) return mm_ublox_parse_uact_response (response, error); - return mm_ublox_parse_ubandsel_response (response, error); + return mm_ublox_parse_ubandsel_response (response, model, error); } static void @@ -213,12 +161,13 @@ load_current_bands (MMIfaceModem *_self, { MMBroadbandModemUblox *self = MM_BROADBAND_MODEM_UBLOX (_self); - g_assert (self->priv->uact != FEATURE_SUPPORT_UNKNOWN); + g_assert (self->priv->support_config.uact != FEATURE_SUPPORT_UNKNOWN && + self->priv->support_config.ubandsel != FEATURE_SUPPORT_UNKNOWN); - if (self->priv->uact == FEATURE_SUPPORTED) { + if (self->priv->support_config.ubandsel == FEATURE_SUPPORTED) { mm_base_modem_at_command ( MM_BASE_MODEM (self), - "+UACT?", + "+UBANDSEL?", 3, FALSE, (GAsyncReadyCallback)callback, @@ -226,13 +175,16 @@ load_current_bands (MMIfaceModem *_self, return; } - mm_base_modem_at_command ( - MM_BASE_MODEM (self), - "+UBANDSEL?", - 3, - FALSE, - (GAsyncReadyCallback)callback, - user_data); + if (self->priv->support_config.uact == FEATURE_SUPPORTED) { + mm_base_modem_at_command ( + MM_BASE_MODEM (self), + "+UACT?", + 3, + FALSE, + (GAsyncReadyCallback)callback, + user_data); + return; + } } /*****************************************************************************/ @@ -319,10 +271,11 @@ set_current_modes_bands_command_ready (MMBaseModem *self, ctx = (SetCurrentModesBandsContext *) g_task_get_task_data (task); g_assert (ctx); - mm_base_modem_at_command_finish (self, res, &ctx->saved_error); - - /* Go to next step (recover current power) regardless of the result */ - ctx->step++; + if (!mm_base_modem_at_command_finish (self, res, &ctx->saved_error)) + ctx->step = SET_CURRENT_MODES_BANDS_STEP_RELEASE; + else + ctx->step++; + set_current_modes_bands_step (task); } @@ -399,15 +352,28 @@ set_current_modes_bands_step (GTask *task) case SET_CURRENT_MODES_BANDS_STEP_POWER_DOWN: if (ctx->initial_state != MM_MODEM_POWER_STATE_LOW) { - mm_dbg ("powering down before configuration change..."); - mm_base_modem_at_command ( - MM_BASE_MODEM (ctx->self), - "+CFUN=4", - 3, - FALSE, - (GAsyncReadyCallback) set_current_modes_bands_low_power_ready, - task); - return; + mm_dbg ("powering down and deregistering from the network for configuration change..."); + if (ctx->self->priv->support_config.method == BAND_UPDATE_NEEDS_COPS) { + mm_base_modem_at_command ( + MM_BASE_MODEM (ctx->self), + "+COPS=2", + 10, + FALSE, + (GAsyncReadyCallback) set_current_modes_bands_low_power_ready, + task); + return; + } + + if (ctx->self->priv->support_config.method == BAND_UPDATE_NEEDS_CFUN) { + mm_base_modem_at_command ( + MM_BASE_MODEM (ctx->self), + "+CFUN=4", + 3, + FALSE, + (GAsyncReadyCallback) set_current_modes_bands_low_power_ready, + task); + return; + } } ctx->step++; /* fall down */ @@ -426,14 +392,37 @@ set_current_modes_bands_step (GTask *task) case SET_CURRENT_MODES_BANDS_STEP_RECOVER_CURRENT_POWER: if (ctx->initial_state != MM_MODEM_POWER_STATE_LOW) { mm_dbg ("recovering power state after configuration change..."); - mm_base_modem_at_command ( - MM_BASE_MODEM (ctx->self), - "+CFUN=1", - 3, - FALSE, - (GAsyncReadyCallback) set_current_modes_bands_recover_power_ready, - task); - return; + if (ctx->self->priv->support_config.method == BAND_UPDATE_NEEDS_COPS) { + gchar *command; + + /* If the user sent a specific network to use, lock it in. */ + if (ctx->self->priv->operator_id) + command = g_strdup_printf ("+COPS=1,2,\"%s\"", ctx->self->priv->operator_id); + else + command = g_strdup ("+COPS=0"); + + mm_base_modem_at_command ( + MM_BASE_MODEM (ctx->self), + command, + 10, + FALSE, + (GAsyncReadyCallback) set_current_modes_bands_recover_power_ready, + task); + g_free (command); + return; + } + + /* Use this to register if CFUN is needed */ + if (ctx->self->priv->support_config.method == BAND_UPDATE_NEEDS_CFUN) { + mm_base_modem_at_command ( + MM_BASE_MODEM (ctx->self), + "+CFUN=1", + 3, + FALSE, + (GAsyncReadyCallback) set_current_modes_bands_recover_power_ready, + task); + return; + } } ctx->step++; /* fall down */ @@ -490,18 +479,21 @@ set_current_bands (MMIfaceModem *_self, GAsyncReadyCallback callback, gpointer user_data) { - MMBroadbandModemUblox *self = MM_BROADBAND_MODEM_UBLOX (_self); + MMBroadbandModemUblox *self = MM_BROADBAND_MODEM_UBLOX (_self); GTask *task; - gchar *command; GError *error = NULL; + gchar *command; + const gchar *model; task = g_task_new (self, NULL, callback, user_data); + model = mm_iface_modem_get_model(_self); + /* Build command */ - if (self->priv->uact == FEATURE_SUPPORTED) + if (self->priv->support_config.uact == FEATURE_SUPPORTED) command = mm_ublox_build_uact_set_command (bands_array, &error); - else - command = mm_ublox_build_ubandsel_set_command (bands_array, &error); + else if (self->priv->support_config.ubandsel == FEATURE_SUPPORTED) + command = mm_ublox_build_ubandsel_set_command (bands_array, model, &error); if (!command) { g_task_return_error (task, error); @@ -674,6 +666,66 @@ common_modem_power_operation (MMBroadbandModemUblox *self, task); } +/*****************************************************************************/ +/* Register in network (3GPP interface) */ + +static gboolean +register_in_network_finish (MMIfaceModem3gpp *self, + GAsyncResult *res, + GError **error) +{ + return g_task_propagate_boolean (G_TASK (res), error); +} + +static void +cops_write_ready (MMBaseModem *_self, + GAsyncResult *res, + GTask *task) +{ + MMBroadbandModemUblox *self = MM_BROADBAND_MODEM_UBLOX (_self); + GError *error = NULL; + + if (!mm_base_modem_at_command_full_finish (_self, res, &error)) + g_task_return_error (task, error); + else { + g_free (self->priv->operator_id); + self->priv->operator_id = g_strdup (g_task_get_task_data (task)); + g_task_return_boolean (task, TRUE); + } + g_object_unref (task); +} + +static void +register_in_network (MMIfaceModem3gpp *self, + const gchar *operator_id, + GCancellable *cancellable, + GAsyncReadyCallback callback, + gpointer user_data) +{ + GTask *task; + gchar *command; + + task = g_task_new (self, cancellable, callback, user_data); + g_task_set_task_data (task, g_strdup (operator_id), g_free); + + /* If the user sent a specific network to use, lock it in. */ + if (operator_id) + command = g_strdup_printf ("+COPS=1,2,\"%s\"", operator_id); + else + command = g_strdup ("+COPS=0"); + + mm_base_modem_at_command_full (MM_BASE_MODEM (self), + mm_base_modem_peek_best_at_port (MM_BASE_MODEM (self), NULL), + command, + 120, + FALSE, + FALSE, /* raw */ + cancellable, + (GAsyncReadyCallback)cops_write_ready, + task); + g_free (command); +} + static void modem_reset (MMIfaceModem *self, GAsyncReadyCallback callback, @@ -1217,8 +1269,9 @@ mm_broadband_modem_ublox_init (MMBroadbandModemUblox *self) self->priv->profile = MM_UBLOX_USB_PROFILE_UNKNOWN; self->priv->mode = MM_UBLOX_NETWORKING_MODE_UNKNOWN; self->priv->any_allowed = MM_MODEM_MODE_NONE; - self->priv->uact = FEATURE_SUPPORT_UNKNOWN; - + self->priv->support_config.method = BAND_UPDATE_NEEDS_UNKNOWN; + self->priv->support_config.uact = FEATURE_SUPPORT_UNKNOWN; + self->priv->support_config.ubandsel = FEATURE_SUPPORT_UNKNOWN; self->priv->pbready_regex = g_regex_new ("\\r\\n\\+PBREADY\\r\\n", G_REGEX_RAW | G_REGEX_OPTIMIZE, 0, NULL); } @@ -1276,6 +1329,8 @@ finalize (GObject *object) g_regex_unref (self->priv->pbready_regex); + g_free (self->priv->operator_id); + G_OBJECT_CLASS (mm_broadband_modem_ublox_parent_class)->finalize (object); } diff --git a/plugins/ublox/mm-modem-helpers-ublox.c b/plugins/ublox/mm-modem-helpers-ublox.c index b6fd34d9..a988eaec 100644 --- a/plugins/ublox/mm-modem-helpers-ublox.c +++ b/plugins/ublox/mm-modem-helpers-ublox.c @@ -472,27 +472,507 @@ out: return combinations; } +typedef struct { + const gchar *model; + UpdateMethod method; + FeatureSupport uact; + FeatureSupport ubandsel; + MMModemMode mode; + MMModemBand bands_2g[4]; + MMModemBand bands_3g[6]; + MMModemBand bands_4g[12]; +} BandConfiguration; + +static const BandConfiguration band_configuration[] = { + { + .model = "SARA-G300", + .method = BAND_UPDATE_NEEDS_COPS, + .uact = FEATURE_UNSUPPORTED, + .ubandsel = FEATURE_SUPPORTED, + .mode = MM_MODEM_MODE_2G, + .bands_2g = { MM_MODEM_BAND_EGSM, MM_MODEM_BAND_DCS } + }, + { + .model = "SARA-G310", + .method = BAND_UPDATE_NEEDS_COPS, + .uact = FEATURE_UNSUPPORTED, + .ubandsel = FEATURE_SUPPORTED, + .mode = MM_MODEM_MODE_2G, + .bands_2g = { MM_MODEM_BAND_G850, MM_MODEM_BAND_EGSM, MM_MODEM_BAND_DCS, MM_MODEM_BAND_PCS } + }, + { + .model = "SARA-G340", + .method = BAND_UPDATE_NEEDS_COPS, + .uact = FEATURE_UNSUPPORTED, + .ubandsel = FEATURE_SUPPORTED, + .mode = MM_MODEM_MODE_2G, + .bands_2g = { MM_MODEM_BAND_EGSM, MM_MODEM_BAND_DCS } + }, + { + .model = "SARA-G350", + .method = BAND_UPDATE_NEEDS_COPS, + .uact = FEATURE_UNSUPPORTED, + .ubandsel = FEATURE_SUPPORTED, + .mode = MM_MODEM_MODE_2G, + .bands_2g = { MM_MODEM_BAND_G850, MM_MODEM_BAND_EGSM, MM_MODEM_BAND_DCS, MM_MODEM_BAND_PCS } + }, + { + .model = "SARA-G450", + .method = BAND_UPDATE_NEEDS_COPS, + .uact = FEATURE_UNSUPPORTED, + .ubandsel = FEATURE_SUPPORTED, + .mode = MM_MODEM_MODE_2G, + .bands_2g = { MM_MODEM_BAND_G850, MM_MODEM_BAND_EGSM, MM_MODEM_BAND_DCS, MM_MODEM_BAND_PCS } + }, + { + .model = "LISA-U200", + .method = BAND_UPDATE_NEEDS_COPS, + .uact = FEATURE_UNSUPPORTED, + .ubandsel = FEATURE_SUPPORTED, + .mode = MM_MODEM_MODE_2G | MM_MODEM_MODE_3G, + .bands_2g = { MM_MODEM_BAND_G850, MM_MODEM_BAND_EGSM, MM_MODEM_BAND_DCS, MM_MODEM_BAND_PCS }, + .bands_3g = { MM_MODEM_BAND_UTRAN_6, MM_MODEM_BAND_UTRAN_5, MM_MODEM_BAND_UTRAN_8, + MM_MODEM_BAND_UTRAN_4, MM_MODEM_BAND_UTRAN_2, MM_MODEM_BAND_UTRAN_1 } + }, + { + .model = "LISA-U201", + .method = BAND_UPDATE_NEEDS_COPS, + .uact = FEATURE_UNSUPPORTED, + .ubandsel = FEATURE_SUPPORTED, + .mode = MM_MODEM_MODE_2G | MM_MODEM_MODE_3G, + .bands_2g = { MM_MODEM_BAND_G850, MM_MODEM_BAND_EGSM, MM_MODEM_BAND_DCS, MM_MODEM_BAND_PCS }, + .bands_3g = { MM_MODEM_BAND_UTRAN_6, MM_MODEM_BAND_UTRAN_5, MM_MODEM_BAND_UTRAN_8, + MM_MODEM_BAND_UTRAN_2, MM_MODEM_BAND_UTRAN_1 } + }, + { + .model = "LISA-U230", + .method = BAND_UPDATE_NEEDS_COPS, + .uact = FEATURE_UNSUPPORTED, + .ubandsel = FEATURE_SUPPORTED, + .mode = MM_MODEM_MODE_2G | MM_MODEM_MODE_3G, + .bands_2g = { MM_MODEM_BAND_G850, MM_MODEM_BAND_EGSM, MM_MODEM_BAND_DCS, MM_MODEM_BAND_PCS }, + .bands_3g = { MM_MODEM_BAND_UTRAN_6, MM_MODEM_BAND_UTRAN_5, MM_MODEM_BAND_UTRAN_8, + MM_MODEM_BAND_UTRAN_4, MM_MODEM_BAND_UTRAN_2, MM_MODEM_BAND_UTRAN_1 } + }, + { + .model = "LISA-U260", + .method = BAND_UPDATE_NEEDS_COPS, + .uact = FEATURE_UNSUPPORTED, + .ubandsel = FEATURE_SUPPORTED, + .mode = MM_MODEM_MODE_2G | MM_MODEM_MODE_3G, + .bands_2g = { MM_MODEM_BAND_G850, MM_MODEM_BAND_EGSM, MM_MODEM_BAND_DCS, MM_MODEM_BAND_PCS }, + .bands_3g = { MM_MODEM_BAND_UTRAN_5, MM_MODEM_BAND_UTRAN_2 } + }, + { + .model = "LISA-U270", + .method = BAND_UPDATE_NEEDS_COPS, + .uact = FEATURE_UNSUPPORTED, + .ubandsel = FEATURE_SUPPORTED, + .mode = MM_MODEM_MODE_2G | MM_MODEM_MODE_3G, + .bands_2g = { MM_MODEM_BAND_G850, MM_MODEM_BAND_EGSM, MM_MODEM_BAND_DCS, MM_MODEM_BAND_PCS }, + .bands_3g = { MM_MODEM_BAND_UTRAN_8, MM_MODEM_BAND_UTRAN_1 } + }, + { + .model = "SARA-U201", + .method = BAND_UPDATE_NEEDS_COPS, + .uact = FEATURE_UNSUPPORTED, + .ubandsel = FEATURE_SUPPORTED, + .mode = MM_MODEM_MODE_2G | MM_MODEM_MODE_3G, + .bands_2g = { MM_MODEM_BAND_G850, MM_MODEM_BAND_EGSM, MM_MODEM_BAND_DCS, MM_MODEM_BAND_PCS }, + .bands_3g = { MM_MODEM_BAND_UTRAN_6, MM_MODEM_BAND_UTRAN_5, MM_MODEM_BAND_UTRAN_8, + MM_MODEM_BAND_UTRAN_2, MM_MODEM_BAND_UTRAN_1 } + }, + { + .model = "SARA-U260", + .method = BAND_UPDATE_NEEDS_COPS, + .uact = FEATURE_UNSUPPORTED, + .ubandsel = FEATURE_SUPPORTED, + .mode = MM_MODEM_MODE_2G | MM_MODEM_MODE_3G, + .bands_2g = { MM_MODEM_BAND_G850, MM_MODEM_BAND_PCS }, + .bands_3g = { MM_MODEM_BAND_UTRAN_5, MM_MODEM_BAND_UTRAN_2 } + }, + { + .model = "SARA-U270", + .method = BAND_UPDATE_NEEDS_COPS, + .uact = FEATURE_UNSUPPORTED, + .ubandsel = FEATURE_SUPPORTED, + .mode = MM_MODEM_MODE_2G | MM_MODEM_MODE_3G, + .bands_2g = { MM_MODEM_BAND_EGSM, MM_MODEM_BAND_DCS }, + .bands_3g = { MM_MODEM_BAND_UTRAN_8, MM_MODEM_BAND_UTRAN_1 } + }, + { + .model = "SARA-U280", + .method = BAND_UPDATE_NEEDS_COPS, + .uact = FEATURE_UNSUPPORTED, + .ubandsel = FEATURE_SUPPORTED, + .mode = MM_MODEM_MODE_3G, + .bands_3g = { MM_MODEM_BAND_UTRAN_5, MM_MODEM_BAND_UTRAN_2 } + }, + { + .model = "MPCI-L201", + .method = BAND_UPDATE_NEEDS_CFUN, + .uact = FEATURE_UNSUPPORTED, + .ubandsel = FEATURE_SUPPORTED, + .mode = MM_MODEM_MODE_3G | MM_MODEM_MODE_4G, + .bands_3g = { MM_MODEM_BAND_UTRAN_5, MM_MODEM_BAND_UTRAN_2 }, + .bands_4g = { MM_MODEM_BAND_EUTRAN_2, MM_MODEM_BAND_EUTRAN_4, MM_MODEM_BAND_EUTRAN_5, + MM_MODEM_BAND_EUTRAN_13, MM_MODEM_BAND_EUTRAN_17 } + }, + { + .model = "MPCI-L200", + .method = BAND_UPDATE_NEEDS_CFUN, + .uact = FEATURE_UNSUPPORTED, + .ubandsel = FEATURE_SUPPORTED, + .mode = MM_MODEM_MODE_2G | MM_MODEM_MODE_3G | MM_MODEM_MODE_4G, + .bands_2g = { MM_MODEM_BAND_G850, MM_MODEM_BAND_EGSM, MM_MODEM_BAND_DCS, MM_MODEM_BAND_PCS }, + .bands_3g = { MM_MODEM_BAND_UTRAN_5, MM_MODEM_BAND_UTRAN_8, MM_MODEM_BAND_UTRAN_4, + MM_MODEM_BAND_UTRAN_2, MM_MODEM_BAND_UTRAN_1 }, + .bands_4g = { MM_MODEM_BAND_EUTRAN_2, MM_MODEM_BAND_EUTRAN_4, MM_MODEM_BAND_EUTRAN_5, + MM_MODEM_BAND_EUTRAN_7, MM_MODEM_BAND_EUTRAN_17 } + }, + { + .model = "MPCI-L210", + .method = BAND_UPDATE_NEEDS_CFUN, + .uact = FEATURE_UNSUPPORTED, + .ubandsel = FEATURE_SUPPORTED, + .mode = MM_MODEM_MODE_2G | MM_MODEM_MODE_3G | MM_MODEM_MODE_4G, + .bands_2g = { MM_MODEM_BAND_G850, MM_MODEM_BAND_EGSM, MM_MODEM_BAND_DCS, MM_MODEM_BAND_PCS }, + .bands_3g = { MM_MODEM_BAND_UTRAN_5, MM_MODEM_BAND_UTRAN_8, MM_MODEM_BAND_UTRAN_2, + MM_MODEM_BAND_UTRAN_1 }, + .bands_4g = { MM_MODEM_BAND_EUTRAN_1, MM_MODEM_BAND_EUTRAN_3, MM_MODEM_BAND_EUTRAN_5, + MM_MODEM_BAND_EUTRAN_7, MM_MODEM_BAND_EUTRAN_8, MM_MODEM_BAND_EUTRAN_20 } + }, + { + .model = "MPCI-L220", + .method = BAND_UPDATE_NEEDS_CFUN, + .uact = FEATURE_UNSUPPORTED, + .ubandsel = FEATURE_SUPPORTED, + .mode = MM_MODEM_MODE_3G | MM_MODEM_MODE_4G, + .bands_3g = { MM_MODEM_BAND_UTRAN_5, MM_MODEM_BAND_UTRAN_8, MM_MODEM_BAND_UTRAN_1 }, + .bands_4g = { MM_MODEM_BAND_EUTRAN_1, MM_MODEM_BAND_EUTRAN_3, MM_MODEM_BAND_EUTRAN_5, + MM_MODEM_BAND_EUTRAN_8, MM_MODEM_BAND_EUTRAN_19 } + }, + { + .model = "MPCI-L280", + .method = BAND_UPDATE_NEEDS_CFUN, + .uact = FEATURE_UNSUPPORTED, + .ubandsel = FEATURE_SUPPORTED, + .mode = MM_MODEM_MODE_2G | MM_MODEM_MODE_3G | MM_MODEM_MODE_4G, + .bands_2g = { MM_MODEM_BAND_G850, MM_MODEM_BAND_EGSM, MM_MODEM_BAND_DCS, MM_MODEM_BAND_PCS }, + .bands_3g = { MM_MODEM_BAND_UTRAN_5, MM_MODEM_BAND_UTRAN_8, MM_MODEM_BAND_UTRAN_2, + MM_MODEM_BAND_UTRAN_1 }, + .bands_4g = { MM_MODEM_BAND_EUTRAN_1, MM_MODEM_BAND_EUTRAN_3, MM_MODEM_BAND_EUTRAN_5, + MM_MODEM_BAND_EUTRAN_7, MM_MODEM_BAND_EUTRAN_8, MM_MODEM_BAND_EUTRAN_28 } + }, + { + .model = "TOBY-L200", + .method = BAND_UPDATE_NEEDS_CFUN, + .uact = FEATURE_UNSUPPORTED, + .ubandsel = FEATURE_SUPPORTED, + .mode = MM_MODEM_MODE_2G | MM_MODEM_MODE_3G | MM_MODEM_MODE_4G, + .bands_2g = { MM_MODEM_BAND_G850, MM_MODEM_BAND_EGSM, MM_MODEM_BAND_DCS, MM_MODEM_BAND_PCS }, + .bands_3g = { MM_MODEM_BAND_UTRAN_5, MM_MODEM_BAND_UTRAN_8, MM_MODEM_BAND_UTRAN_4, + MM_MODEM_BAND_UTRAN_2, MM_MODEM_BAND_UTRAN_1 }, + .bands_4g = { MM_MODEM_BAND_EUTRAN_2, MM_MODEM_BAND_EUTRAN_4, MM_MODEM_BAND_EUTRAN_5, + MM_MODEM_BAND_EUTRAN_7, MM_MODEM_BAND_EUTRAN_17 } + }, + { + .model = "TOBY-L201", + .method = BAND_UPDATE_NEEDS_CFUN, + .uact = FEATURE_UNSUPPORTED, + .ubandsel = FEATURE_SUPPORTED, + .mode = MM_MODEM_MODE_3G | MM_MODEM_MODE_4G, + .bands_3g = { MM_MODEM_BAND_UTRAN_5, MM_MODEM_BAND_UTRAN_2 }, + .bands_4g = { MM_MODEM_BAND_EUTRAN_2, MM_MODEM_BAND_EUTRAN_4, MM_MODEM_BAND_EUTRAN_5, + MM_MODEM_BAND_EUTRAN_13, MM_MODEM_BAND_EUTRAN_17 } + }, + { + .model = "TOBY-L210", + .method = BAND_UPDATE_NEEDS_CFUN, + .uact = FEATURE_UNSUPPORTED, + .ubandsel = FEATURE_SUPPORTED, + .mode = MM_MODEM_MODE_2G | MM_MODEM_MODE_3G | MM_MODEM_MODE_4G, + .bands_2g = { MM_MODEM_BAND_G850, MM_MODEM_BAND_EGSM, MM_MODEM_BAND_DCS, MM_MODEM_BAND_PCS }, + .bands_3g = { MM_MODEM_BAND_UTRAN_5, MM_MODEM_BAND_UTRAN_8, MM_MODEM_BAND_UTRAN_2, + MM_MODEM_BAND_UTRAN_1 }, + .bands_4g = { MM_MODEM_BAND_EUTRAN_1, MM_MODEM_BAND_EUTRAN_3, MM_MODEM_BAND_EUTRAN_5, + MM_MODEM_BAND_EUTRAN_7, MM_MODEM_BAND_EUTRAN_8, MM_MODEM_BAND_EUTRAN_20 } + }, + { + .model = "TOBY-L220", + .method = BAND_UPDATE_NEEDS_CFUN, + .uact = FEATURE_UNSUPPORTED, + .ubandsel = FEATURE_SUPPORTED, + .mode = MM_MODEM_MODE_3G | MM_MODEM_MODE_4G, + .bands_3g = { MM_MODEM_BAND_UTRAN_5, MM_MODEM_BAND_UTRAN_8, MM_MODEM_BAND_UTRAN_2, + MM_MODEM_BAND_UTRAN_1 }, + .bands_4g = { MM_MODEM_BAND_EUTRAN_1, MM_MODEM_BAND_EUTRAN_3, MM_MODEM_BAND_EUTRAN_5, + MM_MODEM_BAND_EUTRAN_8, MM_MODEM_BAND_EUTRAN_19 } + }, + { + .model = "TOBY-L280", + .method = BAND_UPDATE_NEEDS_CFUN, + .uact = FEATURE_UNSUPPORTED, + .ubandsel = FEATURE_SUPPORTED, + .mode = MM_MODEM_MODE_2G | MM_MODEM_MODE_3G | MM_MODEM_MODE_4G, + .bands_2g = { MM_MODEM_BAND_G850, MM_MODEM_BAND_EGSM, MM_MODEM_BAND_DCS, MM_MODEM_BAND_PCS }, + .bands_3g = { MM_MODEM_BAND_UTRAN_5, MM_MODEM_BAND_UTRAN_8, MM_MODEM_BAND_UTRAN_2, + MM_MODEM_BAND_UTRAN_1 }, + .bands_4g = { MM_MODEM_BAND_EUTRAN_1, MM_MODEM_BAND_EUTRAN_3, MM_MODEM_BAND_EUTRAN_5, + MM_MODEM_BAND_EUTRAN_7, MM_MODEM_BAND_EUTRAN_8, MM_MODEM_BAND_EUTRAN_28 } + }, + { + .model = "TOBY-L4006", + .method = BAND_UPDATE_NEEDS_CFUN, + .uact = FEATURE_SUPPORTED, + .ubandsel = FEATURE_UNSUPPORTED, + .mode = MM_MODEM_MODE_2G | MM_MODEM_MODE_3G | MM_MODEM_MODE_4G, + .bands_2g = { MM_MODEM_BAND_G850, MM_MODEM_BAND_PCS }, + .bands_3g = { MM_MODEM_BAND_UTRAN_5, MM_MODEM_BAND_UTRAN_4, MM_MODEM_BAND_UTRAN_2 }, + .bands_4g = { MM_MODEM_BAND_EUTRAN_2, MM_MODEM_BAND_EUTRAN_4, MM_MODEM_BAND_EUTRAN_5, + MM_MODEM_BAND_EUTRAN_7, MM_MODEM_BAND_EUTRAN_12, MM_MODEM_BAND_EUTRAN_13, + MM_MODEM_BAND_EUTRAN_29 } + }, + { + .model = "TOBY-L4106", + .method = BAND_UPDATE_NEEDS_CFUN, + .uact = FEATURE_SUPPORTED, + .ubandsel = FEATURE_UNSUPPORTED, + .mode = MM_MODEM_MODE_2G | MM_MODEM_MODE_3G | MM_MODEM_MODE_4G, + .bands_2g = { MM_MODEM_BAND_EGSM, MM_MODEM_BAND_DCS }, + .bands_3g = { MM_MODEM_BAND_UTRAN_8, MM_MODEM_BAND_UTRAN_1 }, + .bands_4g = { MM_MODEM_BAND_EUTRAN_1, MM_MODEM_BAND_EUTRAN_3, MM_MODEM_BAND_EUTRAN_7, + MM_MODEM_BAND_EUTRAN_8, MM_MODEM_BAND_EUTRAN_20, MM_MODEM_BAND_EUTRAN_38 } + }, + { + .model = "TOBY-L4206", + .method = BAND_UPDATE_NEEDS_CFUN, + .uact = FEATURE_SUPPORTED, + .ubandsel = FEATURE_UNSUPPORTED, + .mode = MM_MODEM_MODE_2G | MM_MODEM_MODE_3G | MM_MODEM_MODE_4G, + .bands_2g = { MM_MODEM_BAND_G850, MM_MODEM_BAND_EGSM, MM_MODEM_BAND_DCS, MM_MODEM_BAND_PCS }, + .bands_3g = { MM_MODEM_BAND_UTRAN_5, MM_MODEM_BAND_UTRAN_8, MM_MODEM_BAND_UTRAN_1 }, + .bands_4g = { MM_MODEM_BAND_EUTRAN_1, MM_MODEM_BAND_EUTRAN_3, MM_MODEM_BAND_EUTRAN_5, + MM_MODEM_BAND_EUTRAN_7, MM_MODEM_BAND_EUTRAN_8, MM_MODEM_BAND_EUTRAN_9, + MM_MODEM_BAND_EUTRAN_19, MM_MODEM_BAND_EUTRAN_28 } + }, + { + .model = "TOBY-L4906", + .method = BAND_UPDATE_NEEDS_CFUN, + .uact = FEATURE_SUPPORTED, + .ubandsel = FEATURE_UNSUPPORTED, + .mode = MM_MODEM_MODE_2G | MM_MODEM_MODE_3G | MM_MODEM_MODE_4G, + .bands_2g = { MM_MODEM_BAND_EGSM, MM_MODEM_BAND_DCS }, + .bands_3g = { MM_MODEM_BAND_UTRAN_8, MM_MODEM_BAND_UTRAN_1 }, + .bands_4g = { MM_MODEM_BAND_EUTRAN_1, MM_MODEM_BAND_EUTRAN_3, MM_MODEM_BAND_EUTRAN_39, + MM_MODEM_BAND_EUTRAN_40, MM_MODEM_BAND_EUTRAN_41 } + }, + { + .model = "TOBY-R200", + .method = BAND_UPDATE_NEEDS_COPS, + .uact = FEATURE_UNSUPPORTED, + .ubandsel = FEATURE_SUPPORTED, + .mode = MM_MODEM_MODE_2G | MM_MODEM_MODE_3G | MM_MODEM_MODE_4G, + .bands_2g = { MM_MODEM_BAND_G850, MM_MODEM_BAND_EGSM, MM_MODEM_BAND_DCS, MM_MODEM_BAND_PCS }, + .bands_3g = { MM_MODEM_BAND_UTRAN_5, MM_MODEM_BAND_UTRAN_8, MM_MODEM_BAND_UTRAN_2, + MM_MODEM_BAND_UTRAN_1 }, + .bands_4g = { MM_MODEM_BAND_EUTRAN_2, MM_MODEM_BAND_EUTRAN_4, MM_MODEM_BAND_EUTRAN_5, + MM_MODEM_BAND_EUTRAN_12 } + }, + { + .model = "TOBY-R202", + .method = BAND_UPDATE_NEEDS_COPS, + .uact = FEATURE_UNSUPPORTED, + .ubandsel = FEATURE_SUPPORTED, + .mode = MM_MODEM_MODE_3G | MM_MODEM_MODE_4G, + .bands_3g = { MM_MODEM_BAND_UTRAN_5, MM_MODEM_BAND_UTRAN_2 }, + .bands_4g = { MM_MODEM_BAND_EUTRAN_2, MM_MODEM_BAND_EUTRAN_4, MM_MODEM_BAND_EUTRAN_5, + MM_MODEM_BAND_EUTRAN_12 } + }, + { + .model = "LARA-R202", + .method = BAND_UPDATE_NEEDS_COPS, + .uact = FEATURE_UNSUPPORTED, + .ubandsel = FEATURE_SUPPORTED, + .mode = MM_MODEM_MODE_3G | MM_MODEM_MODE_4G, + .bands_3g = { MM_MODEM_BAND_UTRAN_5, MM_MODEM_BAND_UTRAN_2 }, + .bands_4g = { MM_MODEM_BAND_EUTRAN_2, MM_MODEM_BAND_EUTRAN_4, MM_MODEM_BAND_EUTRAN_5, + MM_MODEM_BAND_EUTRAN_12 } + }, + { + .model = "LARA-R203", + .method = BAND_UPDATE_NEEDS_COPS, + .uact = FEATURE_UNSUPPORTED, + .ubandsel = FEATURE_SUPPORTED, + .mode = MM_MODEM_MODE_4G, + .bands_4g = { MM_MODEM_BAND_EUTRAN_2, MM_MODEM_BAND_EUTRAN_4, MM_MODEM_BAND_EUTRAN_12 } + }, + { + .model = "LARA-R204", + .method = BAND_UPDATE_NEEDS_COPS, + .uact = FEATURE_UNSUPPORTED, + .ubandsel = FEATURE_SUPPORTED, + .mode = MM_MODEM_MODE_4G, + .bands_4g = { MM_MODEM_BAND_EUTRAN_4, MM_MODEM_BAND_EUTRAN_13 } + }, + { + .model = "LARA-R211", + .method = BAND_UPDATE_NEEDS_COPS, + .uact = FEATURE_UNSUPPORTED, + .ubandsel = FEATURE_SUPPORTED, + .mode = MM_MODEM_MODE_2G | MM_MODEM_MODE_4G, + .bands_2g = { MM_MODEM_BAND_EGSM, MM_MODEM_BAND_DCS }, + .bands_4g = { MM_MODEM_BAND_EUTRAN_3, MM_MODEM_BAND_EUTRAN_7, MM_MODEM_BAND_EUTRAN_20 } + }, + { + .model = "LARA-R280", + .method = BAND_UPDATE_NEEDS_COPS, + .uact = FEATURE_UNSUPPORTED, + .ubandsel = FEATURE_SUPPORTED, + .mode = MM_MODEM_MODE_3G | MM_MODEM_MODE_4G, + .bands_3g = { MM_MODEM_BAND_UTRAN_1 }, + .bands_4g = { MM_MODEM_BAND_EUTRAN_3, MM_MODEM_BAND_EUTRAN_8, MM_MODEM_BAND_EUTRAN_28 } + }, + { + .model = "LARA-R3121", + .method = BAND_UPDATE_NEEDS_UNKNOWN, + .uact = FEATURE_SUPPORT_UNKNOWN, + .uact = FEATURE_SUPPORT_UNKNOWN, + .mode = MM_MODEM_MODE_4G, + .bands_4g = { MM_MODEM_BAND_EUTRAN_3, MM_MODEM_BAND_EUTRAN_7, MM_MODEM_BAND_EUTRAN_20 } + }, + { + .model = "SARA-N200", + .method = BAND_UPDATE_NEEDS_UNKNOWN, + .uact = FEATURE_SUPPORT_UNKNOWN, + .uact = FEATURE_SUPPORT_UNKNOWN, + .mode = MM_MODEM_MODE_4G, + .bands_4g = { MM_MODEM_BAND_EUTRAN_8 } + }, + { + .model = "SARA-N201", + .method = BAND_UPDATE_NEEDS_UNKNOWN, + .uact = FEATURE_SUPPORT_UNKNOWN, + .uact = FEATURE_SUPPORT_UNKNOWN, + .mode = MM_MODEM_MODE_4G, + .bands_4g = { MM_MODEM_BAND_EUTRAN_5 } + }, + { + .model = "SARA-N210", + .method = BAND_UPDATE_NEEDS_UNKNOWN, + .uact = FEATURE_SUPPORT_UNKNOWN, + .uact = FEATURE_SUPPORT_UNKNOWN, + .mode = MM_MODEM_MODE_4G, + .bands_4g = { MM_MODEM_BAND_EUTRAN_20 } + }, + { + .model = "SARA-N211", + .method = BAND_UPDATE_NEEDS_UNKNOWN, + .uact = FEATURE_SUPPORT_UNKNOWN, + .uact = FEATURE_SUPPORT_UNKNOWN, + .mode = MM_MODEM_MODE_4G, + .bands_4g = { MM_MODEM_BAND_EUTRAN_8, MM_MODEM_BAND_EUTRAN_20 } + }, + { + .model = "SARA-N280", + .method = BAND_UPDATE_NEEDS_UNKNOWN, + .uact = FEATURE_SUPPORT_UNKNOWN, + .uact = FEATURE_SUPPORT_UNKNOWN, + .mode = MM_MODEM_MODE_4G, + .bands_4g = { MM_MODEM_BAND_EUTRAN_28 } + }, + { + .model = "SARA-R410M-52B", + .method = BAND_UPDATE_NEEDS_UNKNOWN, + .uact = FEATURE_SUPPORT_UNKNOWN, + .uact = FEATURE_SUPPORT_UNKNOWN, + .mode = MM_MODEM_MODE_4G, + .bands_4g = { MM_MODEM_BAND_EUTRAN_2, MM_MODEM_BAND_EUTRAN_4, MM_MODEM_BAND_EUTRAN_5, + MM_MODEM_BAND_EUTRAN_12, MM_MODEM_BAND_EUTRAN_13 } + }, + { + .model = "SARA-R410M-02B", + .method = BAND_UPDATE_NEEDS_UNKNOWN, + .uact = FEATURE_SUPPORT_UNKNOWN, + .uact = FEATURE_SUPPORT_UNKNOWN, + .mode = MM_MODEM_MODE_4G, + .bands_4g = { MM_MODEM_BAND_EUTRAN_1, MM_MODEM_BAND_EUTRAN_2, MM_MODEM_BAND_EUTRAN_3, + MM_MODEM_BAND_EUTRAN_4, MM_MODEM_BAND_EUTRAN_5, MM_MODEM_BAND_EUTRAN_8, + MM_MODEM_BAND_EUTRAN_12, MM_MODEM_BAND_EUTRAN_13, MM_MODEM_BAND_EUTRAN_19, + MM_MODEM_BAND_EUTRAN_20, MM_MODEM_BAND_EUTRAN_28, MM_MODEM_BAND_EUTRAN_39 } + }, + { + .model = "SARA-R412M-02B", + .method = BAND_UPDATE_NEEDS_UNKNOWN, + .uact = FEATURE_SUPPORT_UNKNOWN, + .uact = FEATURE_SUPPORT_UNKNOWN, + .mode = MM_MODEM_MODE_2G | MM_MODEM_MODE_4G, + .bands_2g = { MM_MODEM_BAND_G850, MM_MODEM_BAND_EGSM, MM_MODEM_BAND_DCS, MM_MODEM_BAND_PCS }, + .bands_4g = { MM_MODEM_BAND_EUTRAN_1, MM_MODEM_BAND_EUTRAN_2, MM_MODEM_BAND_EUTRAN_3, + MM_MODEM_BAND_EUTRAN_4, MM_MODEM_BAND_EUTRAN_5, MM_MODEM_BAND_EUTRAN_8, + MM_MODEM_BAND_EUTRAN_12, MM_MODEM_BAND_EUTRAN_13, MM_MODEM_BAND_EUTRAN_19, + MM_MODEM_BAND_EUTRAN_20, MM_MODEM_BAND_EUTRAN_28, MM_MODEM_BAND_EUTRAN_39 } + }, + { + .model = "SARA-N410-02B", + .method = BAND_UPDATE_NEEDS_UNKNOWN, + .uact = FEATURE_SUPPORT_UNKNOWN, + .uact = FEATURE_SUPPORT_UNKNOWN, + .mode = MM_MODEM_MODE_4G, + .bands_4g = { MM_MODEM_BAND_EUTRAN_1, MM_MODEM_BAND_EUTRAN_2, MM_MODEM_BAND_EUTRAN_3, + MM_MODEM_BAND_EUTRAN_4, MM_MODEM_BAND_EUTRAN_5, MM_MODEM_BAND_EUTRAN_8, + MM_MODEM_BAND_EUTRAN_12, MM_MODEM_BAND_EUTRAN_13, MM_MODEM_BAND_EUTRAN_19, + MM_MODEM_BAND_EUTRAN_20, MM_MODEM_BAND_EUTRAN_28 } + }, +}; + +/* Returns AT command support configuration */ + +gboolean mm_ublox_get_support_config (const gchar *model, + UbloxSupportConfig *config, + GError **error) +{ + guint i; + + if (model) { + for (i = 0; i < G_N_ELEMENTS (band_configuration); i++) + if (g_str_has_prefix (model, band_configuration[i].model)) { + config->method = band_configuration[i].method; + config->uact = band_configuration[i].uact; + config->ubandsel = band_configuration[i].ubandsel; + return TRUE; + } + } + + if (i == G_N_ELEMENTS (band_configuration) || !(model)) { + g_set_error (error, MM_CORE_ERROR, MM_CORE_ERROR_FAILED, + "Unknown support found for modem: %s", model); + return FALSE; + } + + return FALSE; +} + /*****************************************************************************/ +/* Supported modes loading */ static MMModemMode supported_modes_per_model (const gchar *model) { - MMModemMode all = (MM_MODEM_MODE_2G | MM_MODEM_MODE_3G | MM_MODEM_MODE_4G); + MMModemMode mode; + guint i; + + mode = MM_MODEM_MODE_2G | MM_MODEM_MODE_3G | MM_MODEM_MODE_4G; if (model) { - /* Some TOBY-L2/MPCI-L2 devices don't support 2G */ - if (g_str_equal (model, "TOBY-L201") || g_str_equal (model, "TOBY-L220") || g_str_equal (model, "MPCI-L201")) - all &= ~MM_MODEM_MODE_2G; - /* None of the LISA-U or SARA-U devices support 4G */ - else if (g_str_has_prefix (model, "LISA-U") || g_str_has_prefix (model, "SARA-U")) { - all &= ~MM_MODEM_MODE_4G; - /* Some SARA devices don't support 2G */ - if (g_str_equal (model, "SARA-U270-53S") || g_str_equal (model, "SARA-U280")) - all &= ~MM_MODEM_MODE_2G; - } + for (i = 0; i < G_N_ELEMENTS (band_configuration); i++) + if (g_str_has_prefix (model, band_configuration[i].model)) { + mode = band_configuration[i].mode; + return mode;; + } } - return all; + return mode; } GArray * @@ -538,99 +1018,49 @@ mm_ublox_filter_supported_modes (const gchar *model, /*****************************************************************************/ /* Supported bands loading */ -typedef struct { - guint ubandsel_value; - MMModemBand bands_2g[2]; - MMModemBand bands_3g[2]; - MMModemBand bands_4g[2]; -} BandConfiguration; - -static const BandConfiguration band_configuration[] = { - { - .ubandsel_value = 700, - .bands_4g = { MM_MODEM_BAND_EUTRAN_13, MM_MODEM_BAND_EUTRAN_17 } - }, - { - .ubandsel_value = 800, - .bands_3g = { MM_MODEM_BAND_UTRAN_6 }, - .bands_4g = { MM_MODEM_BAND_EUTRAN_20 } - }, - { - .ubandsel_value = 850, - .bands_2g = { MM_MODEM_BAND_G850 }, - .bands_3g = { MM_MODEM_BAND_UTRAN_5 }, - .bands_4g = { MM_MODEM_BAND_EUTRAN_5 } - }, - { - .ubandsel_value = 900, - .bands_2g = { MM_MODEM_BAND_EGSM }, - .bands_3g = { MM_MODEM_BAND_UTRAN_8 }, - .bands_4g = { MM_MODEM_BAND_EUTRAN_8 } - }, - { - .ubandsel_value = 1500, - .bands_3g = { MM_MODEM_BAND_UTRAN_11 }, - .bands_4g = { MM_MODEM_BAND_EUTRAN_11 } - }, - { - .ubandsel_value = 1700, - .bands_3g = { MM_MODEM_BAND_UTRAN_4 }, - .bands_4g = { MM_MODEM_BAND_EUTRAN_4 } - }, - { - .ubandsel_value = 1800, - .bands_2g = { MM_MODEM_BAND_DCS }, - .bands_3g = { MM_MODEM_BAND_UTRAN_3 }, - .bands_4g = { MM_MODEM_BAND_EUTRAN_3 } - }, - { - .ubandsel_value = 1900, - .bands_2g = { MM_MODEM_BAND_PCS }, - .bands_3g = { MM_MODEM_BAND_UTRAN_2 }, - .bands_4g = { MM_MODEM_BAND_EUTRAN_2 } - }, - { - .ubandsel_value = 2100, - .bands_3g = { MM_MODEM_BAND_UTRAN_1 }, - .bands_4g = { MM_MODEM_BAND_EUTRAN_1 } - }, - { - .ubandsel_value = 2600, - .bands_3g = { MM_MODEM_BAND_UTRAN_7 }, - .bands_4g = { MM_MODEM_BAND_EUTRAN_7 } - }, -}; - GArray * mm_ublox_get_supported_bands (const gchar *model, GError **error) { MMModemMode mode; GArray *bands; - guint i; - - mode = supported_modes_per_model (model); + guint i, j; + mode = supported_modes_per_model (model); bands = g_array_new (FALSE, FALSE, sizeof (MMModemBand)); for (i = 0; i < G_N_ELEMENTS (band_configuration); i++) { - if ((mode & MM_MODEM_MODE_2G) && band_configuration[i].bands_2g[0]) { - bands = g_array_append_val (bands, band_configuration[i].bands_2g[0]); - if (band_configuration[i].bands_2g[1]) - bands = g_array_append_val (bands, band_configuration[i].bands_2g[1]); + if (g_str_has_prefix (model, band_configuration[i].model)) { + mm_dbg("Found Model (Supported Bands): %s", band_configuration[i].model); + break; } - if ((mode & MM_MODEM_MODE_3G) && band_configuration[i].bands_3g[0]) { - bands = g_array_append_val (bands, band_configuration[i].bands_3g[0]); - if (band_configuration[i].bands_3g[1]) - bands = g_array_append_val (bands, band_configuration[i].bands_3g[1]); + } + + if (i == G_N_ELEMENTS (band_configuration)) { + mm_warn ("Unknown model name given: %s", model); + return NULL; + } + + mode = band_configuration[i].mode; + + if (mode & MM_MODEM_MODE_2G) { + for (j = 0; band_configuration[i].bands_2g[j] && j < G_N_ELEMENTS (band_configuration[i].bands_2g); j++) { + bands = g_array_append_val (bands, band_configuration[i].bands_2g[j]); } - if ((mode & MM_MODEM_MODE_4G) && band_configuration[i].bands_4g[0]) { - bands = g_array_append_val (bands, band_configuration[i].bands_4g[0]); - if (band_configuration[i].bands_4g[1]) - bands = g_array_append_val (bands, band_configuration[i].bands_4g[1]); + } + + if (mode & MM_MODEM_MODE_3G) { + for (j = 0; band_configuration[i].bands_3g[j] && j < G_N_ELEMENTS (band_configuration[i].bands_3g); j++) { + bands = g_array_append_val (bands, band_configuration[i].bands_3g[j]); } } + if (mode & MM_MODEM_MODE_4G) { + for (j = 0; band_configuration[i].bands_4g[j] && j < G_N_ELEMENTS (band_configuration[i].bands_4g); j++) { + bands = g_array_append_val (bands, band_configuration[i].bands_4g[j]); + } + } + if (bands->len == 0) { g_array_unref (bands); g_set_error (error, MM_CORE_ERROR, MM_CORE_ERROR_FAILED, @@ -641,49 +1071,158 @@ mm_ublox_get_supported_bands (const gchar *model, return bands; } +typedef struct { + guint num; + MMModemBand band[4]; +} NumToBand; + +/* 2G GSM Band Frequencies */ +static const NumToBand num_bands_2g [] = { + { .num = 850, .band = { MM_MODEM_BAND_G850 } }, + { .num = 900, .band = { MM_MODEM_BAND_EGSM } }, + { .num = 1900, .band = { MM_MODEM_BAND_PCS } }, + { .num = 1800, .band = { MM_MODEM_BAND_DCS } }, +}; + +/* 3G UMTS Band Frequencies */ +static const NumToBand num_bands_3g [] = { + { .num = 800, .band = { MM_MODEM_BAND_UTRAN_6 } }, + { .num = 850, .band = { MM_MODEM_BAND_UTRAN_5 } }, + { .num = 900, .band = { MM_MODEM_BAND_UTRAN_8 } }, + { .num = 1700, .band = { MM_MODEM_BAND_UTRAN_4 } }, + { .num = 1900, .band = { MM_MODEM_BAND_UTRAN_2 } }, + { .num = 2100, .band = { MM_MODEM_BAND_UTRAN_1 } }, +}; + +/* 4G LTE Band Frequencies */ +static const NumToBand num_bands_4g [] = { + { .num = 700, .band = { MM_MODEM_BAND_EUTRAN_12, MM_MODEM_BAND_EUTRAN_13, MM_MODEM_BAND_EUTRAN_17 } }, + { .num = 800, .band = { MM_MODEM_BAND_EUTRAN_20, MM_MODEM_BAND_EUTRAN_27 } }, + { .num = 850, .band = { MM_MODEM_BAND_EUTRAN_5, MM_MODEM_BAND_EUTRAN_18, MM_MODEM_BAND_EUTRAN_19, MM_MODEM_BAND_EUTRAN_26 } }, + { .num = 900, .band = { MM_MODEM_BAND_EUTRAN_8 } }, + { .num = 1700, .band = { MM_MODEM_BAND_EUTRAN_4, MM_MODEM_BAND_EUTRAN_10 } }, + { .num = 1800, .band = { MM_MODEM_BAND_EUTRAN_3 } }, + { .num = 1900, .band = { MM_MODEM_BAND_EUTRAN_2, MM_MODEM_BAND_EUTRAN_39 } }, + { .num = 2100, .band = { MM_MODEM_BAND_EUTRAN_1 } }, + { .num = 2300, .band = { MM_MODEM_BAND_EUTRAN_40 } }, + { .num = 2500, .band = { MM_MODEM_BAND_EUTRAN_41 } }, + { .num = 2600, .band = { MM_MODEM_BAND_EUTRAN_7, MM_MODEM_BAND_EUTRAN_38 } }, +}; /*****************************************************************************/ /* +UBANDSEL? response parser */ +static MMModemBand num_to_band_2g (guint num) { + guint i; + + for (i = 0; i < G_N_ELEMENTS (num_bands_2g); i++) { + if (num == num_bands_2g[i].num) + return num_bands_2g[i].band[0]; + } + return MM_MODEM_BAND_UNKNOWN; +} + +static MMModemBand num_to_band_3g (guint num) { + guint i; + + for (i = 0; i < G_N_ELEMENTS (num_bands_3g); i++) { + if (num == num_bands_3g[i].num) + return num_bands_3g[i].band[0]; + } + return MM_MODEM_BAND_UNKNOWN; +} + +static guint band_to_num (MMModemBand band) { + guint i, j; + guint num = 0; + + /* Search 2G list */ + for (i = 0; i < G_N_ELEMENTS (num_bands_2g); i++) { + for (j = 0; num_bands_2g[i].band[j] && j < G_N_ELEMENTS(num_bands_2g[i].band); j++) { + if (band == num_bands_2g[i].band[j]) { + num = num_bands_2g[i].num; + return num; + } + } + } + + /* Search 3G list */ + for (i = 0; i < G_N_ELEMENTS (num_bands_3g); i++) { + for (j = 0; num_bands_3g[i].band[j] && j < G_N_ELEMENTS(num_bands_3g[i].band); j++) { + if (band == num_bands_3g[i].band[j]) { + num = num_bands_3g[i].num; + return num; + } + } + } + + /* Search 4G list */ + for (i = 0; i < G_N_ELEMENTS (num_bands_4g); i++) { + for (j = 0; num_bands_4g[i].band[j] && j < G_N_ELEMENTS(num_bands_4g[i].band); j++) { + if (band == num_bands_4g[i].band[j]) { + num = num_bands_4g[i].num; + return num; + } + } + } + + return num; +} + static void append_bands (GArray *bands, - guint ubandsel_value) + guint ubandsel_value, + MMModemMode mode, + const gchar *model) { - guint i; + guint i, j, k, x; - for (i = 0; i < G_N_ELEMENTS (band_configuration); i++) - if (ubandsel_value == band_configuration[i].ubandsel_value) + MMModemBand band; + + /* Find Modem Model Index in band_configuration */ + for (i = 0; i < G_N_ELEMENTS (band_configuration); i++) { + if (g_str_has_prefix (model, band_configuration[i].model)) break; + } if (i == G_N_ELEMENTS (band_configuration)) { - mm_warn ("Unknown band configuration value given: %u", ubandsel_value); + mm_warn ("Unknown Modem Model given: %s", model); return; } - /* Note: we don't care if the device doesn't support one of these modes; - * the generic logic will filter out all bands not supported before - * exposing them in the DBus property */ - - if (band_configuration[i].bands_2g[0]) { - g_array_append_val (bands, band_configuration[i].bands_2g[0]); - if (band_configuration[i].bands_2g[1]) - g_array_append_val (bands, band_configuration[i].bands_2g[1]); + if (mode & MM_MODEM_MODE_2G) { + band = num_to_band_2g (ubandsel_value); + if (band != MM_MODEM_BAND_UNKNOWN) + g_array_append_val(bands, band); } - - if (band_configuration[i].bands_3g[0]) { - g_array_append_val (bands, band_configuration[i].bands_3g[0]); - if (band_configuration[i].bands_3g[1]) - g_array_append_val (bands, band_configuration[i].bands_3g[1]); + + if (mode & MM_MODEM_MODE_3G) { + band = num_to_band_3g (ubandsel_value); + if (band != MM_MODEM_BAND_UNKNOWN) + g_array_append_val(bands, band); } - if (band_configuration[i].bands_4g[0]) { - g_array_append_val (bands, band_configuration[i].bands_4g[0]); - if (band_configuration[i].bands_4g[1]) - g_array_append_val (bands, band_configuration[i].bands_4g[1]); +/* Note: The wierd code segment below is to seperate out specific LTE bands since + * since UBANDSEL? reports back the frequency of the band and not the band itself + */ + + band = MM_MODEM_BAND_UNKNOWN; + if ( mode & MM_MODEM_MODE_4G) { + for (j = 0; ubandsel_value == num_bands_4g[j].num && j < G_N_ELEMENTS (num_bands_4g); j++) { + for (k = 0; k < 5; k++) { + band = num_bands_4g[j].band[k]; + for (x = 0; band_configuration[i].bands_4g[x] == band && + x < G_N_ELEMENTS (band_configuration[i].bands_4g); x++) { + g_array_append_val(bands, band); + break; + } + } + } } } GArray * mm_ublox_parse_ubandsel_response (const gchar *response, + const gchar *model, GError **error) { GArray *array_values = NULL; @@ -692,6 +1231,8 @@ mm_ublox_parse_ubandsel_response (const gchar *response, GError *inner_error = NULL; guint i; + MMModemMode mode = supported_modes_per_model(model); + if (!g_str_has_prefix (response, "+UBANDSEL")) { inner_error = g_error_new (MM_CORE_ERROR, MM_CORE_ERROR_FAILED, "Couldn't parse +UBANDSEL response: '%s'", response); @@ -710,7 +1251,7 @@ mm_ublox_parse_ubandsel_response (const gchar *response, /* Convert list of ubandsel numbers to MMModemBand values */ array = g_array_new (FALSE, FALSE, sizeof (MMModemBand)); for (i = 0; i < array_values->len; i++) - append_bands (array, g_array_index (array_values, guint, i)); + append_bands (array, g_array_index (array_values, guint, i), mode, model); if (!array->len) { inner_error = g_error_new (MM_CORE_ERROR, MM_CORE_ERROR_FAILED, @@ -738,31 +1279,60 @@ ubandsel_num_cmp (const guint *a, const guint *b) } gchar * -mm_ublox_build_ubandsel_set_command (GArray *bands, - GError **error) +mm_ublox_build_ubandsel_set_command (GArray *bands, + const gchar *model, + GError **error) { GString *command = NULL; GArray *ubandsel_nums; - guint i; + guint num; + gboolean found; if (bands->len == 1 && g_array_index (bands, MMModemBand, 0) == MM_MODEM_BAND_ANY) return g_strdup ("+UBANDSEL=0"); ubandsel_nums = g_array_sized_new (FALSE, FALSE, sizeof (guint), G_N_ELEMENTS (band_configuration)); + + guint i, j, k; + for (i = 0; i < G_N_ELEMENTS (band_configuration); i++) { - guint j; + if (g_str_has_prefix (model, band_configuration[i].model)) + break; + } - for (j = 0; j < bands->len; j++) { - MMModemBand band; + if (i == G_N_ELEMENTS (band_configuration)) { + g_set_error (error, MM_CORE_ERROR, MM_CORE_ERROR_FAILED, + "Unknown modem model %s", model); + g_array_unref (ubandsel_nums); + return NULL; + } - band = g_array_index (bands, MMModemBand, j); + for (j = 0; j < bands->len; j++) { + MMModemBand band; + gboolean found = FALSE; + + band = g_array_index (bands, MMModemBand, j); + + /* Check to see if band is supported by the model */ + for (k = 0; band_configuration[i].bands_2g[k] && !found && k < G_N_ELEMENTS (band_configuration[i].bands_2g); k++) { + if (band == band_configuration[i].bands_2g[k]) + found = TRUE; + } - if (band == band_configuration[i].bands_2g[0] || band == band_configuration[i].bands_2g[1] || - band == band_configuration[i].bands_3g[0] || band == band_configuration[i].bands_3g[1] || - band == band_configuration[i].bands_4g[0] || band == band_configuration[i].bands_4g[1]) { - g_array_append_val (ubandsel_nums, band_configuration[i].ubandsel_value); - break; - } + for (k = 0; band_configuration[i].bands_3g[k] && !found && k < G_N_ELEMENTS (band_configuration[i].bands_3g); k++) { + if (band == band_configuration[i].bands_3g[k]) + found = TRUE; + } + + for (k = 0; band_configuration[i].bands_4g[k] && !found && k < G_N_ELEMENTS (band_configuration[i].bands_4g); k++) { + if (band == band_configuration[i].bands_4g[k]) + found = TRUE; + } + + if (found) { + num = band_to_num (band); + if (num) + g_array_append_val (ubandsel_nums, num); } } @@ -780,6 +1350,7 @@ mm_ublox_build_ubandsel_set_command (GArray *bands, command = g_string_new ("+UBANDSEL="); for (i = 0; i < ubandsel_nums->len; i++) g_string_append_printf (command, "%s%u", i == 0 ? "" : ",", g_array_index (ubandsel_nums, guint, i)); + return g_string_free (command, FALSE); } diff --git a/plugins/ublox/mm-modem-helpers-ublox.h b/plugins/ublox/mm-modem-helpers-ublox.h index 1a51df38..d47fd41e 100644 --- a/plugins/ublox/mm-modem-helpers-ublox.h +++ b/plugins/ublox/mm-modem-helpers-ublox.h @@ -20,6 +20,27 @@ #include <ModemManager.h> /*****************************************************************************/ +/* AT Commands Support */ + +typedef enum { + FEATURE_SUPPORT_UNKNOWN, + FEATURE_SUPPORTED, + FEATURE_UNSUPPORTED, +} FeatureSupport; + +typedef enum { + BAND_UPDATE_NEEDS_UNKNOWN, + BAND_UPDATE_NEEDS_CFUN, + BAND_UPDATE_NEEDS_COPS, +} UpdateMethod; + +typedef struct UbloxSupportConfig { + UpdateMethod method; + FeatureSupport uact; + FeatureSupport ubandsel; +} UbloxSupportConfig; + +/*****************************************************************************/ /* +UPINCNT response parser */ gboolean mm_ublox_parse_upincnt_response (const gchar *response, @@ -82,6 +103,12 @@ GArray *mm_ublox_parse_urat_test_response (const gchar *response, GError **error); /*****************************************************************************/ +/* Model-based config support loading */ +gboolean mm_ublox_get_support_config (const gchar *model, + UbloxSupportConfig *config, + GError **error); + +/*****************************************************************************/ /* Model-based supported modes filtering */ GArray *mm_ublox_filter_supported_modes (const gchar *model, @@ -91,20 +118,22 @@ GArray *mm_ublox_filter_supported_modes (const gchar *model, /*****************************************************************************/ /* Model-based supported bands loading */ -GArray *mm_ublox_get_supported_bands (const gchar *model, - GError **error); +GArray *mm_ublox_get_supported_bands (const gchar *model, + GError **error); /*****************************************************************************/ /* UBANDSEL? response parser */ GArray *mm_ublox_parse_ubandsel_response (const gchar *response, + const gchar *model, GError **error); /*****************************************************************************/ /* UBANDSEL=X command builder */ -gchar *mm_ublox_build_ubandsel_set_command (GArray *bands, - GError **error); +gchar *mm_ublox_build_ubandsel_set_command (GArray *bands, + const gchar *model, + GError **error); /*****************************************************************************/ /* UACT? response parser */ diff --git a/plugins/ublox/tests/test-modem-helpers-ublox.c b/plugins/ublox/tests/test-modem-helpers-ublox.c index e8b19220..4ba61c22 100644 --- a/plugins/ublox/tests/test-modem-helpers-ublox.c +++ b/plugins/ublox/tests/test-modem-helpers-ublox.c @@ -616,12 +616,13 @@ test_supported_bands_sara_u280 (void) static void common_validate_ubandsel_response (const gchar *str, const MMModemBand *expected_bands, + const gchar *model, guint n_expected_bands) { GError *error = NULL; GArray *bands; - bands = mm_ublox_parse_ubandsel_response (str, &error); + bands = mm_ublox_parse_ubandsel_response (str, model, &error); g_assert_no_error (error); g_assert (bands); @@ -632,36 +633,38 @@ static void test_ubandsel_response_four (void) { const MMModemBand expected_bands[] = { - /* 850 */ MM_MODEM_BAND_G850, MM_MODEM_BAND_UTRAN_5, MM_MODEM_BAND_EUTRAN_5, - /* 900 */ MM_MODEM_BAND_EGSM, MM_MODEM_BAND_UTRAN_8, MM_MODEM_BAND_EUTRAN_8, - /* 1800 */ MM_MODEM_BAND_DCS, MM_MODEM_BAND_UTRAN_3, MM_MODEM_BAND_EUTRAN_3, - /* 1900 */ MM_MODEM_BAND_PCS, MM_MODEM_BAND_UTRAN_2, MM_MODEM_BAND_EUTRAN_2, + /* 700 */ MM_MODEM_BAND_EUTRAN_4, + /* 1700 */ MM_MODEM_BAND_EUTRAN_13 }; - common_validate_ubandsel_response ("+UBANDSEL: 850,900,1800,1900\r\n", expected_bands, G_N_ELEMENTS (expected_bands)); + common_validate_ubandsel_response ("+UBANDSEL: 700,1700\r\n", expected_bands, "LARA-R204", G_N_ELEMENTS (expected_bands)); } static void test_ubandsel_response_three (void) { const MMModemBand expected_bands[] = { - /* 850 */ MM_MODEM_BAND_G850, MM_MODEM_BAND_UTRAN_5, MM_MODEM_BAND_EUTRAN_5, - /* 900 */ MM_MODEM_BAND_EGSM, MM_MODEM_BAND_UTRAN_8, MM_MODEM_BAND_EUTRAN_8, - /* 1800 */ MM_MODEM_BAND_DCS, MM_MODEM_BAND_UTRAN_3, MM_MODEM_BAND_EUTRAN_3, + /* 800 */ MM_MODEM_BAND_UTRAN_6, + /* 850 */ MM_MODEM_BAND_G850, MM_MODEM_BAND_UTRAN_5, + /* 900 */ MM_MODEM_BAND_EGSM, MM_MODEM_BAND_UTRAN_8, + /* 1900 */ MM_MODEM_BAND_PCS, MM_MODEM_BAND_UTRAN_2, + /* 2100 */ MM_MODEM_BAND_UTRAN_1 }; - common_validate_ubandsel_response ("+UBANDSEL: 850,900,1800\r\n", expected_bands, G_N_ELEMENTS (expected_bands)); + common_validate_ubandsel_response ("+UBANDSEL: 800,850,900,1900,2100\r\n", expected_bands, "SARA-U201", G_N_ELEMENTS (expected_bands)); } static void test_ubandsel_response_two (void) { const MMModemBand expected_bands[] = { - /* 850 */ MM_MODEM_BAND_G850, MM_MODEM_BAND_UTRAN_5, MM_MODEM_BAND_EUTRAN_5, - /* 900 */ MM_MODEM_BAND_EGSM, MM_MODEM_BAND_UTRAN_8, MM_MODEM_BAND_EUTRAN_8, + /* 850 */ MM_MODEM_BAND_G850, + /* 900 */ MM_MODEM_BAND_EGSM, + /* 1800 */ MM_MODEM_BAND_DCS, + /* 1900 */ MM_MODEM_BAND_PCS }; - common_validate_ubandsel_response ("+UBANDSEL: 850,900\r\n", expected_bands, G_N_ELEMENTS (expected_bands)); + common_validate_ubandsel_response ("+UBANDSEL: 850,900,1800,1900\r\n", expected_bands, "SARA-G310", G_N_ELEMENTS (expected_bands)); } static void @@ -669,9 +672,11 @@ test_ubandsel_response_one (void) { const MMModemBand expected_bands[] = { /* 850 */ MM_MODEM_BAND_G850, MM_MODEM_BAND_UTRAN_5, MM_MODEM_BAND_EUTRAN_5, + /* 1700 */ MM_MODEM_BAND_EUTRAN_4, + /* 1900 */ MM_MODEM_BAND_UTRAN_2, MM_MODEM_BAND_EUTRAN_2 }; - common_validate_ubandsel_response ("+UBANDSEL: 850\r\n", expected_bands, G_N_ELEMENTS (expected_bands)); + common_validate_ubandsel_response ("+UBANDSEL: 850,1700,1900\r\n", expected_bands, "TOBY-R200", G_N_ELEMENTS (expected_bands)); } /*****************************************************************************/ @@ -680,6 +685,7 @@ test_ubandsel_response_one (void) static void common_validate_ubandsel_request (const MMModemBand *bands, guint n_bands, + const gchar *model, const gchar *expected_request) { GError *error = NULL; @@ -689,7 +695,7 @@ common_validate_ubandsel_request (const MMModemBand *bands, bands_array = g_array_sized_new (FALSE, FALSE, sizeof (MMModemBand), n_bands); g_array_append_vals (bands_array, bands, n_bands); - request = mm_ublox_build_ubandsel_set_command (bands_array, &error); + request = mm_ublox_build_ubandsel_set_command (bands_array, model, &error); g_assert_no_error (error); g_assert (request); @@ -706,7 +712,7 @@ test_ubandsel_request_any (void) MM_MODEM_BAND_ANY }; - common_validate_ubandsel_request (bands, G_N_ELEMENTS (bands), "+UBANDSEL=0"); + common_validate_ubandsel_request (bands, G_N_ELEMENTS (bands), "TOBY-R200", "+UBANDSEL=0"); } static void @@ -716,7 +722,7 @@ test_ubandsel_request_2g (void) MM_MODEM_BAND_G850, MM_MODEM_BAND_EGSM, MM_MODEM_BAND_DCS, MM_MODEM_BAND_PCS }; - common_validate_ubandsel_request (bands, G_N_ELEMENTS (bands), "+UBANDSEL=850,900,1800,1900"); + common_validate_ubandsel_request (bands, G_N_ELEMENTS (bands), "SARA-G310", "+UBANDSEL=850,900,1800,1900"); } static void @@ -726,7 +732,7 @@ test_ubandsel_request_1800 (void) MM_MODEM_BAND_DCS, MM_MODEM_BAND_UTRAN_3, MM_MODEM_BAND_EUTRAN_3 }; - common_validate_ubandsel_request (bands, G_N_ELEMENTS (bands), "+UBANDSEL=1800"); + common_validate_ubandsel_request (bands, G_N_ELEMENTS (bands), "TOBY-R200", "+UBANDSEL=1800"); } /*****************************************************************************/ |