modem: Allow to set current channel list
This adds support for setting the channels to override the boot up modem defaults: ``` busctl --system call org.freedesktop.ModemManager1 /org/freedesktop/ModemManager1/Modem/0 org.freedesktop.ModemManager1.Modem.CellBroadcast SetChannels 'a(uu)' 1 0 9999 busctl --system get-property org.freedesktop.ModemManager1 /org/freedesktop/ModemManager1/Modem/0 org.freedesktop.ModemManager1.Modem.CellBroadcast Channels a(uu) 1 0 9999 ``` Closes: https://gitlab.freedesktop.org/mobile-broadband/ModemManager/-/issues/934 Signed-off-by: Guido Günther <agx@sigxcpu.org>
This commit is contained in:
committed by
Dan Williams
parent
d8135be6e2
commit
2878833f5c
@@ -87,5 +87,27 @@
|
|||||||
-->
|
-->
|
||||||
<property name="CellBroadcasts" type="ao" access="read" />
|
<property name="CellBroadcasts" type="ao" access="read" />
|
||||||
|
|
||||||
|
<!--
|
||||||
|
SetChannels:
|
||||||
|
@channels: The list of channels
|
||||||
|
|
||||||
|
Set the list of channels to receive Cell Broadcasts for.
|
||||||
|
|
||||||
|
Since: 1.24
|
||||||
|
-->
|
||||||
|
<method name="SetChannels">
|
||||||
|
<arg name="channels" type="a(uu)" direction="in" />
|
||||||
|
</method>
|
||||||
|
|
||||||
|
<!--
|
||||||
|
Channels:
|
||||||
|
|
||||||
|
The list of channels that cell broadcast messages are
|
||||||
|
received for.
|
||||||
|
|
||||||
|
Since: 1.24
|
||||||
|
-->
|
||||||
|
<property name="Channels" type="a(uu)" access="read" />
|
||||||
|
|
||||||
</interface>
|
</interface>
|
||||||
</node>
|
</node>
|
||||||
|
|||||||
@@ -10603,6 +10603,66 @@ modem_cell_broadcast_create_cbm (MMIfaceModemCellBroadcast *self)
|
|||||||
return mm_base_cbm_new (MM_BASE_MODEM (self));
|
return mm_base_cbm_new (MM_BASE_MODEM (self));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/***********************************************************************************/
|
||||||
|
/* Get channels (CellBroadcast interface) */
|
||||||
|
|
||||||
|
static gboolean
|
||||||
|
modem_cell_broadcast_set_channels_finish (MMIfaceModemCellBroadcast *self,
|
||||||
|
GAsyncResult *res,
|
||||||
|
GError **error)
|
||||||
|
{
|
||||||
|
return g_task_propagate_boolean (G_TASK (res), error);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
modem_cell_broadcast_set_channels_ready (MMBaseModem *self,
|
||||||
|
GAsyncResult *res,
|
||||||
|
GTask *task)
|
||||||
|
{
|
||||||
|
GError *error = NULL;
|
||||||
|
|
||||||
|
if (!mm_base_modem_at_command_finish (self, res, &error))
|
||||||
|
g_task_return_error (task, error);
|
||||||
|
else
|
||||||
|
g_task_return_boolean (task, TRUE);
|
||||||
|
g_object_unref (task);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
modem_cell_broadcast_set_channels (MMIfaceModemCellBroadcast *self,
|
||||||
|
GArray *channels,
|
||||||
|
GAsyncReadyCallback callback,
|
||||||
|
gpointer user_data)
|
||||||
|
{
|
||||||
|
GTask *task;
|
||||||
|
g_autoptr (GString) cmd = g_string_new ("+CSCB=0,\"");
|
||||||
|
guint i;
|
||||||
|
|
||||||
|
task = g_task_new (self, NULL, callback, user_data);
|
||||||
|
|
||||||
|
for (i = 0; i < channels->len; i++) {
|
||||||
|
MMCellBroadcastChannels ch = g_array_index (channels, MMCellBroadcastChannels, i);
|
||||||
|
|
||||||
|
if (i > 0)
|
||||||
|
g_string_append_c (cmd, ',');
|
||||||
|
|
||||||
|
if (ch.start == ch.end)
|
||||||
|
g_string_append_printf (cmd, "%u", ch.start);
|
||||||
|
else
|
||||||
|
g_string_append_printf (cmd, "%u-%u", ch.start, ch.end);
|
||||||
|
}
|
||||||
|
g_string_append (cmd, "\",\"\"");
|
||||||
|
|
||||||
|
mm_obj_dbg (self, "Setting channels...");
|
||||||
|
mm_base_modem_at_command (
|
||||||
|
MM_BASE_MODEM (self),
|
||||||
|
cmd->str,
|
||||||
|
3,
|
||||||
|
FALSE,
|
||||||
|
(GAsyncReadyCallback)modem_cell_broadcast_set_channels_ready,
|
||||||
|
task);
|
||||||
|
}
|
||||||
|
|
||||||
/*********************************************************/
|
/*********************************************************/
|
||||||
/* Check CellBroadcast support (CellBroadcast interface) */
|
/* Check CellBroadcast support (CellBroadcast interface) */
|
||||||
|
|
||||||
@@ -14344,6 +14404,8 @@ iface_modem_cell_broadcast_init (MMIfaceModemCellBroadcastInterface *iface)
|
|||||||
iface->setup_unsolicited_events_finish = modem_cell_broadcast_setup_cleanup_unsolicited_events_finish;
|
iface->setup_unsolicited_events_finish = modem_cell_broadcast_setup_cleanup_unsolicited_events_finish;
|
||||||
iface->cleanup_unsolicited_events = modem_cell_broadcast_cleanup_unsolicited_events;
|
iface->cleanup_unsolicited_events = modem_cell_broadcast_cleanup_unsolicited_events;
|
||||||
iface->cleanup_unsolicited_events_finish = modem_cell_broadcast_setup_cleanup_unsolicited_events_finish;
|
iface->cleanup_unsolicited_events_finish = modem_cell_broadcast_setup_cleanup_unsolicited_events_finish;
|
||||||
|
iface->set_channels = modem_cell_broadcast_set_channels;
|
||||||
|
iface->set_channels_finish = modem_cell_broadcast_set_channels_finish;
|
||||||
iface->create_cbm = modem_cell_broadcast_create_cbm;
|
iface->create_cbm = modem_cell_broadcast_create_cbm;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -42,6 +42,102 @@ mm_iface_modem_cell_broadcast_bind_simple_status (MMIfaceModemCellBroadcast *sel
|
|||||||
|
|
||||||
/*****************************************************************************/
|
/*****************************************************************************/
|
||||||
|
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
MmGdbusModemCellBroadcast *skeleton;
|
||||||
|
GDBusMethodInvocation *invocation;
|
||||||
|
MMIfaceModemCellBroadcast *self;
|
||||||
|
GArray *channels;
|
||||||
|
} HandleSetChannelsCellBroadcastContext;
|
||||||
|
|
||||||
|
static void
|
||||||
|
handle_set_channels_context_free (HandleSetChannelsCellBroadcastContext *ctx)
|
||||||
|
{
|
||||||
|
g_object_unref (ctx->skeleton);
|
||||||
|
g_object_unref (ctx->invocation);
|
||||||
|
g_object_unref (ctx->self);
|
||||||
|
g_array_unref (ctx->channels);
|
||||||
|
g_slice_free (HandleSetChannelsCellBroadcastContext, ctx);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
set_channels_ready (MMIfaceModemCellBroadcast *self,
|
||||||
|
GAsyncResult *res,
|
||||||
|
HandleSetChannelsCellBroadcastContext *ctx)
|
||||||
|
{
|
||||||
|
GError *error = NULL;
|
||||||
|
|
||||||
|
if (!MM_IFACE_MODEM_CELL_BROADCAST_GET_IFACE (self)->set_channels_finish (self, res, &error))
|
||||||
|
mm_dbus_method_invocation_take_error (ctx->invocation, error);
|
||||||
|
else {
|
||||||
|
mm_gdbus_modem_cell_broadcast_set_channels (ctx->skeleton,
|
||||||
|
mm_common_cell_broadcast_channels_garray_to_variant (ctx->channels));
|
||||||
|
mm_gdbus_modem_cell_broadcast_complete_set_channels (ctx->skeleton, ctx->invocation);
|
||||||
|
}
|
||||||
|
|
||||||
|
handle_set_channels_context_free (ctx);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
handle_set_channels_auth_ready (MMBaseModem *self,
|
||||||
|
GAsyncResult *res,
|
||||||
|
HandleSetChannelsCellBroadcastContext *ctx)
|
||||||
|
{
|
||||||
|
GError *error = NULL;
|
||||||
|
|
||||||
|
if (!mm_base_modem_authorize_finish (self, res, &error)) {
|
||||||
|
mm_dbus_method_invocation_take_error (ctx->invocation, error);
|
||||||
|
handle_set_channels_context_free (ctx);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Validate channels (either number or range) */
|
||||||
|
if (!mm_validate_cbs_channels (ctx->channels, &error)) {
|
||||||
|
mm_dbus_method_invocation_return_gerror (ctx->invocation, error);
|
||||||
|
handle_set_channels_context_free (ctx);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Check if plugin implements it */
|
||||||
|
if (!MM_IFACE_MODEM_CELL_BROADCAST_GET_IFACE (self)->set_channels ||
|
||||||
|
!MM_IFACE_MODEM_CELL_BROADCAST_GET_IFACE (self)->set_channels_finish) {
|
||||||
|
mm_dbus_method_invocation_return_error_literal (ctx->invocation, MM_CORE_ERROR, MM_CORE_ERROR_UNSUPPORTED,
|
||||||
|
"Cannot set channels: not implemented");
|
||||||
|
handle_set_channels_context_free (ctx);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Request to change channels */
|
||||||
|
mm_obj_info (self, "processing user request to set channels...");
|
||||||
|
MM_IFACE_MODEM_CELL_BROADCAST_GET_IFACE (self)->set_channels (ctx->self,
|
||||||
|
ctx->channels,
|
||||||
|
(GAsyncReadyCallback)set_channels_ready,
|
||||||
|
ctx);
|
||||||
|
}
|
||||||
|
|
||||||
|
static gboolean
|
||||||
|
handle_set_channels (MmGdbusModemCellBroadcast *skeleton,
|
||||||
|
GDBusMethodInvocation *invocation,
|
||||||
|
GVariant *channels,
|
||||||
|
MMIfaceModemCellBroadcast *self)
|
||||||
|
{
|
||||||
|
HandleSetChannelsCellBroadcastContext *ctx;
|
||||||
|
|
||||||
|
ctx = g_slice_new0 (HandleSetChannelsCellBroadcastContext);
|
||||||
|
ctx->skeleton = g_object_ref (skeleton);
|
||||||
|
ctx->invocation = g_object_ref (invocation);
|
||||||
|
ctx->self = g_object_ref (self);
|
||||||
|
ctx->channels = mm_common_cell_broadcast_channels_variant_to_garray (channels);
|
||||||
|
mm_base_modem_authorize (MM_BASE_MODEM (self),
|
||||||
|
invocation,
|
||||||
|
MM_AUTHORIZATION_DEVICE_CONTROL,
|
||||||
|
(GAsyncReadyCallback)handle_set_channels_auth_ready,
|
||||||
|
ctx);
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*****************************************************************************/
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
MmGdbusModemCellBroadcast *skeleton;
|
MmGdbusModemCellBroadcast *skeleton;
|
||||||
GDBusMethodInvocation *invocation;
|
GDBusMethodInvocation *invocation;
|
||||||
@@ -315,6 +411,12 @@ interface_initialization_step (GTask *task)
|
|||||||
|
|
||||||
case INITIALIZATION_STEP_LAST:
|
case INITIALIZATION_STEP_LAST:
|
||||||
/* We are done without errors! */
|
/* We are done without errors! */
|
||||||
|
|
||||||
|
/* Handle method invocations */
|
||||||
|
g_signal_connect (ctx->skeleton,
|
||||||
|
"handle-set-channels",
|
||||||
|
G_CALLBACK (handle_set_channels),
|
||||||
|
self);
|
||||||
g_signal_connect (ctx->skeleton,
|
g_signal_connect (ctx->skeleton,
|
||||||
"handle-delete",
|
"handle-delete",
|
||||||
G_CALLBACK (handle_delete),
|
G_CALLBACK (handle_delete),
|
||||||
|
|||||||
@@ -76,6 +76,15 @@ struct _MMIfaceModemCellBroadcastInterface {
|
|||||||
|
|
||||||
/* Create Cbm objects */
|
/* Create Cbm objects */
|
||||||
MMBaseCbm * (* create_cbm) (MMIfaceModemCellBroadcast *self);
|
MMBaseCbm * (* create_cbm) (MMIfaceModemCellBroadcast *self);
|
||||||
|
|
||||||
|
/* Set channel list */
|
||||||
|
void (* set_channels) (MMIfaceModemCellBroadcast *self,
|
||||||
|
GArray *channels,
|
||||||
|
GAsyncReadyCallback callback,
|
||||||
|
gpointer user_data);
|
||||||
|
gboolean (* set_channels_finish) (MMIfaceModemCellBroadcast *self,
|
||||||
|
GAsyncResult *res,
|
||||||
|
GError **error);
|
||||||
};
|
};
|
||||||
|
|
||||||
/* Initialize CellBroadcast interface (async) */
|
/* Initialize CellBroadcast interface (async) */
|
||||||
|
|||||||
Reference in New Issue
Block a user