aboutsummaryrefslogtreecommitdiff
path: root/plugins/quectel/mm-shared-quectel.c
diff options
context:
space:
mode:
authorTeijo Kinnunen <teijo.kinnunen@uros.com>2020-09-28 09:29:09 +0000
committerAleksander Morgado <aleksander@aleksander.es>2020-09-28 09:29:09 +0000
commite91f2ef315526a1a8a1b451acb5a190686b05225 (patch)
tree171bb5a752e02d6facca6f5c79e43c4771ae6f2b /plugins/quectel/mm-shared-quectel.c
parent318b2b01e340936e3f3b8d443f89acc432b85190 (diff)
shared-qmi: implement SIM/profile change detection
Implement eUICC change detection for QMI based modems using one of the following mechanisms (in order of preference): 1. If the modem supports "get slot status" operation, we monitor physical slot status indications from the modem for the active slot to detect when ICCID changes. 2. Use "refresh register all" to subscribe refresh indications when the eUICC triggers REFRESH operation following the enablement of a new profile. 3. Use "refresh register" to subscribe refresh indications (file path of EF_ICCID is used) in a similar way. This is used with older modems that do not support "refresh register all". If ICCID change is detected, the already existing SIM hot swap mechanism in MM is triggered.
Diffstat (limited to 'plugins/quectel/mm-shared-quectel.c')
-rw-r--r--plugins/quectel/mm-shared-quectel.c40
1 files changed, 38 insertions, 2 deletions
diff --git a/plugins/quectel/mm-shared-quectel.c b/plugins/quectel/mm-shared-quectel.c
index 4d8423ae..0274fbe1 100644
--- a/plugins/quectel/mm-shared-quectel.c
+++ b/plugins/quectel/mm-shared-quectel.c
@@ -43,6 +43,7 @@ typedef enum {
} FeatureSupport;
typedef struct {
+ MMIfaceModem *iface_modem_parent;
MMIfaceModemLocation *iface_modem_location_parent;
MMModemLocationSource provided_sources;
MMModemLocationSource enabled_sources;
@@ -65,8 +66,11 @@ get_private (MMSharedQuectel *self)
priv->enabled_sources = MM_MODEM_LOCATION_SOURCE_NONE;
priv->qgps_supported = FEATURE_SUPPORT_UNKNOWN;
- g_assert (MM_SHARED_QUECTEL_GET_INTERFACE (self)->peek_parent_location_interface);
- priv->iface_modem_location_parent = MM_SHARED_QUECTEL_GET_INTERFACE (self)->peek_parent_location_interface (self);
+ g_assert (MM_SHARED_QUECTEL_GET_INTERFACE (self)->peek_parent_modem_location_interface);
+ priv->iface_modem_location_parent = MM_SHARED_QUECTEL_GET_INTERFACE (self)->peek_parent_modem_location_interface (self);
+
+ g_assert (MM_SHARED_QUECTEL_GET_INTERFACE (self)->peek_parent_modem_interface);
+ priv->iface_modem_parent = MM_SHARED_QUECTEL_GET_INTERFACE (self)->peek_parent_modem_interface (self);
g_object_set_qdata (G_OBJECT (self), private_quark, priv);
}
@@ -170,16 +174,37 @@ mm_shared_quectel_setup_sim_hot_swap_finish (MMIfaceModem *self,
return g_task_propagate_boolean (G_TASK (res), error);
}
+static void
+parent_setup_sim_hot_swap_ready (MMIfaceModem *self,
+ GAsyncResult *res,
+ GTask *task)
+{
+ Private *priv;
+ g_autoptr(GError) error = NULL;
+
+ priv = get_private (MM_SHARED_QUECTEL (self));
+
+ if (!priv->iface_modem_parent->setup_sim_hot_swap_finish (self, res, &error))
+ mm_obj_dbg (self, "additional SIM hot swap detection setup failed: %s", error->message);
+
+ /* The +QUSIM based setup never fails, so we can safely return success here */
+ g_task_return_boolean (task, TRUE);
+ g_object_unref (task);
+}
+
void
mm_shared_quectel_setup_sim_hot_swap (MMIfaceModem *self,
GAsyncReadyCallback callback,
gpointer user_data)
{
+ Private *priv;
MMPortSerialAt *ports[2];
GTask *task;
GRegex *pattern;
guint i;
+ priv = get_private (MM_SHARED_QUECTEL (self));
+
task = g_task_new (self, NULL, callback, user_data);
ports[0] = mm_base_modem_peek_port_primary (MM_BASE_MODEM (self));
@@ -200,6 +225,17 @@ mm_shared_quectel_setup_sim_hot_swap (MMIfaceModem *self,
g_regex_unref (pattern);
mm_obj_dbg (self, "+QUSIM detection set up");
+
+ /* Now, if available, setup parent logic */
+ if (priv->iface_modem_parent->setup_sim_hot_swap &&
+ priv->iface_modem_parent->setup_sim_hot_swap_finish) {
+ priv->iface_modem_parent->setup_sim_hot_swap (self,
+ (GAsyncReadyCallback) parent_setup_sim_hot_swap_ready,
+ task);
+ return;
+ }
+
+ /* Otherwise, we're done */
g_task_return_boolean (task, TRUE);
g_object_unref (task);
}