diff options
author | Carlo Lobrano <c.lobrano@gmail.com> | 2017-04-13 11:53:53 +0200 |
---|---|---|
committer | Aleksander Morgado <aleksander@aleksander.es> | 2017-04-15 22:52:12 +0200 |
commit | a902199772ce3d9155919d5d8ef3df81e7f776a6 (patch) | |
tree | 679f4adf65d3a38444481d7ebf9c8c6c3015f6d1 | |
parent | 23b67db7c98a3f2fafd7d32a4c26fe02d81624ec (diff) |
telit: unsupported CSIM lock should not skip loading unlock retries
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).
-rw-r--r-- | plugins/telit/mm-broadband-modem-telit.c | 94 | ||||
-rw-r--r-- | 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 fb169fd2..95eeb71c 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) { @@ -1265,6 +1319,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 @@ -1310,4 +1369,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 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{ |