diff options
-rw-r--r-- | docs/reference/libmm-glib/libmm-glib-sections.txt | 14 | ||||
-rw-r--r-- | introspection/org.freedesktop.ModemManager1.Sim.xml | 15 | ||||
-rw-r--r-- | libmm-glib/mm-sim-preferred-network.c | 50 | ||||
-rw-r--r-- | libmm-glib/mm-sim-preferred-network.h | 18 | ||||
-rw-r--r-- | libmm-glib/mm-sim.c | 118 | ||||
-rw-r--r-- | libmm-glib/mm-sim.h | 13 | ||||
-rw-r--r-- | src/mm-base-sim.c | 102 | ||||
-rw-r--r-- | src/mm-base-sim.h | 9 |
8 files changed, 313 insertions, 26 deletions
diff --git a/docs/reference/libmm-glib/libmm-glib-sections.txt b/docs/reference/libmm-glib/libmm-glib-sections.txt index c1daf23a..a077be65 100644 --- a/docs/reference/libmm-glib/libmm-glib-sections.txt +++ b/docs/reference/libmm-glib/libmm-glib-sections.txt @@ -1218,16 +1218,17 @@ mm_bearer_properties_get_type <FILE>mm-sim-preferred-network</FILE> <TITLE>MMSimPreferredNetwork</TITLE> MMSimPreferredNetwork +mm_sim_preferred_network_new mm_sim_preferred_network_get_operator_code +mm_sim_preferred_network_set_operator_code mm_sim_preferred_network_get_access_technology +mm_sim_preferred_network_set_access_technology mm_sim_preferred_network_free <SUBSECTION Private> -mm_sim_preferred_network_new mm_sim_preferred_network_new_from_variant -mm_sim_preferred_network_set_access_technology -mm_sim_preferred_network_set_operator_code mm_sim_preferred_network_get_tuple mm_sim_preferred_network_list_get_variant +mm_sim_preferred_network_list_new_from_variant <SUBSECTION Standard> MM_TYPE_SIM_PREFERRED_NETWORK mm_sim_preferred_network_get_type @@ -1270,6 +1271,9 @@ mm_sim_disable_pin_sync mm_sim_change_pin mm_sim_change_pin_finish mm_sim_change_pin_sync +mm_sim_set_preferred_networks +mm_sim_set_preferred_networks_finish +mm_sim_set_preferred_networks_sync <SUBSECTION Standard> MMSimClass MM_IS_SIM @@ -3160,6 +3164,9 @@ mm_gdbus_sim_call_enable_pin_sync mm_gdbus_sim_call_change_pin mm_gdbus_sim_call_change_pin_finish mm_gdbus_sim_call_change_pin_sync +mm_gdbus_sim_call_set_preferred_networks +mm_gdbus_sim_call_set_preferred_networks_finish +mm_gdbus_sim_call_set_preferred_networks_sync <SUBSECTION Private> mm_gdbus_sim_set_active mm_gdbus_sim_set_imsi @@ -3173,6 +3180,7 @@ mm_gdbus_sim_complete_change_pin mm_gdbus_sim_complete_enable_pin mm_gdbus_sim_complete_send_pin mm_gdbus_sim_complete_send_puk +mm_gdbus_sim_complete_set_preferred_networks mm_gdbus_sim_interface_info mm_gdbus_sim_override_properties <SUBSECTION Standard> diff --git a/introspection/org.freedesktop.ModemManager1.Sim.xml b/introspection/org.freedesktop.ModemManager1.Sim.xml index 63d0e9b7..13a385a7 100644 --- a/introspection/org.freedesktop.ModemManager1.Sim.xml +++ b/introspection/org.freedesktop.ModemManager1.Sim.xml @@ -66,6 +66,21 @@ </method> <!-- + SetPreferredNetworks: + @preferred_plmns: List of preferred networks. + + Stores the provided preferred network list to the SIM card. Each entry contains + an operator id string (<literal>"MCCMNC"</literal>) consisting of 5 or 6 digits, + and an <link linkend="MMModemAccessTechnology">MMModemAccessTechnology</link> mask + to store to SIM card if supported. + + This method removes any pre-existing entries of the preferred network list. + --> + <method name="SetPreferredNetworks"> + <arg name="preferred_networks" type="a(su)" direction="in" /> + </method> + + <!-- Active: Boolean indicating whether the SIM is currently active. diff --git a/libmm-glib/mm-sim-preferred-network.c b/libmm-glib/mm-sim-preferred-network.c index c53239dd..8c56810e 100644 --- a/libmm-glib/mm-sim-preferred-network.c +++ b/libmm-glib/mm-sim-preferred-network.c @@ -89,7 +89,13 @@ mm_sim_preferred_network_get_access_technology (const MMSimPreferredNetwork *sel } /** - * mm_sim_preferred_network_set_operator_code: (skip) + * mm_sim_preferred_network_set_operator_code: + * @self: A #MMSimPreferredNetwork. + * @operator_code: Operator code + * + * Set the operator code (MCCMNC) of this preferred network. + * + * Since: 1.18 */ void mm_sim_preferred_network_set_operator_code (MMSimPreferredNetwork *self, @@ -102,7 +108,13 @@ mm_sim_preferred_network_set_operator_code (MMSimPreferredNetwork *self, } /** - * mm_sim_preferred_network_set_access_technology: (skip) + * mm_sim_preferred_network_set_access_technology: + * @self: A #MMSimPreferredNetwork. + * @access_technology: A #MMModemAccessTechnology mask. + * + * Set the desired access technologies of this preferred network entry. + * + * Since: 1.18 */ void mm_sim_preferred_network_set_access_technology (MMSimPreferredNetwork *self, @@ -114,7 +126,14 @@ mm_sim_preferred_network_set_access_technology (MMSimPreferredNetwork *self, } /** - * mm_sim_preferred_network_new: (skip) + * mm_sim_preferred_network_new: + * + * Creates a new empty #MMSimPreferredNetwork. + * + * Returns: (transfer full): a #MMSimPreferredNetwork. The returned value should be freed + * with mm_sim_preferred_network_free(). + * + * Since: 1.18 */ MMSimPreferredNetwork * mm_sim_preferred_network_new (void) @@ -165,3 +184,28 @@ mm_sim_preferred_network_list_get_variant (const GList *preferred_network_list) } return g_variant_builder_end (&builder); } + +/** + * mm_sim_preferred_network_list_new_from_variant: (skip) + */ +GList * +mm_sim_preferred_network_list_new_from_variant (GVariant *variant) +{ + GList *network_list = NULL; + GVariant *child; + GVariantIter iter; + + g_return_val_if_fail (g_variant_is_of_type (variant, G_VARIANT_TYPE ("a(su)")), NULL); + + g_variant_iter_init (&iter, variant); + while ((child = g_variant_iter_next_value (&iter))) { + MMSimPreferredNetwork *preferred_net; + + preferred_net = mm_sim_preferred_network_new_from_variant (child); + if (preferred_net) + network_list = g_list_append (network_list, preferred_net); + g_variant_unref (child); + } + + return network_list; +} diff --git a/libmm-glib/mm-sim-preferred-network.h b/libmm-glib/mm-sim-preferred-network.h index e6042587..1c7deeab 100644 --- a/libmm-glib/mm-sim-preferred-network.h +++ b/libmm-glib/mm-sim-preferred-network.h @@ -36,9 +36,16 @@ typedef struct _MMSimPreferredNetwork MMSimPreferredNetwork; #define MM_TYPE_SIM_PREFERRED_NETWORK (mm_sim_preferred_network_get_type ()) GType mm_sim_preferred_network_get_type (void); +MMSimPreferredNetwork * mm_sim_preferred_network_new (void); + const gchar *mm_sim_preferred_network_get_operator_code (const MMSimPreferredNetwork *self); MMModemAccessTechnology mm_sim_preferred_network_get_access_technology (const MMSimPreferredNetwork *self); +void mm_sim_preferred_network_set_operator_code (MMSimPreferredNetwork *self, + const gchar *operator_code); +void mm_sim_preferred_network_set_access_technology (MMSimPreferredNetwork *self, + MMModemAccessTechnology access_technology); + void mm_sim_preferred_network_free (MMSimPreferredNetwork *self); G_DEFINE_AUTOPTR_CLEANUP_FUNC (MMSimPreferredNetwork, mm_sim_preferred_network_free) @@ -50,16 +57,11 @@ G_DEFINE_AUTOPTR_CLEANUP_FUNC (MMSimPreferredNetwork, mm_sim_preferred_network_f defined (_LIBMM_INSIDE_MMCLI) || \ defined (LIBMM_GLIB_COMPILATION) -MMSimPreferredNetwork * mm_sim_preferred_network_new (void); MMSimPreferredNetwork * mm_sim_preferred_network_new_from_variant (GVariant *variant); -void mm_sim_preferred_network_set_operator_code (MMSimPreferredNetwork *self, - const gchar *operator_code); -void mm_sim_preferred_network_set_access_technology (MMSimPreferredNetwork *self, - MMModemAccessTechnology access_technology); - -GVariant *mm_sim_preferred_network_get_tuple (const MMSimPreferredNetwork *self); -GVariant *mm_sim_preferred_network_list_get_variant (const GList *preferred_network_list); +GVariant *mm_sim_preferred_network_get_tuple (const MMSimPreferredNetwork *self); +GVariant *mm_sim_preferred_network_list_get_variant (const GList *preferred_network_list); +GList *mm_sim_preferred_network_list_new_from_variant (GVariant *variant); #endif diff --git a/libmm-glib/mm-sim.c b/libmm-glib/mm-sim.c index ac509d3e..17722d22 100644 --- a/libmm-glib/mm-sim.c +++ b/libmm-glib/mm-sim.c @@ -879,25 +879,119 @@ GList * mm_sim_get_preferred_networks (MMSim *self) { GList *network_list = NULL; - GVariant *container, *child; - GVariantIter iter; + GVariant *container; g_return_val_if_fail (MM_IS_SIM (self), NULL); container = mm_gdbus_sim_get_preferred_networks (MM_GDBUS_SIM (self)); - g_return_val_if_fail (g_variant_is_of_type (container, G_VARIANT_TYPE ("a(su)")), NULL); + network_list = mm_sim_preferred_network_list_new_from_variant (container); - g_variant_iter_init (&iter, container); - while ((child = g_variant_iter_next_value (&iter))) { - MMSimPreferredNetwork *preferred_net; + return network_list; +} - preferred_net = mm_sim_preferred_network_new_from_variant (child); - if (preferred_net) - network_list = g_list_append (network_list, preferred_net); - g_variant_unref (child); - } +/** + * mm_sim_set_preferred_networks_finish: + * @self: A #MMSim. + * @res: The #GAsyncResult obtained from the #GAsyncReadyCallback passed to + * mm_sim_set_preferred_networks(). + * @error: Return location for error or %NULL. + * + * Finishes an operation started with mm_sim_set_preferred_networks(). + * + * Returns: %TRUE if the operation was successful, %FALSE if @error is set. + * + * Since: 1.18 + */ +gboolean +mm_sim_set_preferred_networks_finish (MMSim *self, + GAsyncResult *res, + GError **error) +{ + g_return_val_if_fail (MM_IS_SIM (self), FALSE); - return network_list; + return mm_gdbus_sim_call_set_preferred_networks_finish (MM_GDBUS_SIM (self), res, error); +} + +/** + * mm_sim_set_preferred_networks: + * @self: A #MMSim. + * @preferred_networks: (element-type ModemManager.SimPreferredNetwork): + * A list of #MMSimPreferredNetwork objects + * @cancellable: (allow-none): A #GCancellable or %NULL. + * @callback: A #GAsyncReadyCallback to call when the request is satisfied or + * %NULL. + * @user_data: User data to pass to @callback. + * + * Asynchronously sets the preferred network list of this #MMSim. + * + * When the operation is finished, @callback will be invoked in the + * <link linkend="g-main-context-push-thread-default">thread-default main loop</link> + * of the thread you are calling this method from. You can then call + * mm_sim_set_preferred_networks_finish() to get the result of + * the operation. + * + * Since: 1.18 + */ +void +mm_sim_set_preferred_networks (MMSim *self, + const GList *preferred_networks, + GCancellable *cancellable, + GAsyncReadyCallback callback, + gpointer user_data) +{ + GVariant *networks_list; + + g_return_if_fail (MM_IS_SIM (self)); + + networks_list = mm_sim_preferred_network_list_get_variant (preferred_networks); + + mm_gdbus_sim_call_set_preferred_networks (MM_GDBUS_SIM (self), + networks_list, + cancellable, + callback, + user_data); +} + +/** + * mm_sim_set_preferred_networks_sync: + * @self: A #MMSim. + * @preferred_networks: (element-type ModemManager.SimPreferredNetwork): + * A list of #MMSimPreferredNetwork objects + * @cancellable: (allow-none): A #GCancellable or %NULL. + * @error: Return location for error or %NULL. + * + * Synchronously sets the preferred network list of this #MMSim. + * + * The calling thread is blocked until a reply is received. See + * mm_sim_set_preferred_networks() for the asynchronous + * version of this method. + * + * When the operation is finished, @callback will be invoked in the + * <link linkend="g-main-context-push-thread-default">thread-default main loop</link> + * of the thread you are calling this method from. You can then call + * mm_sim_set_preferred_networks_finish() to get the result of + * the operation. + * + * Since: 1.18 + */ +gboolean +mm_sim_set_preferred_networks_sync (MMSim *self, + const GList *preferred_networks, + GCancellable *cancellable, + GError **error) +{ + gboolean result; + GVariant *networks_list; + + g_return_if_fail (MM_IS_SIM (self)); + + networks_list = mm_sim_preferred_network_list_get_variant (preferred_networks); + + result = mm_gdbus_sim_call_set_preferred_networks_sync (MM_GDBUS_SIM (self), + networks_list, + cancellable, + error); + return result; } /*****************************************************************************/ diff --git a/libmm-glib/mm-sim.h b/libmm-glib/mm-sim.h index 8ebf069f..d64b46c9 100644 --- a/libmm-glib/mm-sim.h +++ b/libmm-glib/mm-sim.h @@ -159,6 +159,19 @@ gboolean mm_sim_change_pin_sync (MMSim *self, GCancellable *cancellable, GError **error); +void mm_sim_set_preferred_networks (MMSim *self, + const GList *preferred_networks, + GCancellable *cancellable, + GAsyncReadyCallback callback, + gpointer user_data); +gboolean mm_sim_set_preferred_networks_finish (MMSim *self, + GAsyncResult *res, + GError **error); +gboolean mm_sim_set_preferred_networks_sync (MMSim *self, + const GList *preferred_networks, + GCancellable *cancellable, + GError **error); + G_END_DECLS #endif /* _MM_SIM_H_ */ diff --git a/src/mm-base-sim.c b/src/mm-base-sim.c index 2407e400..0a96df2d 100644 --- a/src/mm-base-sim.c +++ b/src/mm-base-sim.c @@ -965,6 +965,104 @@ handle_send_puk (MMBaseSim *self, } /*****************************************************************************/ +/* SET PREFERRED NETWORKS (DBus call handling) */ + +typedef struct { + MMBaseSim *self; + GDBusMethodInvocation *invocation; + GVariant *networks; +} HandleSetPreferredNetworksContext; + +static void +handle_set_preferred_networks_context_free (HandleSetPreferredNetworksContext *ctx) +{ + g_object_unref (ctx->invocation); + g_object_unref (ctx->self); + g_variant_unref (ctx->networks); + g_free (ctx); +} + +static void +handle_set_preferred_networks_ready (MMBaseSim *self, + GAsyncResult *res, + HandleSetPreferredNetworksContext *ctx) +{ + GError *error = NULL; + + MM_BASE_SIM_GET_CLASS (self)->set_preferred_networks_finish (self, res, &error); + if (error) { + mm_obj_warn (self, "couldn't set preferred networks: %s", error->message); + g_dbus_method_invocation_take_error (ctx->invocation, g_steal_pointer (&error)); + } else { + mm_gdbus_sim_set_preferred_networks (MM_GDBUS_SIM (self), ctx->networks); + mm_gdbus_sim_complete_set_preferred_networks (MM_GDBUS_SIM (self), ctx->invocation); + } + + handle_set_preferred_networks_context_free (ctx); +} + +static void +handle_set_preferred_networks_auth_ready (MMBaseModem *modem, + GAsyncResult *res, + HandleSetPreferredNetworksContext *ctx) +{ + GError *error = NULL; + + if (!mm_base_modem_authorize_finish (modem, res, &error)) { + g_dbus_method_invocation_take_error (ctx->invocation, error); + handle_set_preferred_networks_context_free (ctx); + return; + } + + if (!mm_gdbus_sim_get_active (MM_GDBUS_SIM (ctx->self))) { + g_dbus_method_invocation_return_error (ctx->invocation, + MM_CORE_ERROR, + MM_CORE_ERROR_UNSUPPORTED, + "Cannot set preferred networks: " + "SIM not currently active"); + handle_set_preferred_networks_context_free (ctx); + return; + } + + if (!MM_BASE_SIM_GET_CLASS (ctx->self)->set_preferred_networks || + !MM_BASE_SIM_GET_CLASS (ctx->self)->set_preferred_networks_finish) { + g_dbus_method_invocation_return_error (ctx->invocation, + MM_CORE_ERROR, + MM_CORE_ERROR_UNSUPPORTED, + "Cannot set preferred networks: " + "not implemented"); + handle_set_preferred_networks_context_free (ctx); + return; + } + + MM_BASE_SIM_GET_CLASS (ctx->self)->set_preferred_networks ( + ctx->self, + mm_sim_preferred_network_list_new_from_variant (ctx->networks), + (GAsyncReadyCallback)handle_set_preferred_networks_ready, + ctx); +} + +static gboolean +handle_set_preferred_networks (MMBaseSim *self, + GDBusMethodInvocation *invocation, + GVariant *networks_variant) +{ + HandleSetPreferredNetworksContext *ctx; + + ctx = g_new0 (HandleSetPreferredNetworksContext, 1); + ctx->self = g_object_ref (self); + ctx->invocation = g_object_ref (invocation); + ctx->networks = g_variant_ref (networks_variant); + + mm_base_modem_authorize (self->priv->modem, + invocation, + MM_AUTHORIZATION_DEVICE_CONTROL, + (GAsyncReadyCallback)handle_set_preferred_networks_auth_ready, + ctx); + return TRUE; +} + +/*****************************************************************************/ static void sim_dbus_export (MMBaseSim *self) @@ -988,6 +1086,10 @@ sim_dbus_export (MMBaseSim *self) "handle-send-puk", G_CALLBACK (handle_send_puk), NULL); + g_signal_connect (self, + "handle-set-preferred-networks", + G_CALLBACK (handle_set_preferred_networks), + NULL); if (!g_dbus_interface_skeleton_export (G_DBUS_INTERFACE_SKELETON (self), self->priv->connection, diff --git a/src/mm-base-sim.h b/src/mm-base-sim.h index 67f2690d..6f40a979 100644 --- a/src/mm-base-sim.h +++ b/src/mm-base-sim.h @@ -158,6 +158,15 @@ struct _MMBaseSimClass { GList * (* load_preferred_networks_finish) (MMBaseSim *self, GAsyncResult *res, GError **error); + + /* Set preferred networks (async) */ + void (* set_preferred_networks) (MMBaseSim *self, + const GList *preferred_network_list, + GAsyncReadyCallback callback, + gpointer user_data); + gboolean (* set_preferred_networks_finish) (MMBaseSim *self, + GAsyncResult *res, + GError **error); }; GType mm_base_sim_get_type (void); |