aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorZhangMingjie <superzmj@fibocom.com>2021-06-25 12:05:52 +0800
committerAleksander Morgado <aleksander@aleksander.es>2021-07-14 15:14:18 +0200
commitb151740d1598ab456d5bd2293babefe1cc2964f6 (patch)
tree7217617ea7dd43585945b5e7cb5aeda39d6ac1c5 /src
parent9d31113edb8125db0d01a36d024c089f0ce98aa1 (diff)
mm-broadband-modem-mbim: implement the load_sim_slots() method for DSSA
Diffstat (limited to 'src')
-rwxr-xr-x[-rw-r--r--]src/mm-broadband-modem-mbim.c352
-rw-r--r--src/mm-broadband-modem-mbim.h1
-rwxr-xr-x[-rw-r--r--]src/mm-sim-mbim.c28
-rwxr-xr-x[-rw-r--r--]src/mm-sim-mbim.h10
4 files changed, 387 insertions, 4 deletions
diff --git a/src/mm-broadband-modem-mbim.c b/src/mm-broadband-modem-mbim.c
index 5c7e28d7..848b0346 100644..100755
--- a/src/mm-broadband-modem-mbim.c
+++ b/src/mm-broadband-modem-mbim.c
@@ -149,6 +149,9 @@ struct _MMBroadbandModemMbimPrivate {
#endif
gboolean intel_firmware_update_unsupported;
+
+ /* Multi-SIM support */
+ guint32 executor_index;
};
/*****************************************************************************/
@@ -6158,6 +6161,351 @@ get_property (GObject *object,
}
}
+/*****************************************************************************/
+/* Create SIMs in all SIM slots */
+
+typedef struct {
+ GPtrArray *sim_slots;
+ guint number_slots;
+ guint query_slot_index;
+ guint active_slot_index;
+} LoadSimSlotsContext;
+
+static void
+load_sim_slots_context_free (LoadSimSlotsContext *ctx)
+{
+ g_clear_pointer (&ctx->sim_slots, g_ptr_array_unref);
+ g_slice_free (LoadSimSlotsContext, ctx);
+}
+
+static gboolean
+load_sim_slots_finish (MMIfaceModem *self,
+ GAsyncResult *res,
+ GPtrArray **sim_slots,
+ guint *primary_sim_slot,
+ GError **error)
+{
+ LoadSimSlotsContext *ctx;
+
+ if (!g_task_propagate_boolean (G_TASK(res), error))
+ return FALSE;
+
+ ctx = g_task_get_task_data (G_TASK (res));
+
+ if (sim_slots)
+ *sim_slots = g_steal_pointer (&ctx->sim_slots);
+ if (primary_sim_slot)
+ *primary_sim_slot = ctx->active_slot_index;
+ return TRUE;
+}
+
+static void
+query_slot_information_status (MbimDevice *device,
+ guint slot_index,
+ GTask *task);
+
+static void
+query_slot_information_status_ready (MbimDevice *device,
+ GAsyncResult *res,
+ GTask *task)
+{
+ MMIfaceModem *self;
+ g_autoptr(MbimMessage) response = NULL;
+ GError *error = NULL;
+ guint32 slot_index;
+ MbimUiccSlotState slot_state;
+ LoadSimSlotsContext *ctx;
+ MMBaseSim *sim;
+ gboolean sim_active = FALSE;
+
+ self = g_task_get_source_object (task);
+ ctx = g_task_get_task_data (task);
+
+ response = mbim_device_command_finish (device, res, &error);
+ if (!response ||
+ !mbim_message_response_get_result (response, MBIM_MESSAGE_TYPE_COMMAND_DONE, &error) ||
+ !mbim_message_ms_basic_connect_extensions_slot_info_status_response_parse (
+ response,
+ &slot_index,
+ &slot_state,
+ &error)) {
+ g_task_return_error (task, error);
+ g_object_unref (task);
+ return;
+ }
+
+ if (slot_index == ctx->active_slot_index) {
+ sim_active = TRUE;
+ }
+
+ if (slot_state == MBIM_UICC_SLOT_STATE_ACTIVE ||
+ slot_state == MBIM_UICC_SLOT_STATE_ACTIVE_ESIM ||
+ slot_state == MBIM_UICC_SLOT_STATE_ACTIVE_ESIM_NO_PROFILES) {
+ sim = mm_sim_mbim_new_initialized (MM_BASE_MODEM (self),
+ slot_index,
+ sim_active,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL);
+ g_ptr_array_add (ctx->sim_slots, sim);
+ } else
+ g_ptr_array_add (ctx->sim_slots, NULL);
+
+ ctx->query_slot_index++;
+ if (ctx->query_slot_index < ctx->number_slots) {
+ query_slot_information_status (device, ctx->query_slot_index, task);
+ return;
+ }
+
+ g_task_return_boolean (task, TRUE);
+ g_object_unref (task);
+}
+
+static void
+query_slot_information_status (MbimDevice *device,
+ guint slot_index,
+ GTask *task)
+{
+ g_autoptr(MbimMessage) message = NULL;
+
+ message = mbim_message_ms_basic_connect_extensions_slot_info_status_query_new (slot_index, NULL);
+ mbim_device_command (device,
+ message,
+ 10,
+ NULL,
+ (GAsyncReadyCallback)query_slot_information_status_ready,
+ task);
+}
+
+static void
+query_device_slot_mappings_ready (MbimDevice *device,
+ GAsyncResult *res,
+ GTask *task)
+{
+ MMBroadbandModemMbim *self;
+ g_autoptr(MbimMessage) response = NULL;
+ GError *error = NULL;
+ g_autoptr(MbimMessage) message = NULL;
+ guint32 map_count = 0;
+ g_autoptr(MbimSlotArray) slot_mappings = NULL;
+ LoadSimSlotsContext *ctx;
+
+ ctx = g_task_get_task_data (task);
+ 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) ||
+ !mbim_message_ms_basic_connect_extensions_device_slot_mappings_response_parse (
+ response,
+ &map_count,
+ &slot_mappings,
+ &error)) {
+ g_task_return_error (task, error);
+ g_object_unref (task);
+ return;
+ }
+
+ if (self->priv->executor_index >= map_count) {
+ g_task_return_new_error (task, MM_CORE_ERROR, MM_CORE_ERROR_NOT_FOUND,
+ "The executor index doesn't have an entry in the map count");
+ g_object_unref (task);
+ return;
+ }
+ ctx->active_slot_index = slot_mappings[self->priv->executor_index]->slot;
+
+ query_slot_information_status (device, ctx->query_slot_index, task);
+}
+
+static void
+query_device_slot_mappings (MbimDevice *device,
+ GTask *task)
+{
+ g_autoptr(MbimMessage) message = NULL;
+
+ message = mbim_message_ms_basic_connect_extensions_device_slot_mappings_query_new (NULL);
+ mbim_device_command (device,
+ message,
+ 10,
+ NULL,
+ (GAsyncReadyCallback)query_device_slot_mappings_ready,
+ task);
+}
+
+static void
+query_device_caps_ready (MbimDevice *device,
+ GAsyncResult *res,
+ GTask *task)
+{
+ MMBroadbandModemMbim *self;
+ g_autoptr(MbimMessage) response = NULL;
+ GError *error = NULL;
+ g_autoptr(MbimMessage) message = NULL;
+ guint32 executor_index;
+
+ 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) ||
+ !mbim_message_ms_basic_connect_extensions_device_caps_response_parse (
+ response,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ &executor_index,
+ &error)) {
+ g_task_return_error (task, error);
+ g_object_unref (task);
+ return;
+ }
+
+ self->priv->executor_index = executor_index;
+
+ query_device_slot_mappings (device, task);
+}
+
+static void
+query_sys_caps_ready (MbimDevice *device,
+ GAsyncResult *res,
+ GTask *task)
+{
+ MMBroadbandModemMbim *self;
+ g_autoptr(MbimMessage) response = NULL;
+ g_autoptr(MbimMessage) message = NULL;
+ GError *error = NULL;
+ guint32 number_executors;
+ guint32 number_slots;
+ guint32 concurrency;
+ guint64 modem_id;
+ LoadSimSlotsContext *ctx;
+
+ ctx = g_task_get_task_data (task);
+ 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) ||
+ !mbim_message_ms_basic_connect_extensions_sys_caps_response_parse (
+ response,
+ &number_executors,
+ &number_slots,
+ &concurrency,
+ &modem_id,
+ &error)) {
+ g_task_return_error (task, error);
+ g_object_unref (task);
+ return;
+ }
+
+ if (number_slots == 1) {
+ g_task_return_new_error (task, MM_CORE_ERROR, MM_CORE_ERROR_NOT_FOUND,
+ "Only one SIM slot is supported");
+ g_object_unref (task);
+ return;
+ }
+ ctx->number_slots = number_slots;
+ ctx->sim_slots = g_ptr_array_new_full (number_slots, NULL);
+
+ if (number_executors == 0) {
+ g_task_return_new_error (task, MM_CORE_ERROR, MM_CORE_ERROR_NOT_FOUND,
+ "There is no executor");
+ g_object_unref (task);
+ return;
+ }
+ /* Given that there is one single executor supported,we assume the executor index to be always 0 */
+ if (number_executors == 1) {
+ self->priv->executor_index = 0;
+ query_device_slot_mappings (device, task);
+ return;
+ }
+ /* Given that more than one executors supported,we first query the current device caps to know which is the current executor index */
+ message = mbim_message_ms_basic_connect_extensions_device_caps_query_new (NULL);
+ mbim_device_command (device,
+ message,
+ 10,
+ NULL,
+ (GAsyncReadyCallback)query_device_caps_ready,
+ task);
+}
+
+static void
+load_sim_slots_mbim (GTask *task)
+{
+ MMBroadbandModemMbim *self;
+ MbimDevice *device;
+ MbimMessage *message;
+
+ self = g_task_get_source_object (task);
+
+ if (!peek_device (self, &device, NULL, NULL))
+ return;
+
+ message = mbim_message_ms_basic_connect_extensions_sys_caps_query_new (NULL);
+ mbim_device_command (device,
+ message,
+ 10,
+ NULL,
+ (GAsyncReadyCallback)query_sys_caps_ready,
+ task);
+ mbim_message_unref (message);
+}
+
+#if defined WITH_QMI && QMI_MBIM_QMUX_SUPPORTED
+static void
+shared_qmi_load_sim_slots_ready (MMIfaceModem *self,
+ GAsyncResult *res,
+ GTask *task)
+{
+ g_autoptr(GPtrArray) sim_slots = NULL;
+ guint primary_sim_slot = 0;
+ LoadSimSlotsContext *ctx;
+
+ if (!mm_shared_qmi_load_sim_slots_finish (self, res, &sim_slots, &primary_sim_slot, NULL)) {
+ load_sim_slots_mbim (task);
+ return;
+ }
+
+ ctx = g_task_get_task_data (task);
+
+ ctx->sim_slots = g_steal_pointer (&sim_slots);
+ ctx->active_slot_index = primary_sim_slot;
+
+ g_task_return_boolean (task, TRUE);
+ g_object_unref (task);
+}
+#endif
+
+static void
+load_sim_slots (MMIfaceModem *self,
+ GAsyncReadyCallback callback,
+ gpointer user_data)
+{
+ GTask *task;
+ LoadSimSlotsContext *ctx;
+
+ task = g_task_new (self, NULL, callback, user_data);
+
+ ctx = g_slice_new0 (LoadSimSlotsContext);
+ g_task_set_task_data (task, ctx, (GDestroyNotify)load_sim_slots_context_free);
+
+#if defined WITH_QMI && QMI_MBIM_QMUX_SUPPORTED
+ mm_shared_qmi_load_sim_slots (self, (GAsyncReadyCallback)shared_qmi_load_sim_slots_ready, task);
+#else
+ load_sim_slots_mbim (task);
+#endif
+}
+
MMBroadbandModemMbim *
mm_broadband_modem_mbim_new (const gchar *device,
const gchar **drivers,
@@ -6308,9 +6656,9 @@ iface_modem_init (MMIfaceModem *iface)
/* Create MBIM-specific SIM */
iface->create_sim = create_sim;
iface->create_sim_finish = create_sim_finish;
+ iface->load_sim_slots = load_sim_slots;
+ iface->load_sim_slots_finish = load_sim_slots_finish;
#if defined WITH_QMI && QMI_MBIM_QMUX_SUPPORTED
- iface->load_sim_slots = mm_shared_qmi_load_sim_slots;
- iface->load_sim_slots_finish = mm_shared_qmi_load_sim_slots_finish;
iface->set_primary_sim_slot = mm_shared_qmi_set_primary_sim_slot;
iface->set_primary_sim_slot_finish = mm_shared_qmi_set_primary_sim_slot_finish;
#endif
diff --git a/src/mm-broadband-modem-mbim.h b/src/mm-broadband-modem-mbim.h
index d2c5d7c6..529b3374 100644
--- a/src/mm-broadband-modem-mbim.h
+++ b/src/mm-broadband-modem-mbim.h
@@ -62,5 +62,4 @@ MMPortMbim *mm_broadband_modem_mbim_get_port_mbim (MMBroadbandModemMbi
MMPortMbim *mm_broadband_modem_mbim_get_port_mbim_for_data (MMBroadbandModemMbim *self,
MMPort *data,
GError **error);
-
#endif /* MM_BROADBAND_MODEM_MBIM_H */
diff --git a/src/mm-sim-mbim.c b/src/mm-sim-mbim.c
index 8be1a2e6..bc350757 100644..100755
--- a/src/mm-sim-mbim.c
+++ b/src/mm-sim-mbim.c
@@ -704,6 +704,34 @@ mm_sim_mbim_new (MMBaseModem *modem,
NULL);
}
+MMBaseSim *
+mm_sim_mbim_new_initialized (MMBaseModem *modem,
+ guint slot_number,
+ gboolean active,
+ const gchar *sim_identifier,
+ const gchar *imsi,
+ const gchar *eid,
+ const gchar *operator_identifier,
+ const gchar *operator_name,
+ const GStrv emergency_numbers)
+{
+ MMBaseSim *sim;
+
+ sim = MM_BASE_SIM (g_object_new (MM_TYPE_SIM_MBIM,
+ MM_BASE_SIM_MODEM, modem,
+ MM_BASE_SIM_SLOT_NUMBER, slot_number,
+ "active", active,
+ "sim-identifier", sim_identifier,
+ "eid", eid,
+ "operator-identifier", operator_identifier,
+ "operator-name", operator_name,
+ "emergency-numbers", emergency_numbers,
+ NULL));
+
+ mm_base_sim_export (sim);
+ return sim;
+}
+
static void
mm_sim_mbim_init (MMSimMbim *self)
{
diff --git a/src/mm-sim-mbim.h b/src/mm-sim-mbim.h
index eb6b1e2e..f6926840 100644..100755
--- a/src/mm-sim-mbim.h
+++ b/src/mm-sim-mbim.h
@@ -48,5 +48,13 @@ void mm_sim_mbim_new (MMBaseModem *modem,
gpointer user_data);
MMBaseSim *mm_sim_mbim_new_finish (GAsyncResult *res,
GError **error);
-
+MMBaseSim *mm_sim_mbim_new_initialized (MMBaseModem *modem,
+ guint slot_number,
+ gboolean active,
+ const gchar *sim_identifier,
+ const gchar *imsi,
+ const gchar *eid,
+ const gchar *operator_identifier,
+ const gchar *operator_name,
+ const GStrv emergency_numbers);
#endif /* MM_SIM_MBIM_H */