diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/mm-broadband-modem.c | 14 | ||||
-rw-r--r-- | src/mm-iface-modem.c | 94 | ||||
-rw-r--r-- | src/mm-iface-modem.h | 11 | ||||
-rw-r--r-- | src/mm-private-boxed-types.c | 29 | ||||
-rw-r--r-- | src/mm-private-boxed-types.h | 3 |
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; |