<div dir="ltr"><div><div><div><div>Hi Aleksander,<br><br></div>that's weird. By the way I should be able to test it this afternoon with a LE910 or HE910 and let you know.<br></div><br></div>BR,<br></div>Carlo<br></div><br><div class="gmail_quote"><div dir="ltr">On Wed, 15 Mar 2017 at 00:38 Aleksander Morgado <<a href="mailto:aleksander@aleksander.es">aleksander@aleksander.es</a>> wrote:<br></div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">It will allow us to avoid totally or partially the after-sim-unlock<br class="gmail_msg">
explicit wait time that we're forcing.<br class="gmail_msg">
<br class="gmail_msg">
<a href="https://bugs.freedesktop.org/show_bug.cgi?id=100206" rel="noreferrer" class="gmail_msg" target="_blank">https://bugs.freedesktop.org/show_bug.cgi?id=100206</a><br class="gmail_msg">
---<br class="gmail_msg">
<br class="gmail_msg">
Hey Carlo & Daniele,<br class="gmail_msg">
<br class="gmail_msg">
I tried to enable #QSS=2 to see if I could get "#QSS: 3" indications:<br class="gmail_msg">
   3 - SIM INSERTED and READY (SMS and Phonebook access are possible).<br class="gmail_msg">
<br class="gmail_msg">
But looks like the HW I have doesn't emit any #QSS indication for some reason, any idea why? E.g. even if I remove the SIM and insert it again I get no "#QSS: 0" or "#QSS: 1" indication. Any idea why?<br class="gmail_msg">
<br class="gmail_msg">
Could you also review and test the patch with a device that supports "#QSS: 3" indications? I'm still not very convinced whether this is worth it to avoid the 1s timeout in the after-sim-unlock step, truth be told, but maybe if this setup works (i.e. we get a #QSS notification as soon as the SIM is completely ready) we could extend the timeout to a value a bit bigger just in case, like 5s?<br class="gmail_msg">
<br class="gmail_msg">
What do you think?<br class="gmail_msg">
<br class="gmail_msg">
---<br class="gmail_msg">
 plugins/telit/mm-broadband-modem-telit.c | 106 ++++++++++++++++++++++++++-----<br class="gmail_msg">
 plugins/telit/mm-broadband-modem-telit.h |   2 +<br class="gmail_msg">
 2 files changed, 91 insertions(+), 17 deletions(-)<br class="gmail_msg">
<br class="gmail_msg">
diff --git a/plugins/telit/mm-broadband-modem-telit.c b/plugins/telit/mm-broadband-modem-telit.c<br class="gmail_msg">
index 8bc9d1e5..76bcb1d4 100644<br class="gmail_msg">
--- a/plugins/telit/mm-broadband-modem-telit.c<br class="gmail_msg">
+++ b/plugins/telit/mm-broadband-modem-telit.c<br class="gmail_msg">
@@ -42,40 +42,83 @@ G_DEFINE_TYPE_EXTENDED (MMBroadbandModemTelit, mm_broadband_modem_telit, MM_TYPE<br class="gmail_msg">
                         G_IMPLEMENT_INTERFACE (MM_TYPE_IFACE_MODEM, iface_modem_init)<br class="gmail_msg">
                         G_IMPLEMENT_INTERFACE (MM_TYPE_IFACE_MODEM_3GPP, iface_modem_3gpp_init));<br class="gmail_msg">
<br class="gmail_msg">
+struct _MMBroadbandModemTelitPrivate {<br class="gmail_msg">
+    /* Whether the SIM ready notification has been received */<br class="gmail_msg">
+    gboolean  sim_ready;<br class="gmail_msg">
+    GTask    *sim_ready_task;<br class="gmail_msg">
+    guint     sim_ready_timeout_id;<br class="gmail_msg">
+};<br class="gmail_msg">
<br class="gmail_msg">
 /*****************************************************************************/<br class="gmail_msg">
 /* After Sim Unlock (Modem interface) */<br class="gmail_msg">
