[PATCH 2/2] Telit plugin: add support to SIM hot swap

Carlo Lobrano c.lobrano at gmail.com
Wed Jul 6 13:35:57 UTC 2016


MMBroadbandModemTelit:
 * added logic to set MMBroadbandModem's SIM_HOT_SWAP property to TRUE
 * added function to enable QSS unsolicited
 * added QSS unsolicited handler
---
 plugins/telit/mm-broadband-modem-telit.c | 136 +++++++++++++++++++++++++++++-
 1 files changed, 135 insertions(+), 1 deletions(-)

diff --git a/plugins/telit/mm-broadband-modem-telit.c b/plugins/telit/mm-broadband-modem-telit.c
index 8baf2cf..deb67b2 100644
--- a/plugins/telit/mm-broadband-modem-telit.c
+++ b/plugins/telit/mm-broadband-modem-telit.c
@@ -43,6 +43,137 @@ G_DEFINE_TYPE_EXTENDED (MMBroadbandModemTelit, mm_broadband_modem_telit, MM_TYPE
                         G_IMPLEMENT_INTERFACE (MM_TYPE_IFACE_MODEM_3GPP, iface_modem_3gpp_init));
 
 /*****************************************************************************/
+/* Setup SIM hot swap (Modem interface) */
+
+static void
+telit_qss_unsolicited_handler (MMPortSerialAt *port,
+                               GMatchInfo *match_info,
+                               MMBroadbandModemTelit *self)
+{
+    guint qss;
+    gboolean is_sim_missing;
+
+    if (!mm_get_uint_from_match_info (match_info, 1, &qss))
+        return;
+
+    switch (qss) {
+        case 0:
+            mm_info ("QSS: SIM removed");
+            break;
+        case 1:
+            mm_info ("QSS: SIM inserted");
+            break;
+        case 2:
+            mm_info ("QSS: SIM inserted and PIN unlocked");
+            break;
+        case 3:
+            mm_info ("QSS: SIM inserted and PIN locked");
+            break;
+        default:
+            mm_warn ("QSS: unknown QSS value %d", qss);
+            break;
+    }
+
+    is_sim_missing = (qss == 0) ? TRUE : FALSE;
+    mm_broadband_modem_update_sim_hot_swap_status (MM_BROADBAND_MODEM (self), is_sim_missing);
+}
+
+typedef struct {
+    MMBroadbandModemTelit *self;
+    GSimpleAsyncResult *result;
+} ToggleQssUnsolicitedContext;
+
+static void
+toggle_qss_unsolicited_context_complete_and_free (ToggleQssUnsolicitedContext *ctx)
+{
+    g_simple_async_result_complete (ctx->result);
+    g_object_unref (ctx->result);
+    g_object_unref (ctx->self);
+    g_slice_free (ToggleQssUnsolicitedContext, ctx);
+}
+
+static gboolean
+modem_setup_sim_hot_swap_finish (MMIfaceModem *self,
+                                 GAsyncResult *res,
+                                 GError **error)
+{
+    return !g_simple_async_result_propagate_error (G_SIMPLE_ASYNC_RESULT (res), error);
+}
+
+static void
+telit_qss_toggle_ready (MMBaseModem *self,
+                        GAsyncResult *res,
+                        ToggleQssUnsolicitedContext *ctx)
+{
+    GError *error = NULL;
+
+    mm_base_modem_at_command_finish (self, res, &error);
+    if (error) {
+        mm_warn ("Enable QSS failed: %s", error->message);
+        g_simple_async_result_set_error (ctx->result,
+                                         MM_CORE_ERROR,
+                                         MM_CORE_ERROR_FAILED,
+                                         "Could not enable QSS");
+    } else {
+        MMPortSerialAt *primary;
+        MMPortSerialAt *secondary;
+
+        primary = mm_base_modem_peek_port_secondary (MM_BASE_MODEM (ctx->self));
+        mm_port_serial_at_add_unsolicited_msg_handler (
+            primary,
+            g_regex_new ("#QSS:\\s*([0-3])\\r\\n", G_REGEX_RAW, 0, NULL),
+            (MMPortSerialAtUnsolicitedMsgFn)telit_qss_unsolicited_handler,
+            ctx->self,
+            NULL);
+
+        secondary = mm_base_modem_peek_port_secondary (MM_BASE_MODEM (ctx->self));
+        if (secondary)
+            mm_port_serial_at_add_unsolicited_msg_handler (
+                secondary,
+                g_regex_new ("#QSS:\\s*([0-3])\\r\\n", G_REGEX_RAW, 0, NULL),
+                (MMPortSerialAtUnsolicitedMsgFn)telit_qss_unsolicited_handler,
+                ctx->self,
+                NULL);
+        g_simple_async_result_set_op_res_gboolean (ctx->result, TRUE);
+    }
+
+    toggle_qss_unsolicited_context_complete_and_free (ctx);
+}
+
+
+static void
+modem_setup_sim_hot_swap (MMIfaceModem *self,
+                          GAsyncReadyCallback callback,
+                          gpointer user_data)
+{
+    ToggleQssUnsolicitedContext *ctx;
+    MMPortSerialAt *port;
+
+    mm_dbg ("Telit SIM hot swap: Enable QSS");
+
+    ctx = g_slice_new0 (ToggleQssUnsolicitedContext);
+    ctx->self = g_object_ref (MM_BROADBAND_MODEM_TELIT (self));
+    ctx->result = g_simple_async_result_new (G_OBJECT (self),
+                                             callback,
+                                             user_data,
+                                             modem_setup_sim_hot_swap);
+
+    port = mm_base_modem_peek_port_secondary (MM_BASE_MODEM (self));
+    if (!port)
+        port = mm_base_modem_peek_port_primary (MM_BASE_MODEM (self));
+
+    mm_base_modem_at_command_full (MM_BASE_MODEM (self),
+                                   port,
+                                   "#QSS=1",
+                                   3,
+                                   FALSE,
+                                   FALSE, /* raw */
+                                   NULL, /* cancellable */
+                                   (GAsyncReadyCallback) telit_qss_toggle_ready,
+                                   ctx);
+}
+
+/*****************************************************************************/
 /* Set current bands (Modem interface) */
 
 static gboolean
@@ -214,7 +345,7 @@ load_bands_ready (MMBaseModem *self,
     else
         g_simple_async_result_set_op_res_gpointer (ctx->result, bands, (GDestroyNotify)g_array_unref);
 
-    load_bands_context_complete_and_free(ctx);
+    load_bands_context_complete_and_free (ctx);
 }
 
 static void
@@ -1017,6 +1148,7 @@ mm_broadband_modem_telit_new (const gchar *device,
                          MM_BASE_MODEM_PLUGIN, plugin,
                          MM_BASE_MODEM_VENDOR_ID, vendor_id,
                          MM_BASE_MODEM_PRODUCT_ID, product_id,
+                         MM_IFACE_MODEM_SIM_HOT_SWAP_SUPPORTED, TRUE,
                          NULL);
 }
 
@@ -1052,6 +1184,8 @@ iface_modem_init (MMIfaceModem *iface)
     iface->load_current_modes_finish = load_current_modes_finish;
     iface->set_current_modes = set_current_modes;
     iface->set_current_modes_finish = set_current_modes_finish;
+    iface->setup_sim_hot_swap = modem_setup_sim_hot_swap;
+    iface->setup_sim_hot_swap_finish = modem_setup_sim_hot_swap_finish;
 }
 
 static void
-- 
2.7.4



More information about the ModemManager-devel mailing list