[PATCH] telit: enable 'SIM ready' notifications with #QSS=2
Daniele Palmas
dnlplm at gmail.com
Wed Mar 15 08:34:35 UTC 2017
Hi Aleksander,
2017-03-15 0:37 GMT+01:00 Aleksander Morgado <aleksander at aleksander.es>:
> It will allow us to avoid totally or partially the after-sim-unlock
> explicit wait time that we're forcing.
>
> https://bugs.freedesktop.org/show_bug.cgi?id=100206
> ---
>
> Hey Carlo & Daniele,
>
> I tried to enable #QSS=2 to see if I could get "#QSS: 3" indications:
> 3 - SIM INSERTED and READY (SMS and Phonebook access are possible).
>
> But looks like the HW I have doesn't emit any #QSS indication for some reason, any idea why?
If I'm not wrong you are using a LE866: which firmware version do you
have? I do not have direct experience with that modem, but as far as I
know there were issues with #QSS in older versions.
> E.g. even if I remove the SIM and insert it again I get no "#QSS: 0" or "#QSS: 1" indication. Any idea why?
Are you using an EVK or a custom design? I'm taking a look at the user
guides and it seems to me that SIM detection needs a gpio pin and
AT#SIMINCFG to be sent since for LE866 the default value for the
first parameter is 0 (no gpio pin selected): please take a look at
http://www.telit.com/fileadmin/user_upload/media/products/cellular/4_G/LE866/1VV0301355_LE866_Hardware_Design_Guide_r0.pdf
page 53 and http://www.telit.com/fileadmin/user_upload/media/products/cellular/4_G/LE866/Telit_LE866_AT_Commands_Reference_Guide_r5.pdf
SIMIN pin configuration #SIMINCFG
Daniele
>
> 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?
>
> What do you think?
>
> ---
> plugins/telit/mm-broadband-modem-telit.c | 106 ++++++++++++++++++++++++++-----
> plugins/telit/mm-broadband-modem-telit.h | 2 +
> 2 files changed, 91 insertions(+), 17 deletions(-)
>
> diff --git a/plugins/telit/mm-broadband-modem-telit.c b/plugins/telit/mm-broadband-modem-telit.c
> index 8bc9d1e5..76bcb1d4 100644
> --- a/plugins/telit/mm-broadband-modem-telit.c
> +++ b/plugins/telit/mm-broadband-modem-telit.c
> @@ -42,40 +42,83 @@ 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));
>
> +struct _MMBroadbandModemTelitPrivate {
> + /* Whether the SIM ready notification has been received */
> + gboolean sim_ready;
> + GTask *sim_ready_task;
> + guint sim_ready_timeout_id;
> +};
>
> /*****************************************************************************/
> /* After Sim Unlock (Modem interface) */
> +
> +/* A short delay is necessary with some SIMs when they have just been
> + * unlocked. Using up to 1 second as secure margin. */
> +#define SIM_READY_TIMEOUT_SECS 1
> +
> static gboolean
> modem_after_sim_unlock_finish (MMIfaceModem *self,
> GAsyncResult *res,
> GError **error)
> {
> - return TRUE;
> + return g_task_propagate_boolean (G_TASK (res), error);
> }
>
> static gboolean
> -after_sim_unlock_ready (GSimpleAsyncResult *result)
> +after_sim_unlock_ready (MMBroadbandModemTelit *self)
> {
> - g_simple_async_result_complete (result);
> - g_object_unref (result);
> + g_assert (self->priv->sim_ready_timeout_id);
> + g_assert (self->priv->sim_ready_task);
> +
> + self->priv->sim_ready_timeout_id = 0;
> +
> + g_task_return_boolean (self->priv->sim_ready_task, TRUE);
> + g_clear_object (&self->priv->sim_ready_task);
> +
> return G_SOURCE_REMOVE;
> }
>
> static void
> -modem_after_sim_unlock (MMIfaceModem *self,
> - GAsyncReadyCallback callback,
> - gpointer user_data)
> +modem_after_sim_unlock_cancel (MMBroadbandModemTelit *self)
> {
> - GSimpleAsyncResult *result;
> + /* Cancel the after-sim-unlock wait timeout */
> + if (self->priv->sim_ready_timeout_id) {
> + g_source_remove (self->priv->sim_ready_timeout_id);
> + self->priv->sim_ready_timeout_id = 0;
> + }
>
> - result = g_simple_async_result_new (G_OBJECT (self),
> - callback,
> - user_data,
> - modem_after_sim_unlock);
> + /* Complete after-sim-unlock wait task with error */
> + if (self->priv->sim_ready_task) {
> + g_task_return_new_error (self->priv->sim_ready_task, MM_CORE_ERROR, MM_CORE_ERROR_FAILED, "SIM removed");
> + g_clear_object (&self->priv->sim_ready_task);
> + }
> +}
> +
> +static void
> +modem_after_sim_unlock (MMIfaceModem *_self,
> + GAsyncReadyCallback callback,
> + gpointer user_data)
> +{
> + MMBroadbandModemTelit *self;
> +
> + self = MM_BROADBAND_MODEM_TELIT (_self);
> +
> + g_assert (!self->priv->sim_ready_task);
> + g_assert (!self->priv->sim_ready_timeout_id);
> +
> + /* Create new task that we store in the private info, so that it can be
> + * completed early when unsolicited messages arrive. */
> + self->priv->sim_ready_task = g_task_new (self, NULL, callback, user_data);
>
> - /* A short delay is necessary with some SIMs when
> - they have just been unlocked. Using 1 second as secure margin. */
> - g_timeout_add_seconds (1, (GSourceFunc) after_sim_unlock_ready, result);
> + /* If SIM ready already reported, we're done */
> + if (self->priv->sim_ready) {
> + g_task_return_boolean (self->priv->sim_ready_task, TRUE);
> + g_clear_object (&self->priv->sim_ready_task);
> + return;
> + }
> +
> + /* Wait for SIM readiness */
> + self->priv->sim_ready_timeout_id = g_timeout_add_seconds (SIM_READY_TIMEOUT_SECS, (GSourceFunc) after_sim_unlock_ready, self);
> }
>
> /*****************************************************************************/
> @@ -94,6 +137,10 @@ telit_qss_unsolicited_handler (MMPortSerialAt *port,
> switch (qss) {
> case 0:
> mm_info ("QSS: SIM removed");
> +
> + /* Flag as not ready */
> + self->priv->sim_ready = FALSE;
> + modem_after_sim_unlock_cancel (self);
> break;
> case 1:
> mm_info ("QSS: SIM inserted");
> @@ -102,7 +149,8 @@ telit_qss_unsolicited_handler (MMPortSerialAt *port,
> mm_info ("QSS: SIM inserted and PIN unlocked");
> break;
> case 3:
> - mm_info ("QSS: SIM inserted and PIN locked");
> + mm_info ("QSS: SIM inserted and Ready");
> + self->priv->sim_ready = TRUE;
> break;
> default:
> mm_warn ("QSS: unknown QSS value %d", qss);
> @@ -203,9 +251,12 @@ modem_setup_sim_hot_swap (MMIfaceModem *self,
> if (!port)
> port = mm_base_modem_peek_port_primary (MM_BASE_MODEM (self));
>
> + /* We enable QSS=2 so that we get notifications not only of SIM inserted or
> + * not inserted, but also when the SIM is unlocked and ready for SMS and
> + * phonebook access */
> mm_base_modem_at_command_full (MM_BASE_MODEM (self),
> port,
> - "#QSS=1",
> + "#QSS=2",
> 3,
> FALSE,
> FALSE, /* raw */
> @@ -1259,6 +1310,22 @@ mm_broadband_modem_telit_new (const gchar *device,
> static void
> mm_broadband_modem_telit_init (MMBroadbandModemTelit *self)
> {
> + /* Initialize private data */
> + self->priv = G_TYPE_INSTANCE_GET_PRIVATE (self, MM_TYPE_BROADBAND_MODEM_TELIT, MMBroadbandModemTelitPrivate);
> +}
> +
> +static void
> +finalize (GObject *object)
> +{
> + MMBroadbandModemTelit *self = MM_BROADBAND_MODEM_TELIT (object);
> +
> + /* The after sim unlock step takes a full reference of the modem object in
> + * the GTask, and therefore, the object will never be unref-ed while this
> + * operation is pending */
> + g_assert (!self->priv->sim_ready_timeout_id);
> + g_assert (!self->priv->sim_ready_task);
> +
> + G_OBJECT_CLASS (mm_broadband_modem_telit_parent_class)->finalize (object);
> }
>
> static void
> @@ -1304,4 +1371,9 @@ 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));
> +
> + object_class->finalize = finalize;
> }
> diff --git a/plugins/telit/mm-broadband-modem-telit.h b/plugins/telit/mm-broadband-modem-telit.h
> index 50e6365f..f68465e7 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.12.0
More information about the ModemManager-devel
mailing list