[PATCH v3] telit: unsupported CSIM lock should not skip loading unlock retries

Carlo Lobrano c.lobrano at gmail.com
Thu Apr 13 09:53:53 UTC 2017


Some modems do not support CSIM lock/unlock, but they do support
querying SIM unlock retries through +CSIM command.

If CSIM lock returns with "unsupported command" do not propagate
the error and continue with the other CSIM queries instead, moreover the
CSIM lock feature is signed as FEATURE_UNSUPPORTED in Telit modem
private structure to prevent being sent again (e.g. calling CSIM
unlock AT command).
---

Fixed csim_lock_support never set to FEATURE_SUPPORTED

---
 plugins/telit/mm-broadband-modem-telit.c | 94 ++++++++++++++++++++++++++------
 plugins/telit/mm-broadband-modem-telit.h |  2 +
 2 files changed, 80 insertions(+), 16 deletions(-)

diff --git a/plugins/telit/mm-broadband-modem-telit.c b/plugins/telit/mm-broadband-modem-telit.c
index cce0229..0d8a34b 100644
--- a/plugins/telit/mm-broadband-modem-telit.c
+++ b/plugins/telit/mm-broadband-modem-telit.c
@@ -42,6 +42,15 @@ G_DEFINE_TYPE_EXTENDED (MMBroadbandModemTelit, mm_broadband_modem_telit, MM_TYPE
                         G_IMPLEMENT_INTERFACE (MM_TYPE_IFACE_MODEM, iface_modem_init)
                         G_IMPLEMENT_INTERFACE (MM_TYPE_IFACE_MODEM_3GPP, iface_modem_3gpp_init));
 
+typedef enum {
+    FEATURE_SUPPORT_UNKNOWN,
+    FEATURE_NOT_SUPPORTED,
+    FEATURE_SUPPORTED
+} FeatureSupport;
+
+struct _MMBroadbandModemTelitPrivate {
+    FeatureSupport csim_lock_support;
+};
 
 /*****************************************************************************/
 /* After Sim Unlock (Modem interface) */
@@ -521,10 +530,19 @@ csim_unlock_ready (MMBaseModem              *self,
     /* Ignore errors */
     response = mm_base_modem_at_command_finish (self, res, &error);
     if (!response) {
+        if (g_error_matches (error,
+                             MM_MOBILE_EQUIPMENT_ERROR,
+                             MM_MOBILE_EQUIPMENT_ERROR_NOT_SUPPORTED)) {
+            ctx->self->priv->csim_lock_support = FEATURE_NOT_SUPPORTED;
+        }
         mm_warn ("Couldn't unlock SIM card: %s", error->message);
         g_error_free (error);
     }
 
+    if (ctx->self->priv->csim_lock_support != FEATURE_NOT_SUPPORTED) {
+        ctx->self->priv->csim_lock_support = FEATURE_SUPPORTED;
+    }
+
     ctx->step++;
     load_unlock_retries_step (ctx);
 }
