modem-qmi: detect personalization locks in LOCKED state

This commit is contained in:
Michal Mazur
2021-04-20 11:33:57 +02:00
committed by Aleksander Morgado
parent c6b5045105
commit d76c5c9bcd
2 changed files with 132 additions and 2 deletions

View File

@@ -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,
@@ -2264,6 +2276,60 @@ modem_3gpp_disable_facility_lock_finish (MMIfaceModem3gpp *self,
return g_task_propagate_boolean (G_TASK (res), error);
}
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,
@@ -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,

View File

@@ -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) {