+<br class="gmail_msg">
+/* A short delay is necessary with some SIMs when they have just been<br class="gmail_msg">
+ * unlocked. Using up to 1 second as secure margin. */<br class="gmail_msg">
+#define SIM_READY_TIMEOUT_SECS 1<br class="gmail_msg">
+<br class="gmail_msg">
 static gboolean<br class="gmail_msg">
 modem_after_sim_unlock_finish (MMIfaceModem *self,<br class="gmail_msg">
                                GAsyncResult *res,<br class="gmail_msg">
                                GError **error)<br class="gmail_msg">
 {<br class="gmail_msg">
-    return TRUE;<br class="gmail_msg">
+    return g_task_propagate_boolean (G_TASK (res), error);<br class="gmail_msg">
 }<br class="gmail_msg">
<br class="gmail_msg">
 static gboolean<br class="gmail_msg">
-after_sim_unlock_ready (GSimpleAsyncResult *result)<br class="gmail_msg">
+after_sim_unlock_ready (MMBroadbandModemTelit *self)<br class="gmail_msg">
 {<br class="gmail_msg">
-    g_simple_async_result_complete (result);<br class="gmail_msg">
-    g_object_unref (result);<br class="gmail_msg">
+    g_assert (self->priv->sim_ready_timeout_id);<br class="gmail_msg">
+    g_assert (self->priv->sim_ready_task);<br class="gmail_msg">
+<br class="gmail_msg">
+    self->priv->sim_ready_timeout_id = 0;<br class="gmail_msg">
+<br class="gmail_msg">
+    g_task_return_boolean (self->priv->sim_ready_task, TRUE);<br class="gmail_msg">
+    g_clear_object (&self->priv->sim_ready_task);<br class="gmail_msg">
+<br class="gmail_msg">
     return G_SOURCE_REMOVE;<br class="gmail_msg">
 }<br class="gmail_msg">
<br class="gmail_msg">
 static void<br class="gmail_msg">
-modem_after_sim_unlock (MMIfaceModem *self,<br class="gmail_msg">
-                        GAsyncReadyCallback callback,<br class="gmail_msg">
-                        gpointer user_data)<br class="gmail_msg">
+modem_after_sim_unlock_cancel (MMBroadbandModemTelit *self)<br class="gmail_msg">
 {<br class="gmail_msg">
-    GSimpleAsyncResult *result;<br class="gmail_msg">
+    /* Cancel the after-sim-unlock wait timeout */<br class="gmail_msg">
+    if (self->priv->sim_ready_timeout_id) {<br class="gmail_msg">
+        g_source_remove (self->priv->sim_ready_timeout_id);<br class="gmail_msg">
+        self->priv->sim_ready_timeout_id = 0;<br class="gmail_msg">
+    }<br class="gmail_msg">
<br class="gmail_msg">
-    result = g_simple_async_result_new (G_OBJECT (self),<br class="gmail_msg">
-                                        callback,<br class="gmail_msg">
-                                        user_data,<br class="gmail_msg">
-                                        modem_after_sim_unlock);<br class="gmail_msg">
+    /* Complete after-sim-unlock wait task with error */<br class="gmail_msg">
+    if (self->priv->sim_ready_task) {<br class="gmail_msg">
+        g_task_return_new_error (self->priv->sim_ready_task, MM_CORE_ERROR, MM_CORE_ERROR_FAILED, "SIM removed");<br class="gmail_msg">
+        g_clear_object (&self->priv->sim_ready_task);<br class="gmail_msg">
+    }<br class="gmail_msg">
+}<br class="gmail_msg">
+<br class="gmail_msg">
+static void<br class="gmail_msg">
+modem_after_sim_unlock (MMIfaceModem        *_self,<br class="gmail_msg">
+                        GAsyncReadyCallback  callback,<br class="gmail_msg">
+                        gpointer             user_data)<br class="gmail_msg">
+{<br class="gmail_msg">
+    MMBroadbandModemTelit *self;<br class="gmail_msg">
+<br class="gmail_msg">
+    self = MM_BROADBAND_MODEM_TELIT (_self);<br class="gmail_msg">
+<br class="gmail_msg">
+    g_assert (!self->priv->sim_ready_task);<br class="gmail_msg">
+    g_assert (!self->priv->sim_ready_timeout_id);<br class="gmail_msg">
+<br class="gmail_msg">
+    /* Create new task that we store in the private info, so that it can be<br class="gmail_msg">
+     * completed early when unsolicited messages arrive. */<br class="gmail_msg">
+    self->priv->sim_ready_task = g_task_new (self, NULL, callback, user_data);<br class="gmail_msg">
<br class="gmail_msg">
-    /* A short delay is necessary with some SIMs when<br class="gmail_msg">
-    they have just been unlocked. Using 1 second as secure margin. */<br class="gmail_msg">
-    g_timeout_add_seconds (1, (GSourceFunc) after_sim_unlock_ready, result);<br class="gmail_msg">
+    /* If SIM ready already reported, we're done */<br class="gmail_msg">
+    if (self->priv->sim_ready) {<br class="gmail_msg">
+        g_task_return_boolean (self->priv->sim_ready_task, TRUE);<br class="gmail_msg">
+        g_clear_object (&self->priv->sim_ready_task);<br class="gmail_msg">
+        return;<br class="gmail_msg">
+    }<br class="gmail_msg">
+<br class="gmail_msg">
+    /* Wait for SIM readiness */<br class="gmail_msg">
+    self->priv->sim_ready_timeout_id = g_timeout_add_seconds (SIM_READY_TIMEOUT_SECS, (GSourceFunc) after_sim_unlock_ready, self);<br class="gmail_msg">
 }<br class="gmail_msg">
