This patch add supported modes loading in Telit plugin. --- plugins/telit/mm-broadband-modem-telit.c | 173 +++++++++++++++++++++++++++++++ 1 file changed, 173 insertions(+)
diff --git a/plugins/telit/mm-broadband-modem-telit.c b/plugins/telit/mm-broadband-modem-telit.c index 77b1800..3866e54 100644 --- a/plugins/telit/mm-broadband-modem-telit.c +++ b/plugins/telit/mm-broadband-modem-telit.c @@ -536,6 +536,177 @@ setup_flow_control (MMIfaceModem *self, } /*****************************************************************************/ +/* Load supported modes (Modem interface) */ + +typedef struct { + GSimpleAsyncResult *result; + MMBroadbandModem *self; + MMModemMode mode; + gboolean run_ws46; +} LoadSupportedModesContext; + +static void +load_supported_modes_context_complete_and_free (LoadSupportedModesContext *ctx) +{ + g_simple_async_result_complete (ctx->result); + g_object_unref (ctx->result); + g_object_unref (ctx->self); + g_slice_free (LoadSupportedModesContext, ctx); +} + +static GArray * +modem_load_supported_modes_finish (MMIfaceModem *self, + GAsyncResult *res, + GError **error) +{ + GArray *modes; + MMModemModeCombination mode; + + if (g_simple_async_result_propagate_error (G_SIMPLE_ASYNC_RESULT (res), error)) + return NULL; + + /* Build a mask with all supported modes */ + modes = g_array_sized_new (FALSE, FALSE, sizeof (MMModemModeCombination), 1); + mode.allowed = (MMModemMode) GPOINTER_TO_UINT (g_simple_async_result_get_op_res_gpointer ( + G_SIMPLE_ASYNC_RESULT (res))); + mode.preferred = MM_MODEM_MODE_NONE; + g_array_append_val (modes, mode); + + return modes; +} + +static void load_supported_modes_step (LoadSupportedModesContext *ctx); + +static void +supported_modes_ws46_test_ready (MMBroadbandModem *self, + GAsyncResult *res, + LoadSupportedModesContext *ctx) +{ + const gchar *response; + GError *error = NULL; + + response = mm_base_modem_at_command_finish (MM_BASE_MODEM (self), res, &error); + if (!error) { + MMModemMode mode = MM_MODEM_MODE_NONE; + + /* + * More than one numeric ID may appear in the list, that's why + * they are checked separately. + * + * From 3GPP TS 27.007 v.11.2.0, section 5.9 + * 12 GSM Digital Cellular Systems (GERAN only) + * 22 UTRAN only + * 25 3GPP Systems (GERAN, UTRAN and E-UTRAN) + * 28 E-UTRAN only + * 29 GERAN and UTRAN + * 30 GERAN and E-UTRAN + * 31 UTRAN and E-UTRAN + */ + + if (strstr (response, "12") != NULL) { + mm_dbg ("Device allows (3GPP) 2G-only network mode"); + mode |= MM_MODEM_MODE_2G; + } + + if (strstr (response, "22") != NULL) { + mm_dbg ("Device allows (3GPP) 3G-only network mode"); + mode |= MM_MODEM_MODE_3G; + } + + if (strstr (response, "28") != NULL) { + mm_dbg ("Device allows (3GPP) 4G-only network mode"); + mode |= MM_MODEM_MODE_4G; + } + + if (strstr (response, "29") != NULL) { + mm_dbg ("Device allows (3GPP) 2G/3G network mode"); + mode |= (MM_MODEM_MODE_2G | MM_MODEM_MODE_3G); + } + + if (strstr (response, "30") != NULL) { + mm_dbg ("Device allows (3GPP) 2G/4G network mode"); + mode |= (MM_MODEM_MODE_2G | MM_MODEM_MODE_4G); + } + + if (strstr (response, "31") != NULL) { + mm_dbg ("Device allows (3GPP) 3G/4G network mode"); + mode |= (MM_MODEM_MODE_3G | MM_MODEM_MODE_4G); + } + + if (strstr (response, "25") != NULL) { + if (mm_iface_modem_is_3gpp_lte (MM_IFACE_MODEM (self))) { + mm_dbg ("Device allows every supported 3GPP network mode (2G/3G/4G)"); + mode |= (MM_MODEM_MODE_2G | MM_MODEM_MODE_3G | MM_MODEM_MODE_4G); + } else { + mm_dbg ("Device allows every supported 3GPP network mode (2G/3G)"); + mode |= (MM_MODEM_MODE_2G | MM_MODEM_MODE_3G); + } + } + + /* If no expected ID found, log error */ + if (mode == MM_MODEM_MODE_NONE) + mm_dbg ("Invalid list of supported networks reported by WS46=?: '%s'", response); + else + ctx->mode |= mode; + } else { + mm_dbg ("Generic query of supported 3GPP networks with WS46=? failed: '%s'", error->message); + g_error_free (error); + } + + /* Now finish the supported mode check */ + ctx->run_ws46 = FALSE; + load_supported_modes_step (ctx); +} + +static void +load_supported_modes_step (LoadSupportedModesContext *ctx) +{ + if (ctx->run_ws46) { + mm_base_modem_at_command ( + MM_BASE_MODEM (ctx->self), + "+WS46=?", + 3, + TRUE, /* allow caching, it's a test command */ + (GAsyncReadyCallback)supported_modes_ws46_test_ready, + ctx); + return; + } + + /* All done. + * If no mode found, error */ + if (ctx->mode == MM_MODEM_MODE_NONE) + g_simple_async_result_set_error (ctx->result, + MM_CORE_ERROR, + MM_CORE_ERROR_FAILED, + "Couldn't retrieve supported modes"); + else + g_simple_async_result_set_op_res_gpointer (ctx->result, + GUINT_TO_POINTER (ctx->mode), + NULL); + load_supported_modes_context_complete_and_free (ctx); +} + +static void +modem_load_supported_modes (MMIfaceModem *self, + GAsyncReadyCallback callback, + gpointer user_data) +{ + LoadSupportedModesContext *ctx; + + mm_dbg ("loading Telit supported modes..."); + ctx = g_slice_new0 (LoadSupportedModesContext); + ctx->self = g_object_ref (self); + ctx->result = g_simple_async_result_new (G_OBJECT (self), + callback, + user_data, + modem_load_supported_modes); + ctx->mode = MM_MODEM_MODE_NONE; + ctx->run_ws46 = TRUE; + + load_supported_modes_step (ctx); +} + +/*****************************************************************************/ /* Enabling unsolicited events (3GPP interface) */ static gboolean @@ -613,6 +784,8 @@ iface_modem_init (MMIfaceModem *iface) iface->load_access_technologies_finish = load_access_technologies_finish; iface->setup_flow_control = setup_flow_control; iface->setup_flow_control_finish = setup_flow_control_finish; + iface->load_supported_modes = modem_load_supported_modes; + iface->load_supported_modes_finish = modem_load_supported_modes_finish; } static void -- 2.4.5 _______________________________________________ ModemManager-devel mailing list ModemManager-devel@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/modemmanager-devel