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

Reply via email to