aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/mm-broadband-modem.c14
-rw-r--r--src/mm-iface-modem.c94
-rw-r--r--src/mm-iface-modem.h11
-rw-r--r--src/mm-private-boxed-types.c29
-rw-r--r--src/mm-private-boxed-types.h3
5 files changed, 150 insertions, 1 deletions
diff --git a/src/mm-broadband-modem.c b/src/mm-broadband-modem.c
index aeb660c6..9b10f83e 100644
--- a/src/mm-broadband-modem.c
+++ b/src/mm-broadband-modem.c
@@ -100,6 +100,7 @@ enum {
PROP_MODEM_OMA_DBUS_SKELETON,
PROP_MODEM_FIRMWARE_DBUS_SKELETON,
PROP_MODEM_SIM,
+ PROP_MODEM_SIM_SLOTS,
PROP_MODEM_BEARER_LIST,
PROP_MODEM_STATE,
PROP_MODEM_3GPP_REGISTRATION_STATE,
@@ -153,6 +154,7 @@ struct _MMBroadbandModemPrivate {
/* Properties */
GObject *modem_dbus_skeleton;
MMBaseSim *modem_sim;
+ GPtrArray *modem_sim_slots;
MMBearerList *modem_bearer_list;
MMModemState modem_state;
gchar *carrier_config_mapping;
@@ -12007,6 +12009,10 @@ set_property (GObject *object,
g_clear_object (&self->priv->modem_sim);
self->priv->modem_sim = g_value_dup_object (value);
break;
+ case PROP_MODEM_SIM_SLOTS:
+ g_clear_pointer (&self->priv->modem_sim_slots, g_ptr_array_unref);
+ self->priv->modem_sim_slots = g_value_dup_boxed (value);
+ break;
case PROP_MODEM_BEARER_LIST:
g_clear_object (&self->priv->modem_bearer_list);
self->priv->modem_bearer_list = g_value_dup_object (value);
@@ -12147,6 +12153,9 @@ get_property (GObject *object,
case PROP_MODEM_SIM:
g_value_set_object (value, self->priv->modem_sim);
break;
+ case PROP_MODEM_SIM_SLOTS:
+ g_value_set_boxed (value, self->priv->modem_sim_slots);
+ break;
case PROP_MODEM_BEARER_LIST:
g_value_set_object (value, self->priv->modem_bearer_list);
break;
@@ -12351,6 +12360,7 @@ dispose (GObject *object)
g_clear_object (&self->priv->modem_3gpp_initial_eps_bearer);
g_clear_object (&self->priv->modem_sim);
+ g_clear_pointer (&self->priv->modem_sim_slots, g_ptr_array_unref);
g_clear_object (&self->priv->modem_bearer_list);
g_clear_object (&self->priv->modem_messaging_sms_list);
g_clear_object (&self->priv->modem_voice_call_list);
@@ -12713,6 +12723,10 @@ mm_broadband_modem_class_init (MMBroadbandModemClass *klass)
MM_IFACE_MODEM_SIM);
g_object_class_override_property (object_class,
+ PROP_MODEM_SIM_SLOTS,
+ MM_IFACE_MODEM_SIM_SLOTS);
+
+ g_object_class_override_property (object_class,
PROP_MODEM_BEARER_LIST,
MM_IFACE_MODEM_BEARER_LIST);
diff --git a/src/mm-iface-modem.c b/src/mm-iface-modem.c
index 8a4a00af..9045d290 100644
--- a/src/mm-iface-modem.c
+++ b/src/mm-iface-modem.c
@@ -13,7 +13,6 @@
* Copyright (C) 2011 Google, Inc.
*/
-
#include <ModemManager.h>
#define _LIBMM_INSIDE_MM
#include <libmm-glib.h>
@@ -26,6 +25,7 @@
#include "mm-base-modem-at.h"
#include "mm-base-sim.h"
#include "mm-bearer-list.h"
+#include "mm-private-boxed-types.h"
#include "mm-log-object.h"
#include "mm-context.h"
@@ -4016,6 +4016,7 @@ typedef enum {
INITIALIZATION_STEP_SUPPORTED_IP_FAMILIES,
INITIALIZATION_STEP_POWER_STATE,
INITIALIZATION_STEP_SIM_HOT_SWAP,
+ INITIALIZATION_STEP_SIM_SLOTS,
INITIALIZATION_STEP_UNLOCK_REQUIRED,
INITIALIZATION_STEP_SIM,
INITIALIZATION_STEP_SETUP_CARRIER_CONFIG,
@@ -4401,6 +4402,73 @@ setup_sim_hot_swap_ready (MMIfaceModem *self,
}
static void
+load_sim_slots_ready (MMIfaceModem *self,
+ GAsyncResult *res,
+ GTask *task)
+{
+ InitializationContext *ctx;
+ g_autoptr(GPtrArray) sim_slots = NULL;
+ g_autoptr(GError) error = NULL;
+ guint primary_sim_slot = 0;
+
+ ctx = g_task_get_task_data (task);
+
+ if (!MM_IFACE_MODEM_GET_INTERFACE (self)->load_sim_slots_finish (self,
+ res,
+ &sim_slots,
+ &primary_sim_slot,
+ &error))
+ mm_obj_warn (self, "couldn't query SIM slots: %s", error->message);
+
+ if (sim_slots) {
+ MMBaseSim *primary_sim = NULL;
+ GPtrArray *sim_slot_paths_array;
+ g_auto(GStrv) sim_slot_paths = NULL;
+ guint i;
+
+ g_assert (primary_sim_slot);
+ g_assert_cmpuint (primary_sim_slot, <=, sim_slots->len);
+
+ sim_slot_paths_array = g_ptr_array_new ();
+ for (i = 0; i < sim_slots->len; i++) {
+ MMBaseSim *sim;
+ const gchar *sim_path;
+
+ sim = MM_BASE_SIM (g_ptr_array_index (sim_slots, i));
+ if (!sim) {
+ g_ptr_array_add (sim_slot_paths_array, g_strdup ("/"));
+ continue;
+ }
+
+ sim_path = mm_base_sim_get_path (sim);
+ g_ptr_array_add (sim_slot_paths_array, g_strdup (sim_path));
+ }
+ g_ptr_array_add (sim_slot_paths_array, NULL);
+ sim_slot_paths = (GStrv) g_ptr_array_free (sim_slot_paths_array, FALSE);
+
+ mm_gdbus_modem_set_sim_slots (ctx->skeleton, (const gchar *const *)sim_slot_paths);
+ mm_gdbus_modem_set_primary_sim_slot (ctx->skeleton, primary_sim_slot);
+
+ /* If loading SIM slots is supported, we also expose already the primary active SIM object */
+ if (primary_sim_slot) {
+ primary_sim = g_ptr_array_index (sim_slots, primary_sim_slot - 1);
+ if (primary_sim)
+ g_object_bind_property (primary_sim, MM_BASE_SIM_PATH,
+ ctx->skeleton, "sim",
+ G_BINDING_DEFAULT | G_BINDING_SYNC_CREATE);
+ }
+ g_object_set (self,
+ MM_IFACE_MODEM_SIM, primary_sim,
+ MM_IFACE_MODEM_SIM_SLOTS, sim_slots,
+ NULL);
+ }
+
+ /* Go on to next step */
+ ctx->step++;
+ interface_initialization_step (task);
+}
+
+static void
modem_update_lock_info_ready (MMIfaceModem *self,
GAsyncResult *res,
GTask *task)
@@ -5090,6 +5158,22 @@ interface_initialization_step (GTask *task)
ctx->step++;
/* fall-through */
+ case INITIALIZATION_STEP_SIM_SLOTS:
+ /* If the modem doesn't need any SIM (not implemented by plugin, or not
+ * needed in CDMA-only modems), or if we don't know how to query
+ * for SIM slots */
+ if (!mm_gdbus_modem_get_sim_slots (ctx->skeleton) &&
+ !mm_iface_modem_is_cdma_only (self) &&
+ MM_IFACE_MODEM_GET_INTERFACE (self)->load_sim_slots &&
+ MM_IFACE_MODEM_GET_INTERFACE (self)->load_sim_slots_finish) {
+ MM_IFACE_MODEM_GET_INTERFACE (self)->load_sim_slots (MM_IFACE_MODEM (self),
+ (GAsyncReadyCallback)load_sim_slots_ready,
+ task);
+ return;
+ }
+ ctx->step++;
+ /* fall-through */
+
case INITIALIZATION_STEP_UNLOCK_REQUIRED:
/* Only check unlock required if we were previously not unlocked */
if (mm_gdbus_modem_get_unlock_required (ctx->skeleton) != MM_MODEM_LOCK_NONE) {
@@ -5686,6 +5770,14 @@ iface_modem_init (gpointer g_iface)
g_object_interface_install_property
(g_iface,
+ g_param_spec_boxed (MM_IFACE_MODEM_SIM_SLOTS,
+ "SIM slots",
+ "SIM objects in SIM slots",
+ MM_TYPE_OBJECT_ARRAY,
+ G_PARAM_READWRITE));
+
+ g_object_interface_install_property
+ (g_iface,
g_param_spec_enum (MM_IFACE_MODEM_STATE,
"State",
"State of the modem",
diff --git a/src/mm-iface-modem.h b/src/mm-iface-modem.h
index 2df3b59c..0393155d 100644
--- a/src/mm-iface-modem.h
+++ b/src/mm-iface-modem.h
@@ -35,6 +35,7 @@
#define MM_IFACE_MODEM_DBUS_SKELETON "iface-modem-dbus-skeleton"
#define MM_IFACE_MODEM_STATE "iface-modem-state"
#define MM_IFACE_MODEM_SIM "iface-modem-sim"
+#define MM_IFACE_MODEM_SIM_SLOTS "iface-modem-sim-slots"
#define MM_IFACE_MODEM_BEARER_LIST "iface-modem-bearer-list"
#define MM_IFACE_MODEM_SIM_HOT_SWAP_SUPPORTED "iface-modem-sim-hot-swap-supported"
#define MM_IFACE_MODEM_SIM_HOT_SWAP_CONFIGURED "iface-modem-sim-hot-swap-configured"
@@ -343,6 +344,16 @@ struct _MMIfaceModem {
GAsyncResult *res,
GError **error);
+ /* Create SIMs in all SIM slots */
+ void (* load_sim_slots) (MMIfaceModem *self,
+ GAsyncReadyCallback callback,
+ gpointer user_data);
+ gboolean (* load_sim_slots_finish) (MMIfaceModem *self,
+ GAsyncResult *res,
+ GPtrArray **sim_slots,
+ guint *primary_sim_slot,
+ GError **error);
+
/* Create bearer */
void (*create_bearer) (MMIfaceModem *self,
MMBearerProperties *properties,
diff --git a/src/mm-private-boxed-types.c b/src/mm-private-boxed-types.c
index 465649b5..a94dd2c4 100644
--- a/src/mm-private-boxed-types.c
+++ b/src/mm-private-boxed-types.c
@@ -171,6 +171,35 @@ mm_pointer_array_get_type (void)
return g_define_type_id__volatile;
}
+static GPtrArray *
+object_array_copy (GPtrArray *object_array)
+{
+ return g_ptr_array_ref (object_array);
+}
+
+static void
+object_array_free (GPtrArray *object_array)
+{
+ g_ptr_array_unref (object_array);
+}
+
+GType
+mm_object_array_get_type (void)
+{
+ static volatile gsize g_define_type_id__volatile = 0;
+
+ if (g_once_init_enter (&g_define_type_id__volatile)) {
+ GType g_define_type_id =
+ g_boxed_type_register_static (g_intern_static_string ("MMObjectArray"),
+ (GBoxedCopyFunc) object_array_copy,
+ (GBoxedFreeFunc) object_array_free);
+
+ g_once_init_leave (&g_define_type_id__volatile, g_define_type_id);
+ }
+
+ return g_define_type_id__volatile;
+}
+
static void
async_method_free (MMAsyncMethod *method)
{
diff --git a/src/mm-private-boxed-types.h b/src/mm-private-boxed-types.h
index fcdcbb10..8a7d5fcb 100644
--- a/src/mm-private-boxed-types.h
+++ b/src/mm-private-boxed-types.h
@@ -34,6 +34,9 @@ GType mm_str_pair_array_get_type (void) G_GNUC_CONST;
GType mm_pointer_array_get_type (void) G_GNUC_CONST;
#define MM_TYPE_POINTER_ARRAY (mm_pointer_array_get_type ())
+GType mm_object_array_get_type (void) G_GNUC_CONST;
+#define MM_TYPE_OBJECT_ARRAY (mm_object_array_get_type ())
+
typedef struct {
GCallback async;
GCallback finish;