diff options
-rw-r--r-- | src/mm-broadband-modem-mbim.c | 133 | ||||
-rw-r--r-- | src/mm-broadband-modem.c | 16 | ||||
-rw-r--r-- | src/mm-iface-modem.c | 92 | ||||
-rw-r--r-- | src/mm-iface-modem.h | 15 | ||||
-rw-r--r-- | src/mm-shared-qmi.c | 4 | ||||
-rw-r--r-- | src/plugins/quectel/mm-shared-quectel.c | 2 |
6 files changed, 221 insertions, 41 deletions
diff --git a/src/mm-broadband-modem-mbim.c b/src/mm-broadband-modem-mbim.c index 882d6a09..aaa561ca 100644 --- a/src/mm-broadband-modem-mbim.c +++ b/src/mm-broadband-modem-mbim.c @@ -6361,6 +6361,137 @@ modem_setup_sim_hot_swap (MMIfaceModem *_self, } /*****************************************************************************/ +/* Check basic SIM details */ + +typedef struct { + gboolean sim_inserted; + gchar *iccid; + gchar *imsi; +} SimDetails; + +static void sim_details_free (SimDetails *sim_info) { + g_free (sim_info->iccid); + g_free (sim_info->imsi); + g_slice_free (SimDetails, sim_info); +} + +static gboolean +modem_check_basic_sim_details_finish (MMIfaceModem *self, + GAsyncResult *res, + gboolean *sim_inserted, + gchar **iccid, + gchar **imsi, + GError **error) +{ + SimDetails *sim_info; + + sim_info = g_task_propagate_pointer (G_TASK (res), error); + if (!sim_info) + return FALSE; + + *sim_inserted = sim_info->sim_inserted; + if (iccid) + *iccid = g_steal_pointer (&sim_info->iccid); + if (imsi) + *imsi = g_steal_pointer (&sim_info->imsi); + sim_details_free (sim_info); + return TRUE; +} + +static void +basic_sim_details_subscriber_ready_state_ready (MbimDevice *device, + GAsyncResult *res, + GTask *task) +{ + MMBroadbandModemMbim *self; + g_autoptr(MbimMessage) response = NULL; + GError *error = NULL; + gchar *imsi = NULL; + g_autofree gchar *raw_iccid = NULL; + MbimSubscriberReadyState ready_state = MBIM_SUBSCRIBER_READY_STATE_NOT_INITIALIZED; + + self = g_task_get_source_object (task); + + response = mbim_device_command_finish (device, res, &error); + if (!response || !mbim_message_response_get_result (response, MBIM_MESSAGE_TYPE_COMMAND_DONE, &error)) { + g_task_return_error (task, error); + g_object_unref (task); + return; + } + + if (mbim_device_check_ms_mbimex_version (device, 3, 0)) { + if (!mbim_message_ms_basic_connect_v3_subscriber_ready_status_response_parse ( + response, + &ready_state, /* ready_state */ + NULL, /* flags */ + &imsi, /* subscriber id */ + &raw_iccid, /* sim_iccid */ + NULL, /* ready_info */ + NULL, /* telephone_numbers_count */ + NULL, + &error)) + g_prefix_error (&error, "Failed processing MBIMEx v3.0 subscriber ready status response: "); + else + mm_obj_dbg (self, "processed MBIMEx v3.0 subscriber ready status response"); + } else { + if (!mbim_message_subscriber_ready_status_response_parse ( + response, + &ready_state, /* ready_state */ + &imsi, /* subscriber id */ + &raw_iccid, /* sim_iccid */ + NULL, /* ready_info */ + NULL, /* telephone_numbers_count */ + NULL, + &error)) + g_prefix_error (&error, "Failed processing subscriber ready status response: "); + else + mm_obj_dbg (self, "processed subscriber ready status response"); + } + + if (error) + g_task_return_error (task, error); + else { + SimDetails *sim_details; + g_autoptr(GError) inner_error = NULL; + + sim_details = g_slice_new0 (SimDetails); + if (ready_state != MBIM_SUBSCRIBER_READY_STATE_SIM_NOT_INSERTED) { + sim_details->sim_inserted = TRUE; + sim_details->iccid = mm_3gpp_parse_iccid (raw_iccid, &inner_error); + if (!sim_details->iccid) { + mm_obj_warn (self, "can not get ICCID info: couldn't parse SIM ICCID: %s", inner_error->message); + } + sim_details->imsi = imsi; + } + g_task_return_pointer (task, sim_details, (GDestroyNotify)sim_details_free); + } + g_object_unref (task); +} + +static void +modem_check_basic_sim_details (MMIfaceModem *self, + GAsyncReadyCallback callback, + gpointer user_data) +{ + MbimDevice *device; + GTask *task; + g_autoptr(MbimMessage) message = NULL; + + if (!peek_device (self, &device, callback, user_data)) + return; + + task = g_task_new (self, NULL, callback, user_data); + + message = mbim_message_subscriber_ready_status_query_new (NULL); + mbim_device_command (device, + message, + 10, + NULL, + (GAsyncReadyCallback)basic_sim_details_subscriber_ready_state_ready, + task); +} + +/*****************************************************************************/ /* Enable/Disable unsolicited events (3GPP interface) */ static gboolean @@ -9911,6 +10042,8 @@ iface_modem_init (MMIfaceModem *iface) /* SIM hot swapping */ iface->setup_sim_hot_swap = modem_setup_sim_hot_swap; iface->setup_sim_hot_swap_finish = modem_setup_sim_hot_swap_finish; + iface->check_basic_sim_details = modem_check_basic_sim_details; + iface->check_basic_sim_details_finish = modem_check_basic_sim_details_finish; /* Other actions */ #if defined WITH_QMI && QMI_MBIM_QMUX_SUPPORTED diff --git a/src/mm-broadband-modem.c b/src/mm-broadband-modem.c index 10a67ea3..4f7e5cf8 100644 --- a/src/mm-broadband-modem.c +++ b/src/mm-broadband-modem.c @@ -4315,20 +4315,12 @@ sim_swap_check_step (GTask *task) case SIM_SWAP_CHECK_STEP_ICCID_CHANGED: ctx->retries = SIM_SWAP_CHECK_LOAD_RETRIES_MAX; - /* We may or may not get the new SIM identifier (iccid). In case - * we've got it, the load_sim_identifier phase can be skipped. */ - if (ctx->iccid) - complete_sim_swap_check (task, ctx->iccid); - else - load_sim_identifier (task); + load_sim_identifier (task); return; case SIM_SWAP_CHECK_STEP_IMSI_CHANGED: ctx->retries = SIM_SWAP_CHECK_LOAD_RETRIES_MAX; - if (ctx->imsi) - complete_sim_swap_check (task, ctx->imsi); - else - load_sim_imsi (task); + load_sim_imsi (task); return; case SIM_SWAP_CHECK_STEP_LAST: @@ -4347,8 +4339,6 @@ sim_swap_check_step (GTask *task) static void modem_check_for_sim_swap (MMIfaceModem *self, - const gchar *iccid, - const gchar *imsi, GAsyncReadyCallback callback, gpointer user_data) { @@ -4360,8 +4350,6 @@ modem_check_for_sim_swap (MMIfaceModem *self, task = g_task_new (self, NULL, callback, user_data); ctx = g_slice_new0 (SimSwapContext); ctx->step = SIM_SWAP_CHECK_STEP_FIRST; - ctx->iccid = g_strdup (iccid); - ctx->imsi = g_strdup (imsi); g_task_set_task_data (task, ctx, (GDestroyNotify)sim_swap_context_free); g_object_get (self, diff --git a/src/mm-iface-modem.c b/src/mm-iface-modem.c index 54063c47..cf79fd10 100644 --- a/src/mm-iface-modem.c +++ b/src/mm-iface-modem.c @@ -141,6 +141,60 @@ mm_iface_modem_check_for_sim_swap_finish (MMIfaceModem *self, } static void +check_basic_sim_details_ready (MMIfaceModem *self, + GAsyncResult *res, + GTask *task) +{ + g_autoptr(MMBaseSim) sim = NULL; + GError *error = NULL; + const gchar *old_iccid = NULL; + const gchar *old_imsi = NULL; + g_autofree gchar *current_iccid = NULL; + g_autofree gchar *current_imsi = NULL; + gboolean sim_inserted; + + if (!MM_IFACE_MODEM_GET_INTERFACE (self)->check_basic_sim_details_finish ( + self, res, &sim_inserted, ¤t_iccid, ¤t_imsi, &error)) { + mm_obj_warn (self, "SIM details check failed: %s", error->message); + g_task_return_error (task, error); + g_object_unref (task); + return; + } + + g_object_get (self, MM_IFACE_MODEM_SIM, &sim, NULL); + if (sim) { + old_iccid = mm_gdbus_sim_get_sim_identifier (MM_GDBUS_SIM (sim)); + old_imsi = mm_gdbus_sim_get_imsi (MM_GDBUS_SIM (sim)); + } + + if (!sim && !sim_inserted) { + mm_obj_info (self, "No SIM inserted before and after"); + } else if (sim && !sim_inserted) { + mm_obj_info (self, "SIM removed"); + mm_iface_modem_process_sim_event (self); + } else if (!sim && sim_inserted) { + mm_obj_info (self, "SIM inserted"); + mm_iface_modem_process_sim_event (self); + } else if ((g_strcmp0 (current_iccid, old_iccid) != 0) || + (g_strcmp0 (current_imsi, old_imsi) != 0)) { + mm_obj_info (self, "new SIM detected"); + mm_obj_info (self, "ICCID: %s -> %s", + mm_log_str_personal_info (old_iccid), + mm_log_str_personal_info (current_iccid)); + mm_obj_info (self, "IMSI: %s -> %s", + mm_log_str_personal_info (old_imsi), + mm_log_str_personal_info (current_imsi)); + mm_iface_modem_process_sim_event (self); + } else { + mm_obj_info (self, "SIM not changed. ICCID: %s, IMSI: %s", + mm_log_str_personal_info (current_iccid), + mm_log_str_personal_info (current_imsi)); + } + g_task_return_boolean (task, TRUE); + g_object_unref (task); +} + +static void explicit_check_for_sim_swap_ready (MMIfaceModem *self, GAsyncResult *res, GTask *task) @@ -159,8 +213,6 @@ explicit_check_for_sim_swap_ready (MMIfaceModem *self, void mm_iface_modem_check_for_sim_swap (MMIfaceModem *self, - const gchar *iccid, - const gchar *imsi, GAsyncReadyCallback callback, gpointer user_data) { @@ -168,21 +220,29 @@ mm_iface_modem_check_for_sim_swap (MMIfaceModem *self, task = g_task_new (self, NULL, callback, user_data); - if (!MM_IFACE_MODEM_GET_INTERFACE (self)->check_for_sim_swap || - !MM_IFACE_MODEM_GET_INTERFACE (self)->check_for_sim_swap_finish) { - mm_obj_info (self, "checking for SIM swap ignored: not implemented"); - g_task_return_boolean (task, TRUE); - g_object_unref (task); + if (MM_IFACE_MODEM_GET_INTERFACE (self)->check_basic_sim_details && + MM_IFACE_MODEM_GET_INTERFACE (self)->check_basic_sim_details_finish) { + mm_obj_info (self, "started checking for basic SIM details..."); + MM_IFACE_MODEM_GET_INTERFACE (self)->check_basic_sim_details ( + self, + (GAsyncReadyCallback)check_basic_sim_details_ready, + task); return; } - mm_obj_info (self, "started checking for SIM swap..."); - MM_IFACE_MODEM_GET_INTERFACE (self)->check_for_sim_swap ( - self, - iccid, - imsi, - (GAsyncReadyCallback)explicit_check_for_sim_swap_ready, - task); + if (MM_IFACE_MODEM_GET_INTERFACE (self)->check_for_sim_swap && + MM_IFACE_MODEM_GET_INTERFACE (self)->check_for_sim_swap_finish) { + mm_obj_info (self, "started checking for SIM swap..."); + MM_IFACE_MODEM_GET_INTERFACE (self)->check_for_sim_swap ( + self, + (GAsyncReadyCallback)explicit_check_for_sim_swap_ready, + task); + return; + } + + mm_obj_info (self, "checking for SIM swap ignored: not implemented"); + g_task_return_boolean (task, TRUE); + g_object_unref (task); } /*****************************************************************************/ @@ -4421,8 +4481,6 @@ interface_enabling_step (GTask *task) MM_IFACE_MODEM_GET_INTERFACE (self)->check_for_sim_swap_finish) { MM_IFACE_MODEM_GET_INTERFACE (self)->check_for_sim_swap ( self, - NULL, - NULL, (GAsyncReadyCallback)check_for_sim_swap_ready, task); return; @@ -4618,8 +4676,6 @@ interface_syncing_step (GTask *task) */ mm_iface_modem_check_for_sim_swap ( self, - NULL, - NULL, (GAsyncReadyCallback)sync_detect_sim_swap_ready, task); return; diff --git a/src/mm-iface-modem.h b/src/mm-iface-modem.h index f6e81f22..37c961d8 100644 --- a/src/mm-iface-modem.h +++ b/src/mm-iface-modem.h @@ -291,14 +291,22 @@ struct _MMIfaceModem { * Useful for when the modem changes power states since we might * not get the relevant notifications from the modem. */ void (*check_for_sim_swap) (MMIfaceModem *self, - const gchar *iccid, - const gchar *imsi, GAsyncReadyCallback callback, gpointer user_data); gboolean (*check_for_sim_swap_finish) (MMIfaceModem *self, GAsyncResult *res, GError **error); + void (*check_basic_sim_details) (MMIfaceModem *self, + GAsyncReadyCallback callback, + gpointer user_data); + gboolean (*check_basic_sim_details_finish) (MMIfaceModem *self, + GAsyncResult *res, + gboolean *sim_inserted, + gchar **iccid, + gchar **imsi, + GError **error); + /* Asynchronous flow control setup */ void (*setup_flow_control) (MMIfaceModem *self, GAsyncReadyCallback callback, @@ -599,8 +607,6 @@ void mm_iface_modem_bind_simple_status (MMIfaceModem *self, /* Check if the SIM or eSIM profile has changed */ void mm_iface_modem_check_for_sim_swap (MMIfaceModem *self, - const gchar *iccid, - const gchar *imsi, GAsyncReadyCallback callback, gpointer user_data); gboolean mm_iface_modem_check_for_sim_swap_finish (MMIfaceModem *self, @@ -613,5 +619,4 @@ void mm_iface_modem_modify_sim (MMIfaceModem *self, void mm_iface_modem_process_sim_event (MMIfaceModem *self); - #endif /* MM_IFACE_MODEM_H */ diff --git a/src/mm-shared-qmi.c b/src/mm-shared-qmi.c index 44c1a311..71d66280 100644 --- a/src/mm-shared-qmi.c +++ b/src/mm-shared-qmi.c @@ -3649,7 +3649,7 @@ uim_start_refresh_timeout (MMSharedQmi *self) mm_obj_dbg (self, "refresh start timed out; trigger SIM change check"); - mm_iface_modem_check_for_sim_swap (MM_IFACE_MODEM (self), NULL, NULL, NULL, NULL); + mm_iface_modem_check_for_sim_swap (MM_IFACE_MODEM (self), NULL, NULL); return G_SOURCE_REMOVE; } @@ -3715,7 +3715,7 @@ uim_refresh_indication_cb (QmiClientUim *client, 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), NULL, NULL, NULL, NULL); + mm_iface_modem_check_for_sim_swap (MM_IFACE_MODEM (self), NULL, NULL); } } } diff --git a/src/plugins/quectel/mm-shared-quectel.c b/src/plugins/quectel/mm-shared-quectel.c index 816a5709..93153fff 100644 --- a/src/plugins/quectel/mm-shared-quectel.c +++ b/src/plugins/quectel/mm-shared-quectel.c @@ -432,8 +432,6 @@ quectel_qusim_unsolicited_handler (MMPortSerialAt *port, mm_obj_dbg (self, "checking SIM swap"); MM_IFACE_MODEM_GET_INTERFACE (self)->check_for_sim_swap ( self, - NULL, - NULL, (GAsyncReadyCallback)quectel_qusim_check_for_sim_swap_ready, NULL); } |