diff options
author | Aleksander Morgado <aleksander@aleksander.es> | 2020-09-28 11:57:55 +0200 |
---|---|---|
committer | Aleksander Morgado <aleksander@aleksander.es> | 2020-09-28 11:57:55 +0200 |
commit | 0880bf3f9aa97ef6e2e4c5040f36d1d4411cb72b (patch) | |
tree | 88f934b3ffbf48d084e2a520723b63f25f4d3573 /src/mm-shared-qmi.c | |
parent | e91f2ef315526a1a8a1b451acb5a190686b05225 (diff) |
Revert "shared-qmi: implement SIM/profile change detection"
This reverts commit e91f2ef315526a1a8a1b451acb5a190686b05225.
This was wrongly merged squashing multiple commits together. Reverting
to merge separate commits.
Diffstat (limited to 'src/mm-shared-qmi.c')
-rw-r--r-- | src/mm-shared-qmi.c | 455 |
1 files changed, 0 insertions, 455 deletions
diff --git a/src/mm-shared-qmi.c b/src/mm-shared-qmi.c index bea47a39..5ae54349 100644 --- a/src/mm-shared-qmi.c +++ b/src/mm-shared-qmi.c @@ -92,12 +92,6 @@ typedef struct { gboolean config_active_default; GArray *config_list; gint config_active_i; - - /* Slot status monitoring */ - QmiClient *uim_client; - gulong uim_slot_status_indication_id; - gulong uim_refresh_indication_id; - guint uim_refresh_start_timeout_id; } Private; static void @@ -117,14 +111,6 @@ private_free (Private *priv) g_signal_handler_disconnect (priv->loc_client, priv->loc_location_nmea_indication_id); if (priv->loc_client) g_object_unref (priv->loc_client); - if (priv->uim_slot_status_indication_id) - g_signal_handler_disconnect (priv->uim_client, priv->uim_slot_status_indication_id); - if (priv->uim_refresh_indication_id) - g_signal_handler_disconnect (priv->uim_client, priv->uim_refresh_indication_id); - if (priv->uim_client) - g_object_unref (priv->uim_client); - if (priv->uim_refresh_start_timeout_id) - g_source_remove (priv->uim_refresh_start_timeout_id); g_strfreev (priv->loc_assistance_data_servers); g_slice_free (Private, priv); } @@ -3616,447 +3602,6 @@ mm_shared_qmi_set_primary_sim_slot (MMIfaceModem *self, } /*****************************************************************************/ -/* SIM hot swap detection */ - -#define REFRESH_START_TIMEOUT_SECS 3 - -gboolean -mm_shared_qmi_setup_sim_hot_swap_finish (MMIfaceModem *self, - GAsyncResult *res, - GError **error) -{ - return g_task_propagate_boolean (G_TASK (res), error); -} - -static void -uim_refresh_complete (QmiClientUim *client, - QmiUimSessionType session_type) -{ - g_autoptr(QmiMessageUimRefreshCompleteInput) refresh_complete_input; - GArray *dummy_aid; - - dummy_aid = g_array_new (FALSE, FALSE, sizeof (guint8)); - - refresh_complete_input = qmi_message_uim_refresh_complete_input_new (); - qmi_message_uim_refresh_complete_input_set_session ( - refresh_complete_input, - session_type, - dummy_aid, /* ignored */ - NULL); - qmi_message_uim_refresh_complete_input_set_info ( - refresh_complete_input, - TRUE, - NULL); - - qmi_client_uim_refresh_complete ( - client, - refresh_complete_input, - 10, - NULL, - NULL, - NULL); - g_array_unref (dummy_aid); -} - -static gboolean -uim_start_refresh_timeout (MMSharedQmi *self) -{ - Private *priv; - - priv = get_private (self); - priv->uim_refresh_start_timeout_id = 0; - - mm_obj_dbg (self, "refresh start timed out; trigger SIM change check"); - - mm_iface_modem_check_for_sim_swap (MM_IFACE_MODEM (self), 0, NULL, NULL, NULL); - - return G_SOURCE_REMOVE; -} - -static void -uim_refresh_indication_cb (QmiClientUim *client, - QmiIndicationUimRefreshOutput *output, - MMSharedQmi *self) -{ - QmiUimRefreshStage stage; - QmiUimRefreshMode mode; - QmiUimSessionType session_type; - Private *priv; - g_autoptr(GError) error = NULL; - - priv = get_private (self); - - if (!qmi_indication_uim_refresh_output_get_event (output, - &stage, - &mode, - &session_type, - NULL, - NULL, - &error)) { - mm_obj_warn (self, "couldn't process UIM refresh indication: %s", error->message); - return; - } - - mm_obj_dbg (self, "refresh indication received: session type '%s', stage '%s', mode '%s'", - qmi_uim_session_type_get_string (session_type), - qmi_uim_refresh_stage_get_string (stage), - qmi_uim_refresh_mode_get_string (mode)); - - /* Support only the first slot for now. Primary GW provisioning is used in old modems. */ - if (session_type != QMI_UIM_SESSION_TYPE_CARD_SLOT_1 && - session_type != QMI_UIM_SESSION_TYPE_PRIMARY_GW_PROVISIONING) { - mm_obj_warn (self, "refresh session type not supported: %s", qmi_uim_session_type_get_string (session_type)); - return; - } - - /* Currently we handle only UICC Reset type refresh, which can be used - * in profile switch scenarios. In other cases we just trigger 'refresh - * complete' during start phase. Signal to notify about potential SIM - * profile switch is triggered when the refresh is ending. If it were - * triggered in start phase, reading SIM files seems to fail with - * an internal error. - * - * It's possible that 'end-with-success' stage never appears. For that, - * we start a timer at 'start' stage and if it expires, the SIM change - * check is triggered anyway. */ - if (stage == QMI_UIM_REFRESH_STAGE_START) { - if (mode == QMI_UIM_REFRESH_MODE_RESET) { - if (!priv->uim_refresh_start_timeout_id) - priv->uim_refresh_start_timeout_id = g_timeout_add_seconds (REFRESH_START_TIMEOUT_SECS, - (GSourceFunc)uim_start_refresh_timeout, - self); - } else - uim_refresh_complete (client, session_type); - } else if (stage == QMI_UIM_REFRESH_STAGE_END_WITH_SUCCESS) { - if (mode == QMI_UIM_REFRESH_MODE_RESET) { - if (priv->uim_refresh_start_timeout_id) { - g_source_remove (priv->uim_refresh_start_timeout_id); - priv->uim_refresh_start_timeout_id = 0; - } - mm_iface_modem_check_for_sim_swap (MM_IFACE_MODEM (self), 0, NULL, NULL, NULL); - } - } -} - -static void -uim_slot_status_indication_cb (QmiClientUim *client, - QmiIndicationUimSlotStatusOutput *output, - MMSharedQmi *self) -{ - GArray *physical_slots = NULL; - guint i; - g_autoptr(GError) error = NULL; - - mm_obj_dbg (self, "received slot status indication"); - - if (!qmi_indication_uim_slot_status_output_get_physical_slot_status (output, - &physical_slots, - &error)) { - mm_obj_warn (self, "could not process slot status indication: %s", error->message); - return; - } - - for (i = 0; i < physical_slots->len; i++) { - QmiPhysicalSlotStatusSlot *slot_status; - - slot_status = &g_array_index (physical_slots, QmiPhysicalSlotStatusSlot, i); - - /* We only care about active slot changes */ - if (slot_status->physical_slot_status == QMI_UIM_SLOT_STATE_ACTIVE) { - g_autofree gchar *iccid = NULL; - - if (slot_status->iccid && slot_status->iccid->len > 0) - iccid = mm_bcd_to_string ((const guint8 *) slot_status->iccid->data, slot_status->iccid->len); - - mm_iface_modem_check_for_sim_swap (MM_IFACE_MODEM (self), - i + 1, /* Slot index */ - iccid, - NULL, - NULL); - } - } -} - -static void -uim_refresh_register_iccid_change_ready (QmiClientUim *client, - GAsyncResult *res, - GTask *task) -{ - MMSharedQmi *self; - Private *priv; - g_autoptr(QmiMessageUimRefreshRegisterOutput) output = NULL; - g_autoptr(GError) error = NULL; - - self = g_task_get_source_object (task); - priv = get_private (self); - - output = qmi_client_uim_refresh_register_finish (client, res, &error); - if (!output || !qmi_message_uim_refresh_register_output_get_result (output, &error)) { - mm_obj_dbg (self, "refresh registration using 'refresh register' failed: %s", error->message); - g_clear_object (&priv->uim_client); - g_task_return_new_error (task, MM_MOBILE_EQUIPMENT_ERROR, MM_MOBILE_EQUIPMENT_ERROR_NOT_SUPPORTED, - "SIM hot swap detection not supported by modem"); - } else { - mm_obj_dbg (self, "registered for SIM refresh events using 'refresh register'"); - priv->uim_refresh_indication_id = - g_signal_connect (client, - "refresh", - G_CALLBACK (uim_refresh_indication_cb), - self); - g_task_return_boolean (task, TRUE); - } - g_object_unref (task); -} - -/* This is the last resort if 'refresh register all' does not work. It works - * on some older modems. Those modems may not also support QMI_UIM_SESSION_TYPE_CARD_SLOT_1 - * so we'll use QMI_UIM_SESSION_TYPE_PRIMARY_GW_PROVISIONING */ -static void -uim_refresh_register_iccid_change (GTask *task) -{ - MMSharedQmi *self; - Private *priv; - QmiMessageUimRefreshRegisterInputInfoFilesElement file_element; - guint8 val; - g_autoptr(QmiMessageUimRefreshRegisterInput) refresh_register_input = NULL; - g_autoptr(GArray) dummy_aid = NULL; - g_autoptr(GArray) file = NULL; - g_autoptr(GArray) file_element_path = NULL; - - self = g_task_get_source_object (task); - priv = get_private (MM_SHARED_QMI (self)); - - mm_obj_dbg (self, "register for refresh file indication"); - - dummy_aid = g_array_new (FALSE, FALSE, sizeof (guint8)); - - file = g_array_sized_new (FALSE, FALSE, sizeof (QmiMessageUimRefreshRegisterInputInfoFilesElement), 1); - - file_element_path = g_array_sized_new (FALSE, FALSE, sizeof (guint8), 2); - val = 0x00; - g_array_append_val (file_element_path, val); - val = 0x3F; - g_array_append_val (file_element_path, val); - - - memset (&file_element, 0, sizeof (file_element)); - file_element.file_id = 0x2FE2; /* ICCID */ - file_element.path = file_element_path; - g_array_append_val (file, file_element); - - refresh_register_input = qmi_message_uim_refresh_register_input_new (); - qmi_message_uim_refresh_register_input_set_info (refresh_register_input, - TRUE, - FALSE, - file, - NULL); - qmi_message_uim_refresh_register_input_set_session (refresh_register_input, - QMI_UIM_SESSION_TYPE_PRIMARY_GW_PROVISIONING, - dummy_aid, - NULL); - - qmi_client_uim_refresh_register (QMI_CLIENT_UIM (priv->uim_client), - refresh_register_input, - 10, - NULL, - (GAsyncReadyCallback) uim_refresh_register_iccid_change_ready, - task); -} - -/* Refresh registration and event handling. - * This is used only as fallback in case slot status indications do not work - * in the particular modem (determined by UIM Get Slot Status failing) for - * detecting ICCID changing due to a profile switch. - * - * We assume that devices not supporting UIM Get Slot Status only have a - * single slot, for which we register refresh events. - */ - -static void -uim_refresh_register_all_ready (QmiClientUim *client, - GAsyncResult *res, - GTask *task) -{ - g_autoptr(QmiMessageUimRefreshRegisterAllOutput) output = NULL; - g_autoptr(GError) error = NULL; - MMIfaceModem *self; - Private *priv; - - self = g_task_get_source_object (task); - priv = get_private (MM_SHARED_QMI (self)); - - output = qmi_client_uim_refresh_register_all_finish (client, res, &error); - if (!output || !qmi_message_uim_refresh_register_all_output_get_result (output, &error)) { - if (g_error_matches (error, QMI_PROTOCOL_ERROR, QMI_PROTOCOL_ERROR_NOT_SUPPORTED) || - g_error_matches (error, QMI_PROTOCOL_ERROR, QMI_PROTOCOL_ERROR_INVALID_QMI_COMMAND)) { - /* As last resort, if 'refresh register all' fails, try a plain 'refresh register'. - * Some older modems may not support 'refresh register all'. */ - uim_refresh_register_iccid_change (task); - return; - } - - mm_obj_dbg (self, "refresh register all operation failed: %s", error->message); - g_clear_object (&priv->uim_client); - g_task_return_error (task, g_steal_pointer (&error)); - } else { - mm_obj_dbg (self, "registered for all SIM refresh events"); - priv->uim_refresh_indication_id = - g_signal_connect (client, - "refresh", - G_CALLBACK (uim_refresh_indication_cb), - self); - g_task_return_boolean (task, TRUE); - } - g_object_unref (task); -} - -static void -uim_slot_status_not_supported (GTask *task) -{ - MMIfaceModem *self; - Private *priv; - g_autoptr(QmiMessageUimRefreshRegisterAllInput) refresh_register_all_input = NULL; - g_autoptr(GArray) dummy_aid = NULL; - - self = g_task_get_source_object (task); - priv = get_private (MM_SHARED_QMI (self)); - - g_assert (!priv->uim_refresh_indication_id); - - mm_obj_dbg (self, "slot status not supported by modem: register for refresh indications"); - - dummy_aid = g_array_new (FALSE, FALSE, sizeof (guint8)); - refresh_register_all_input = qmi_message_uim_refresh_register_all_input_new (); - - qmi_message_uim_refresh_register_all_input_set_info (refresh_register_all_input, - TRUE, - NULL); - qmi_message_uim_refresh_register_all_input_set_session (refresh_register_all_input, - QMI_UIM_SESSION_TYPE_CARD_SLOT_1, - dummy_aid, - NULL); - - qmi_client_uim_refresh_register_all (QMI_CLIENT_UIM (priv->uim_client), - refresh_register_all_input, - 10, - NULL, - (GAsyncReadyCallback) uim_refresh_register_all_ready, - task); -} - -static void -uim_check_get_slot_status_ready (QmiClientUim *client, - GAsyncResult *res, - GTask *task) -{ - g_autoptr(QmiMessageUimGetSlotStatusOutput) output = NULL; - g_autoptr(GError) error = NULL; - MMIfaceModem *self; - Private *priv; - - self = g_task_get_source_object (task); - priv = get_private (MM_SHARED_QMI (self)); - - output = qmi_client_uim_get_slot_status_finish (client, res, &error); - if (!output || !qmi_message_uim_get_slot_status_output_get_result (output, &error)) { - if (priv->uim_slot_status_indication_id) { - g_signal_handler_disconnect (client, priv->uim_slot_status_indication_id); - priv->uim_slot_status_indication_id = 0; - } - - if (g_error_matches (error, QMI_PROTOCOL_ERROR, QMI_PROTOCOL_ERROR_NOT_SUPPORTED) || - g_error_matches (error, QMI_PROTOCOL_ERROR, QMI_PROTOCOL_ERROR_INVALID_QMI_COMMAND)) { - uim_slot_status_not_supported (task); - return; - } - - mm_obj_dbg (self, "slot status retrieval failed: %s", error->message); - g_clear_object (&priv->uim_client); - g_task_return_error (task, g_steal_pointer (&error)); - g_object_unref (task); - return; - } - - mm_obj_dbg (self, "slot status retrieval succeeded: monitoring slot status indications"); - g_task_return_boolean (task, TRUE); - g_object_unref (task); -} - -static void -uim_register_events_ready (QmiClientUim *client, - GAsyncResult *res, - GTask *task) -{ - g_autoptr(QmiMessageUimRegisterEventsOutput) output = NULL; - g_autoptr(GError) error = NULL; - MMIfaceModem *self; - Private *priv; - - self = g_task_get_source_object (task); - priv = get_private (MM_SHARED_QMI (self)); - - /* If event registration fails, go on with initialization. In that case - * we cannot use slot status indications to detect eUICC profile switches. */ - output = qmi_client_uim_register_events_finish (client, res, &error); - if (output && qmi_message_uim_register_events_output_get_result (output, &error)) { - g_assert (!priv->uim_slot_status_indication_id); - priv->uim_slot_status_indication_id = g_signal_connect (priv->uim_client, - "slot-status", - G_CALLBACK (uim_slot_status_indication_cb), - self); - mm_obj_dbg (self, "registered for slot status indications"); - - /* Successful registration does not mean that the modem actually sends - * physical slot status indications; invoke Get Slot Status to find out if - * the modem really supports slot status. */ - qmi_client_uim_get_slot_status (client, - NULL, - 10, - NULL, - (GAsyncReadyCallback) uim_check_get_slot_status_ready, - task); - return; - } - - mm_obj_dbg (self, "not registered for slot status indications: %s", error->message); - uim_slot_status_not_supported (task); -} - -void -mm_shared_qmi_setup_sim_hot_swap (MMIfaceModem *self, - GAsyncReadyCallback callback, - gpointer user_data) -{ - g_autoptr(QmiMessageUimRegisterEventsInput) register_events_input = NULL; - GTask *task; - QmiClient *client = NULL; - Private *priv; - - if (!mm_shared_qmi_ensure_client (MM_SHARED_QMI (self), - QMI_SERVICE_UIM, &client, - callback, user_data)) - return; - - task = g_task_new (self, NULL, callback, user_data); - priv = get_private (MM_SHARED_QMI (self)); - - g_assert (!priv->uim_slot_status_indication_id); - g_assert (!priv->uim_client); - priv->uim_client = g_object_ref (client); - - register_events_input = qmi_message_uim_register_events_input_new (); - qmi_message_uim_register_events_input_set_event_registration_mask (register_events_input, - QMI_UIM_EVENT_REGISTRATION_FLAG_PHYSICAL_SLOT_STATUS, - NULL); - qmi_client_uim_register_events (QMI_CLIENT_UIM (priv->uim_client), - register_events_input, - 10, - NULL, - (GAsyncReadyCallback) uim_register_events_ready, - task); -} - -/*****************************************************************************/ /* Location: Set SUPL server */ typedef struct { |