@@ -591,10 +609,22 @@ csim_lock_ready (MMBaseModem              *self,
 
     response = mm_base_modem_at_command_finish (self, res, &error);
     if (!response) {
-        g_prefix_error (&error, "Couldn't lock SIM card: ");
-        g_simple_async_result_take_error (ctx->result, error);
-        load_unlock_retries_context_complete_and_free (ctx);
-        return;
+        if (g_error_matches (error,
+                             MM_MOBILE_EQUIPMENT_ERROR,
+                             MM_MOBILE_EQUIPMENT_ERROR_NOT_SUPPORTED)) {
+            ctx->self->priv->csim_lock_support = FEATURE_NOT_SUPPORTED;
+            mm_warn ("Couldn't lock SIM card: %s. Continuing without CSIM lock.", error->message);
+            g_error_free (error);
+        } else {
+            g_prefix_error (&error, "Couldn't lock SIM card: ");
+            g_simple_async_result_take_error (ctx->result, error);
+            load_unlock_retries_context_complete_and_free (ctx);
+            return;
+        }
+    }
+
+    if (ctx->self->priv->csim_lock_support != FEATURE_NOT_SUPPORTED) {
+        ctx->self->priv->csim_lock_support = FEATURE_SUPPORTED;
     }
 
     ctx->step++;
@@ -602,6 +632,40 @@ csim_lock_ready (MMBaseModem              *self,
 }
 
 static void
+handle_csim_locking (LoadUnlockRetriesContext *ctx, gboolean is_lock)
+{
+    switch (ctx->self->priv->csim_lock_support) {
+        case FEATURE_SUPPORT_UNKNOWN:
+        case FEATURE_SUPPORTED:
+            if (is_lock) {
+                mm_base_modem_at_command (MM_BASE_MODEM (ctx->self),
+                                          CSIM_LOCK_STR,
+                                          CSIM_QUERY_TIMEOUT,
+                                          FALSE,
+                                          (GAsyncReadyCallback) csim_lock_ready,
+                                          ctx);
+            } else {
+                mm_base_modem_at_command (MM_BASE_MODEM (ctx->self),
+                                          CSIM_UNLOCK_STR,
+                                          CSIM_QUERY_TIMEOUT,
+                                          FALSE,
+                                          (GAsyncReadyCallback) csim_unlock_ready,
+                                          ctx);
+            }
+            break;
+        case FEATURE_NOT_SUPPORTED:
+            mm_dbg ("CSIM lock not supported by this modem. Skipping %s command",
+                    is_lock ? "lock" : "unlock");
+            ctx->step++;
+            load_unlock_retries_step (ctx);
+            break;
+        default:
+            g_assert_not_reached ();
+            break;
+    }
+}
+
+static void
 load_unlock_retries_step (LoadUnlockRetriesContext *ctx)
 {
     switch (ctx->step) {
@@ -609,12 +673,7 @@ load_unlock_retries_step (LoadUnlockRetriesContext *ctx)
             /* Fall back on next step */
             ctx->step++;
         case LOAD_UNLOCK_RETRIES_STEP_LOCK:
-            mm_base_modem_at_command (MM_BASE_MODEM (ctx->self),
-                                      CSIM_LOCK_STR,
-                                      CSIM_QUERY_TIMEOUT,
-                                      FALSE,
-                                      (GAsyncReadyCallback) csim_lock_ready,
-                                      ctx);
+            handle_csim_locking (ctx, TRUE);
             break;
         case LOAD_UNLOCK_RETRIES_STEP_PIN:
             mm_base_modem_at_command (MM_BASE_MODEM (ctx->self),
@@ -649,12 +708,7 @@ load_unlock_retries_step (LoadUnlockRetriesContext *ctx)
                                       ctx);
             break;
         case LOAD_UNLOCK_RETRIES_STEP_UNLOCK:
-            mm_base_modem_at_command (MM_BASE_MODEM (ctx->self),
-                                      CSIM_UNLOCK_STR,
-                                      CSIM_QUERY_TIMEOUT,
-                                      FALSE,
-                                      (GAsyncReadyCallback) csim_unlock_ready,
-                                      ctx);
+            handle_csim_locking (ctx, FALSE);
             break;
         case LOAD_UNLOCK_RETRIES_STEP_LAST:
             if (ctx->succeded_requests == 0) {
@@ -1220,6 +1274,11 @@ mm_broadband_modem_telit_new (const gchar *device,
 static void
 mm_broadband_modem_telit_init (MMBroadbandModemTelit *self)
 {
+    self->priv = G_TYPE_INSTANCE_GET_PRIVATE (self,
+                                              MM_TYPE_BROADBAND_MODEM_TELIT,
+                                              MMBroadbandModemTelitPrivate);
+
+    self->priv->csim_lock_support = FEATURE_SUPPORT_UNKNOWN;
 }
 
 static void
@@ -1263,4 +1322,7 @@ iface_modem_3gpp_init (MMIfaceModem3gpp *iface)
 static void
 mm_broadband_modem_telit_class_init (MMBroadbandModemTelitClass *klass)
 {
+    GObjectClass *object_class = G_OBJECT_CLASS (klass);
+
+    g_type_class_add_private (object_class, sizeof (MMBroadbandModemTelitPrivate));
 }
diff --git a/plugins/telit/mm-broadband-modem-telit.h b/plugins/telit/mm-broadband-modem-telit.h
index 50e6365..f68465e 100644
--- a/plugins/telit/mm-broadband-modem-telit.h
+++ b/plugins/telit/mm-broadband-modem-telit.h
@@ -29,9 +29,11 @@
 
 typedef struct _MMBroadbandModemTelit MMBroadbandModemTelit;
 typedef struct _MMBroadbandModemTelitClass MMBroadbandModemTelitClass;
+typedef struct _MMBroadbandModemTelitPrivate MMBroadbandModemTelitPrivate;
 
 struct _MMBroadbandModemTelit {
     MMBroadbandModem parent;
+    MMBroadbandModemTelitPrivate *priv;
 };
 
 struct _MMBroadbandModemTelitClass{
-- 
2.7.4



More information about the ModemManager-devel mailing list