api,sim: add new Sim.SetPreferredNetworks method

This commit includes D-Bus processing and documentation, but not any
modem access implementation.
This commit is contained in:
Teijo Kinnunen
2021-03-03 16:23:09 +02:00
parent 72d753ba83
commit 66e93751b8
8 changed files with 314 additions and 27 deletions

View File

@@ -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>

View File

@@ -65,6 +65,21 @@
<arg name="new_pin" type="s" direction="in" />
</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:

View File

@@ -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;
}

View File

@@ -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);
GList *mm_sim_preferred_network_list_new_from_variant (GVariant *variant);
#endif

View File

@@ -879,27 +879,121 @@ 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);
g_variant_iter_init (&iter, container);
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);
}
network_list = mm_sim_preferred_network_list_new_from_variant (container);
return network_list;
}
/**
* 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 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;
}
/*****************************************************************************/
static void

View File

@@ -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_ */

View File

@@ -964,6 +964,104 @@ handle_send_puk (MMBaseSim *self,
return TRUE;
}
/*****************************************************************************/
/* 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
@@ -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,

View File

@@ -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);