[PATCH v3] telit-plugin: ignore QSS when SIM-ME interface is locked
Aleksander Morgado
aleksander at aleksander.es
Tue Aug 1 08:33:41 UTC 2017
On 28/07/17 15:57, Carlo Lobrano wrote:
> With some modems, the lock/unlock of the SIM-ME interface with +CSIM=1/0
> command is followed by #QSS unsolicited messages. With the current
> implementation, this messages are mistaken for SIM swap events and so the
> modem is first dropped and then re-probed.
>
> With this patch, the plugin takes into account the SIM-ME lock state when
> parsing #QSS unsolicited, so that the QSS handler can correctly
> elaborate the messages that are not related to SIM swap events.
> ---
>
> I spotted an error in version 2: csim_lock_task was saved in priv only if CSIM was locked
>
Pushed to git master, thanks.
> ---
> plugins/telit/mm-broadband-modem-telit.c | 85 ++++++++++++++++++++++++++++----
> plugins/telit/mm-modem-helpers-telit.h | 9 ++++
> 2 files changed, 85 insertions(+), 9 deletions(-)
>
> diff --git a/plugins/telit/mm-broadband-modem-telit.c b/plugins/telit/mm-broadband-modem-telit.c
> index e7650c0..2c6f7a9 100644
> --- a/plugins/telit/mm-broadband-modem-telit.c
> +++ b/plugins/telit/mm-broadband-modem-telit.c
> @@ -44,6 +44,8 @@ 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));
>
> +#define CSIM_UNLOCK_MAX_TIMEOUT 3
> +
> typedef enum {
> FEATURE_SUPPORT_UNKNOWN,
> FEATURE_NOT_SUPPORTED,
> @@ -53,6 +55,9 @@ typedef enum {
> struct _MMBroadbandModemTelitPrivate {
> FeatureSupport csim_lock_support;
> MMTelitQssStatus qss_status;
> + MMTelitCsimLockState csim_lock_state;
> + GTask *csim_lock_task;
> + guint csim_lock_timeout_id;
> };
>
> /*****************************************************************************/
> @@ -107,6 +112,7 @@ typedef struct {
> } QssSetupContext;
>
> static void qss_setup_step (GTask *task);
> +static void pending_csim_unlock_complete (MMBroadbandModemTelit *self);
>
> static void
> telit_qss_unsolicited_handler (MMPortSerialAt *port,
> @@ -122,14 +128,36 @@ telit_qss_unsolicited_handler (MMPortSerialAt *port,
> prev_qss_status = self->priv->qss_status;
> self->priv->qss_status = cur_qss_status;
>
> + if (self->priv->csim_lock_state >= CSIM_LOCK_STATE_LOCK_REQUESTED) {
> +
> + if (prev_qss_status > QSS_STATUS_SIM_REMOVED && cur_qss_status == QSS_STATUS_SIM_REMOVED) {
> + mm_dbg ("QSS handler: #QSS=0 after +CSIM=1 -> CSIM locked!");
> + self->priv->csim_lock_state = CSIM_LOCK_STATE_LOCKED;
> + }
> +
> + if (prev_qss_status == QSS_STATUS_SIM_REMOVED && cur_qss_status != QSS_STATUS_SIM_REMOVED) {
> + mm_dbg ("QSS handler: #QSS>=1 after +CSIM=0 -> CSIM unlocked!");
> + self->priv->csim_lock_state = CSIM_LOCK_STATE_UNLOCKED;
> +
> + if (self->priv->csim_lock_timeout_id) {
> + g_source_remove (self->priv->csim_lock_timeout_id);
> + self->priv->csim_lock_timeout_id = 0;
> + }
> +
> + pending_csim_unlock_complete (self);
> + }
> +
> + return;
> + }
> +
> if (cur_qss_status != prev_qss_status)
> - mm_dbg ("QSS: status changed '%s -> %s",
> + mm_dbg ("QSS handler: status changed '%s -> %s",
> mm_telit_qss_status_get_string (prev_qss_status),
> mm_telit_qss_status_get_string (cur_qss_status));
>
> if ((prev_qss_status == QSS_STATUS_SIM_REMOVED && cur_qss_status != QSS_STATUS_SIM_REMOVED) ||
> (prev_qss_status > QSS_STATUS_SIM_REMOVED && cur_qss_status == QSS_STATUS_SIM_REMOVED)) {
> - mm_info ("QSS: SIM swap detected");
> + mm_info ("QSS handler: SIM swap detected");
> mm_broadband_modem_update_sim_hot_swap_detected (MM_BROADBAND_MODEM (self));
> }
> }
> @@ -610,8 +638,9 @@ csim_unlock_ready (MMBaseModem *_self,
> if (!response) {
> if (g_error_matches (error,
> MM_MOBILE_EQUIPMENT_ERROR,
> - MM_MOBILE_EQUIPMENT_ERROR_NOT_SUPPORTED))
> + MM_MOBILE_EQUIPMENT_ERROR_NOT_SUPPORTED)) {
> self->priv->csim_lock_support = FEATURE_NOT_SUPPORTED;
> + }
> mm_warn ("Couldn't unlock SIM card: %s", error->message);
> g_error_free (error);
> }
> @@ -703,6 +732,8 @@ csim_lock_ready (MMBaseModem *_self,
> g_object_unref (task);
> return;
> }
> + } else {
> + self->priv->csim_lock_state = CSIM_LOCK_STATE_LOCK_REQUESTED;
> }
>
> if (self->priv->csim_lock_support != FEATURE_NOT_SUPPORTED) {
> @@ -755,6 +786,37 @@ handle_csim_locking (GTask *task,
> }
>
> static void
> +pending_csim_unlock_complete (MMBroadbandModemTelit *self)
> +{
> + LoadUnlockRetriesContext *ctx;
> +
> + ctx = g_task_get_task_data (self->priv->csim_lock_task);
> +
> + if (ctx->succeded_requests == 0) {
> + g_task_return_new_error (self->priv->csim_lock_task, MM_CORE_ERROR, MM_CORE_ERROR_FAILED,
> + "Could not get any of the SIM unlock retries values");
> + } else {
> + g_task_return_pointer (self->priv->csim_lock_task, g_object_ref (ctx->retries), g_object_unref);
> + }
> +
> + g_clear_object (&self->priv->csim_lock_task);
> +}
> +
> +static gboolean
> +csim_unlock_periodic_check (MMBroadbandModemTelit *self)
> +{
> + if (self->priv->csim_lock_state != CSIM_LOCK_STATE_UNLOCKED) {
> + mm_warn ("CSIM is still locked after %d seconds. Trying to continue anyway", CSIM_UNLOCK_MAX_TIMEOUT);
> + }
> +
> + self->priv->csim_lock_timeout_id = 0;
> + pending_csim_unlock_complete (self);
> + g_object_unref (self);
> +
> + return G_SOURCE_REMOVE;
> +}
> +
> +static void
> load_unlock_retries_step (GTask *task)
> {
> MMBroadbandModemTelit *self;
> @@ -805,12 +867,16 @@ load_unlock_retries_step (GTask *task)
> handle_csim_locking (task, FALSE);
> break;
> case LOAD_UNLOCK_RETRIES_STEP_LAST:
> - if (ctx->succeded_requests == 0)
> - g_task_return_new_error (task, MM_CORE_ERROR, MM_CORE_ERROR_FAILED,
> - "Could not get any of the SIM unlock retries values");
> - else
> - g_task_return_pointer (task, g_object_ref (ctx->retries), g_object_unref);
> - g_object_unref (task);
> + self->priv->csim_lock_task = task;
> + if (self->priv->csim_lock_state == CSIM_LOCK_STATE_LOCKED) {
> + mm_dbg ("CSIM is locked. Waiting for #QSS=1");
> + self->priv->csim_lock_timeout_id = g_timeout_add_seconds (CSIM_UNLOCK_MAX_TIMEOUT,
> + (GSourceFunc) csim_unlock_periodic_check,
> + g_object_ref(self));
> + } else {
> + self->priv->csim_lock_state = CSIM_LOCK_STATE_UNLOCKED;
> + pending_csim_unlock_complete (self);
> + }
> break;
> default:
> break;
> @@ -1388,6 +1454,7 @@ mm_broadband_modem_telit_init (MMBroadbandModemTelit *self)
> MMBroadbandModemTelitPrivate);
>
> self->priv->csim_lock_support = FEATURE_SUPPORT_UNKNOWN;
> + self->priv->csim_lock_state = CSIM_LOCK_STATE_UNKNOWN;
> self->priv->qss_status = QSS_STATUS_UNKNOWN;
> }
>
> diff --git a/plugins/telit/mm-modem-helpers-telit.h b/plugins/telit/mm-modem-helpers-telit.h
> index 24c39e0..1cf76f0 100644
> --- a/plugins/telit/mm-modem-helpers-telit.h
> +++ b/plugins/telit/mm-modem-helpers-telit.h
> @@ -110,4 +110,13 @@ typedef enum { /*< underscore_name=mm_telit_qss_status >*/
>
> MMTelitQssStatus mm_telit_parse_qss_query (const gchar *response, GError **error);
>
> +/* CSIM lock state */
> +typedef enum { /*< underscore_name=mm_telit_csim_lock_state >*/
> + CSIM_LOCK_STATE_UNKNOWN,
> + CSIM_LOCK_STATE_UNLOCKED,
> + CSIM_LOCK_STATE_LOCK_REQUESTED,
> + CSIM_LOCK_STATE_LOCKED,
> +} MMTelitCsimLockState;
> +
> +
> #endif /* MM_MODEM_HELPERS_TELIT_H */
>
--
Aleksander
https://aleksander.es
More information about the ModemManager-devel
mailing list