diff options
author | Michal Mazur <mkm@semihalf.com> | 2021-04-20 11:33:57 +0200 |
---|---|---|
committer | Aleksander Morgado <aleksander@aleksander.es> | 2021-05-22 23:56:22 +0000 |
commit | d76c5c9bcd7b94b89f26a434235dd25297f5159b (patch) | |
tree | 530f3614e68d9e468a50eb98e5615109072b8460 /src | |
parent | c6b5045105a12098ddd8177f8a3c43d73e3f6680 (diff) |
modem-qmi: detect personalization locks in LOCKED state
Diffstat (limited to 'src')
-rw-r--r-- | src/mm-broadband-modem-qmi.c | 80 | ||||
-rw-r--r-- | src/mm-modem-helpers-qmi.c | 54 |
2 files changed, 132 insertions, 2 deletions
diff --git a/src/mm-broadband-modem-qmi.c b/src/mm-broadband-modem-qmi.c index da1cd883..12244b05 100644 --- a/src/mm-broadband-modem-qmi.c +++ b/src/mm-broadband-modem-qmi.c @@ -2256,6 +2256,18 @@ modem_3gpp_load_enabled_facility_locks (MMIfaceModem3gpp *self, /*****************************************************************************/ /* Facility locks disabling (3GPP interface) */ +# define DISABLE_FACILITY_LOCK_CHECK_TIMEOUT_MS 100 +# define DISABLE_FACILITY_LOCK_CHECK_ATTEMPTS 10 + +typedef struct _DisableFacilityLockContext DisableFacilityLockContext; +struct _DisableFacilityLockContext { + MMModem3gppFacility facility; + guint remaining_attempts; + guint8 slot; +}; + +static gboolean disable_facility_lock_check (GTask *task); + static gboolean modem_3gpp_disable_facility_lock_finish (MMIfaceModem3gpp *self, GAsyncResult *res, @@ -2265,6 +2277,60 @@ modem_3gpp_disable_facility_lock_finish (MMIfaceModem3gpp *self, } static void +disable_facility_lock_check_ready (MMIfaceModem3gpp *self, + GAsyncResult *res, + GTask *task) +{ + DisableFacilityLockContext *ctx; + MMModem3gppFacility facilities; + GError *error = NULL; + + ctx = g_task_get_task_data (task); + + facilities = modem_3gpp_load_enabled_facility_locks_finish (self, res, &error); + if (error) { + g_prefix_error (&error, "Failed to check the facility locks: "); + g_task_return_error (task, error); + g_object_unref (task); + return; + } + + /* Check if the facility lock is still enabled */ + if (facilities & ctx->facility) { + /* Wait again and retry */ + g_timeout_add (DISABLE_FACILITY_LOCK_CHECK_TIMEOUT_MS, + (GSourceFunc)disable_facility_lock_check, + task); + return; + } + + g_task_return_boolean (task, TRUE); + g_object_unref (task); +} + +static gboolean +disable_facility_lock_check (GTask *task) +{ + DisableFacilityLockContext *ctx; + MMIfaceModem3gpp *self; + + self = g_task_get_source_object (task); + ctx = g_task_get_task_data (task); + if (ctx->remaining_attempts) { + ctx->remaining_attempts--; + modem_3gpp_load_enabled_facility_locks (self, + (GAsyncReadyCallback)disable_facility_lock_check_ready, + task); + } else { + g_task_return_new_error (task, MM_CORE_ERROR, MM_CORE_ERROR_FAILED, + "Failed to disable the facility lock."); + g_object_unref (task); + } + + return G_SOURCE_REMOVE; +} + +static void disable_facility_lock_ready (QmiClientUim *client, GAsyncResult *res, GTask *task) @@ -2277,13 +2343,16 @@ disable_facility_lock_ready (QmiClientUim *client, !qmi_message_uim_depersonalization_output_get_result (output, &error)) { g_prefix_error (&error, "QMI message Depersonalization failed: "); g_task_return_error (task, error); + g_object_unref (task); } else { - g_task_return_boolean (task, TRUE); + /* Wait defined time for lock change to propagate to Card Status */ + g_timeout_add (DISABLE_FACILITY_LOCK_CHECK_TIMEOUT_MS, + (GSourceFunc)disable_facility_lock_check, + task); } if (output) qmi_message_uim_depersonalization_output_unref (output); - g_object_unref (task); } static void @@ -2296,6 +2365,7 @@ modem_3gpp_disable_facility_lock (MMIfaceModem3gpp *self, { QmiUimCardApplicationPersonalizationFeature feature; QmiMessageUimDepersonalizationInput *input; + DisableFacilityLockContext *ctx; QmiClient *client = NULL; GTask *task; @@ -2327,6 +2397,12 @@ modem_3gpp_disable_facility_lock (MMIfaceModem3gpp *self, NULL); qmi_message_uim_depersonalization_input_set_slot (input, slot, NULL); + ctx = g_new0 (DisableFacilityLockContext, 1); + ctx->facility = facility; + ctx->slot = slot; + ctx->remaining_attempts = DISABLE_FACILITY_LOCK_CHECK_ATTEMPTS; + g_task_set_task_data (task, ctx, g_free); + qmi_client_uim_depersonalization (QMI_CLIENT_UIM (client), input, 30, diff --git a/src/mm-modem-helpers-qmi.c b/src/mm-modem-helpers-qmi.c index c95aa9eb..4fbb9a1d 100644 --- a/src/mm-modem-helpers-qmi.c +++ b/src/mm-modem-helpers-qmi.c @@ -2175,6 +2175,7 @@ mm_qmi_uim_get_card_status_output_parse (gpointer log_ if (app->state != QMI_UIM_CARD_APPLICATION_STATE_READY && app->state != QMI_UIM_CARD_APPLICATION_STATE_PIN1_OR_UPIN_PIN_REQUIRED && app->state != QMI_UIM_CARD_APPLICATION_STATE_PUK1_OR_UPIN_PUK_REQUIRED && + app->state != QMI_UIM_CARD_APPLICATION_STATE_CHECK_PERSONALIZATION_STATE && app->state != QMI_UIM_CARD_APPLICATION_STATE_PIN1_BLOCKED) { mm_obj_dbg (log_object, "neither SIM nor USIM are ready"); g_set_error (error, MM_CORE_ERROR, MM_CORE_ERROR_RETRY, @@ -2240,6 +2241,59 @@ mm_qmi_uim_get_card_status_output_parse (gpointer log_ return FALSE; } + /* Personalization */ + if (lock == MM_MODEM_LOCK_NONE && + app->state == QMI_UIM_CARD_APPLICATION_STATE_CHECK_PERSONALIZATION_STATE) { + if (app->personalization_state == QMI_UIM_CARD_APPLICATION_PERSONALIZATION_STATE_IN_PROGRESS || + app->personalization_state == QMI_UIM_CARD_APPLICATION_PERSONALIZATION_STATE_UNKNOWN) { + g_set_error (error, + MM_CORE_ERROR, + MM_CORE_ERROR_RETRY, + "Personalization check in progress"); + return FALSE; + } + if (app->personalization_state == QMI_UIM_CARD_APPLICATION_PERSONALIZATION_STATE_CODE_REQUIRED || + app->personalization_state == QMI_UIM_CARD_APPLICATION_PERSONALIZATION_STATE_PUK_CODE_REQUIRED) { + gboolean pin; + + pin = app->personalization_state == QMI_UIM_CARD_APPLICATION_PERSONALIZATION_STATE_CODE_REQUIRED; + + switch (app->personalization_feature) { + case QMI_UIM_CARD_APPLICATION_PERSONALIZATION_FEATURE_GW_NETWORK: + lock = (pin ? MM_MODEM_LOCK_PH_NET_PIN : MM_MODEM_LOCK_PH_NET_PUK); + break; + case QMI_UIM_CARD_APPLICATION_PERSONALIZATION_FEATURE_GW_NETWORK_SUBSET: + lock = (pin ? MM_MODEM_LOCK_PH_NETSUB_PIN : MM_MODEM_LOCK_PH_NETSUB_PUK); + break; + case QMI_UIM_CARD_APPLICATION_PERSONALIZATION_FEATURE_GW_SERVICE_PROVIDER: + lock = (pin ? MM_MODEM_LOCK_PH_SP_PIN : MM_MODEM_LOCK_PH_SP_PUK); + break; + case QMI_UIM_CARD_APPLICATION_PERSONALIZATION_FEATURE_GW_CORPORATE: + lock = (pin ? MM_MODEM_LOCK_PH_CORP_PIN : MM_MODEM_LOCK_PH_CORP_PUK); + break; + case QMI_UIM_CARD_APPLICATION_PERSONALIZATION_FEATURE_GW_UIM: + if (pin) { + lock = MM_MODEM_LOCK_PH_SIM_PIN; + break; + } + /* fall through */ + case QMI_UIM_CARD_APPLICATION_PERSONALIZATION_FEATURE_1X_NETWORK_TYPE_1: + case QMI_UIM_CARD_APPLICATION_PERSONALIZATION_FEATURE_1X_NETWORK_TYPE_2: + case QMI_UIM_CARD_APPLICATION_PERSONALIZATION_FEATURE_1X_HRPD: + case QMI_UIM_CARD_APPLICATION_PERSONALIZATION_FEATURE_1X_SERVICE_PROVIDER: + case QMI_UIM_CARD_APPLICATION_PERSONALIZATION_FEATURE_1X_CORPORATE: + case QMI_UIM_CARD_APPLICATION_PERSONALIZATION_FEATURE_1X_RUIM: + case QMI_UIM_CARD_APPLICATION_PERSONALIZATION_FEATURE_UNKNOWN: + default: + g_set_error (error, + MM_MOBILE_EQUIPMENT_ERROR, + MM_MOBILE_EQUIPMENT_ERROR_SIM_WRONG, + "Unsupported personalization feature"); + return FALSE; + } + } + } + /* PIN2 */ if (lock == MM_MODEM_LOCK_NONE) { switch (app->pin2_state) { |