diff options
Diffstat (limited to 'src/mm-iface-modem-cell-broadcast.c')
-rw-r--r-- | src/mm-iface-modem-cell-broadcast.c | 141 |
1 files changed, 141 insertions, 0 deletions
diff --git a/src/mm-iface-modem-cell-broadcast.c b/src/mm-iface-modem-cell-broadcast.c index 8e5af67c..f543d8f9 100644 --- a/src/mm-iface-modem-cell-broadcast.c +++ b/src/mm-iface-modem-cell-broadcast.c @@ -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 { MmGdbusModemCellBroadcast *skeleton; GDBusMethodInvocation *invocation; @@ -315,6 +411,12 @@ interface_initialization_step (GTask *task) case INITIALIZATION_STEP_LAST: /* 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, "handle-delete", G_CALLBACK (handle_delete), @@ -425,6 +527,7 @@ typedef enum { ENABLING_STEP_FIRST, ENABLING_STEP_SETUP_UNSOLICITED_EVENTS, ENABLING_STEP_ENABLE_UNSOLICITED_EVENTS, + ENABLING_STEP_GET_CHANNELS, ENABLING_STEP_LAST } EnablingStep; @@ -491,6 +594,31 @@ enable_unsolicited_events_ready (MMIfaceModemCellBroadcast *self, } static void +load_channels_ready (MMIfaceModemCellBroadcast *self, + GAsyncResult *res, + GTask *task) +{ + EnablingContext *ctx; + g_autoptr (GError) error = NULL; + g_autoptr (GArray) channels = NULL; + + ctx = g_task_get_task_data (task); + channels = MM_IFACE_MODEM_CELL_BROADCAST_GET_IFACE (self)->load_channels_finish (self, res, &error); + if (channels) { + mm_gdbus_modem_cell_broadcast_set_channels ( + ctx->skeleton, + mm_common_cell_broadcast_channels_garray_to_variant (channels)); + } else { + /* Not critical! */ + mm_obj_warn (self, "Couldn't load current channel list: %s", error->message); + } + + /* Go on with next step */ + ctx->step++; + interface_enabling_step (task); +} + +static void interface_enabling_step (GTask *task) { MMIfaceModemCellBroadcast *self; @@ -552,6 +680,19 @@ interface_enabling_step (GTask *task) ctx->step++; /* fall through */ + case ENABLING_STEP_GET_CHANNELS: + /* Read current channel list */ + if (MM_IFACE_MODEM_CELL_BROADCAST_GET_IFACE (self)->load_channels && + MM_IFACE_MODEM_CELL_BROADCAST_GET_IFACE (self)->load_channels_finish) { + MM_IFACE_MODEM_CELL_BROADCAST_GET_IFACE (self)->load_channels ( + self, + (GAsyncReadyCallback)load_channels_ready, + task); + return; + } + ctx->step++; + /* fall through */ + case ENABLING_STEP_LAST: /* We are done without errors! */ g_task_return_boolean (task, TRUE); |