<br class="gmail_msg">
 /*****************************************************************************/<br class="gmail_msg">
@@ -94,6 +137,10 @@ telit_qss_unsolicited_handler (MMPortSerialAt *port,<br class="gmail_msg">
     switch (qss) {<br class="gmail_msg">
         case 0:<br class="gmail_msg">
             mm_info ("QSS: SIM removed");<br class="gmail_msg">
+<br class="gmail_msg">
+            /* Flag as not ready */<br class="gmail_msg">
+            self->priv->sim_ready = FALSE;<br class="gmail_msg">
+            modem_after_sim_unlock_cancel (self);<br class="gmail_msg">
             break;<br class="gmail_msg">
         case 1:<br class="gmail_msg">
             mm_info ("QSS: SIM inserted");<br class="gmail_msg">
@@ -102,7 +149,8 @@ telit_qss_unsolicited_handler (MMPortSerialAt *port,<br class="gmail_msg">
             mm_info ("QSS: SIM inserted and PIN unlocked");<br class="gmail_msg">
             break;<br class="gmail_msg">
         case 3:<br class="gmail_msg">
-            mm_info ("QSS: SIM inserted and PIN locked");<br class="gmail_msg">
+            mm_info ("QSS: SIM inserted and Ready");<br class="gmail_msg">
+            self->priv->sim_ready = TRUE;<br class="gmail_msg">
             break;<br class="gmail_msg">
         default:<br class="gmail_msg">
             mm_warn ("QSS: unknown QSS value %d", qss);<br class="gmail_msg">
@@ -203,9 +251,12 @@ modem_setup_sim_hot_swap (MMIfaceModem *self,<br class="gmail_msg">
     if (!port)<br class="gmail_msg">
         port = mm_base_modem_peek_port_primary (MM_BASE_MODEM (self));<br class="gmail_msg">
<br class="gmail_msg">
+    /* We enable QSS=2 so that we get notifications not only of SIM inserted or<br class="gmail_msg">
+     * not inserted, but also when the SIM is unlocked and ready for SMS and<br class="gmail_msg">
+     * phonebook access */<br class="gmail_msg">
     mm_base_modem_at_command_full (MM_BASE_MODEM (self),<br class="gmail_msg">
                                    port,<br class="gmail_msg">
-                                   "#QSS=1",<br class="gmail_msg">
+                                   "#QSS=2",<br class="gmail_msg">
                                    3,<br class="gmail_msg">
                                    FALSE,<br class="gmail_msg">
                                    FALSE, /* raw */<br class="gmail_msg">
@@ -1259,6 +1310,22 @@ mm_broadband_modem_telit_new (const gchar *device,<br class="gmail_msg">
 static void<br class="gmail_msg">
 mm_broadband_modem_telit_init (MMBroadbandModemTelit *self)<br class="gmail_msg">
 {<br class="gmail_msg">
+    /* Initialize private data */<br class="gmail_msg">
+    self->priv = G_TYPE_INSTANCE_GET_PRIVATE (self, MM_TYPE_BROADBAND_MODEM_TELIT, MMBroadbandModemTelitPrivate);<br class="gmail_msg">
+}<br class="gmail_msg">
+<br class="gmail_msg">
+static void<br class="gmail_msg">
+finalize (GObject *object)<br class="gmail_msg">
+{<br class="gmail_msg">
+    MMBroadbandModemTelit *self = MM_BROADBAND_MODEM_TELIT (object);<br class="gmail_msg">
+<br class="gmail_msg">
+    /* The after sim unlock step takes a full reference of the modem object in<br class="gmail_msg">
+     * the GTask, and therefore, the object will never be unref-ed while this<br class="gmail_msg">
+     * operation is pending */<br class="gmail_msg">
+    g_assert (!self->priv->sim_ready_timeout_id);<br class="gmail_msg">
+    g_assert (!self->priv->sim_ready_task);<br class="gmail_msg">
+<br class="gmail_msg">
+    G_OBJECT_CLASS (mm_broadband_modem_telit_parent_class)->finalize (object);<br class="gmail_msg">
 }<br class="gmail_msg">
<br class="gmail_msg">
 static void<br class="gmail_msg">
@@ -1304,4 +1371,9 @@ iface_modem_3gpp_init (MMIfaceModem3gpp *iface)<br class="gmail_msg">
 static void<br class="gmail_msg">
 mm_broadband_modem_telit_class_init (MMBroadbandModemTelitClass *klass)<br class="gmail_msg">
 {<br class="gmail_msg">
+    GObjectClass *object_class = G_OBJECT_CLASS (klass);<br class="gmail_msg">
+<br class="gmail_msg">
+    g_type_class_add_private (object_class, sizeof (MMBroadbandModemTelitPrivate));<br class="gmail_msg">
+<br class="gmail_msg">
+    object_class->finalize = finalize;<br class="gmail_msg">
 }<br class="gmail_msg">
diff --git a/plugins/telit/mm-broadband-modem-telit.h b/plugins/telit/mm-broadband-modem-telit.h<br class="gmail_msg">
index 50e6365f..f68465e7 100644<br class="gmail_msg">
--- a/plugins/telit/mm-broadband-modem-telit.h<br class="gmail_msg">
+++ b/plugins/telit/mm-broadband-modem-telit.h<br class="gmail_msg">
@@ -29,9 +29,11 @@<br class="gmail_msg">
<br class="gmail_msg">
 typedef struct _MMBroadbandModemTelit MMBroadbandModemTelit;<br class="gmail_msg">
 typedef struct _MMBroadbandModemTelitClass MMBroadbandModemTelitClass;<br class="gmail_msg">
+typedef struct _MMBroadbandModemTelitPrivate MMBroadbandModemTelitPrivate;<br class="gmail_msg">
<br class="gmail_msg">
 struct _MMBroadbandModemTelit {<br class="gmail_msg">
     MMBroadbandModem parent;<br class="gmail_msg">
+    MMBroadbandModemTelitPrivate *priv;<br class="gmail_msg">
 };<br class="gmail_msg">
<br class="gmail_msg">
 struct _MMBroadbandModemTelitClass{<br class="gmail_msg">
--<br class="gmail_msg">
2.12.0<br class="gmail_msg">
</blockquote></div>