aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/mm-broadband-modem-mbim.c133
-rw-r--r--src/mm-broadband-modem.c16
-rw-r--r--src/mm-iface-modem.c92
-rw-r--r--src/mm-iface-modem.h15
-rw-r--r--src/mm-shared-qmi.c4
-rw-r--r--src/plugins/quectel/mm-shared-quectel.c2
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, &current_iccid, &current_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);
}