aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAleksander Morgado <aleksander@aleksander.es>2022-01-07 16:33:26 +0100
committerAleksander Morgado <aleksander@aleksander.es>2022-01-18 09:00:10 +0000
commit3c49e04377db5a61280da83f2c1f371219cf277f (patch)
tree9566e21a4efffe13274346f8cea65c42ee4a4ecb
parentc4f59aebe00c0cd25c4d27ed9e58b690e6b4b878 (diff)
iface-modem: implement support for 'GetCellInfo()'
-rw-r--r--src/mm-iface-modem.c110
-rw-r--r--src/mm-iface-modem.h8
2 files changed, 118 insertions, 0 deletions
diff --git a/src/mm-iface-modem.c b/src/mm-iface-modem.c
index 1426b44a..c22d46a7 100644
--- a/src/mm-iface-modem.c
+++ b/src/mm-iface-modem.c
@@ -1234,6 +1234,115 @@ handle_set_primary_sim_slot (MmGdbusModem *skeleton,
/*****************************************************************************/
+typedef struct {
+ MmGdbusModem *skeleton;
+ GDBusMethodInvocation *invocation;
+ MMIfaceModem *self;
+} HandleGetCellInfoContext;
+
+static void
+handle_get_cell_info_context_free (HandleGetCellInfoContext *ctx)
+{
+ g_object_unref (ctx->skeleton);
+ g_object_unref (ctx->invocation);
+ g_object_unref (ctx->self);
+ g_free (ctx);
+}
+
+static GVariant *
+get_cell_info_build_result (GList *info_list)
+{
+ GList *l;
+ GVariantBuilder builder;
+
+ g_variant_builder_init (&builder, G_VARIANT_TYPE ("aa{sv}"));
+
+ for (l = info_list; l; l = g_list_next (l)) {
+ g_autoptr(GVariant) dict = NULL;
+
+ dict = mm_cell_info_get_dictionary (MM_CELL_INFO (l->data));
+ g_variant_builder_add_value (&builder, dict);
+ }
+
+ return g_variant_ref_sink (g_variant_builder_end (&builder));
+}
+
+static void
+get_cell_info_ready (MMIfaceModem *self,
+ GAsyncResult *res,
+ HandleGetCellInfoContext *ctx)
+{
+ GError *error = NULL;
+ GList *info_list;
+
+ info_list = MM_IFACE_MODEM_GET_INTERFACE (self)->get_cell_info_finish (self, res, &error);
+ if (error)
+ g_dbus_method_invocation_take_error (ctx->invocation, error);
+ else {
+ g_autoptr(GVariant) dict_array = NULL;
+
+ dict_array = get_cell_info_build_result (info_list);
+ mm_gdbus_modem_complete_get_cell_info (ctx->skeleton, ctx->invocation, dict_array);
+ }
+
+ g_list_free_full (info_list, (GDestroyNotify)g_object_unref);
+ handle_get_cell_info_context_free (ctx);
+}
+
+static void
+handle_get_cell_info_auth_ready (MMBaseModem *self,
+ GAsyncResult *res,
+ HandleGetCellInfoContext *ctx)
+{
+ GError *error = NULL;
+
+ if (!mm_base_modem_authorize_finish (self, res, &error)) {
+ g_dbus_method_invocation_take_error (ctx->invocation, error);
+ handle_get_cell_info_context_free (ctx);
+ return;
+ }
+
+ /* If getting cell info is not implemented, report an error */
+ if (!MM_IFACE_MODEM_GET_INTERFACE (self)->get_cell_info ||
+ !MM_IFACE_MODEM_GET_INTERFACE (self)->get_cell_info_finish) {
+ g_dbus_method_invocation_return_error (ctx->invocation, MM_CORE_ERROR, MM_CORE_ERROR_UNSUPPORTED,
+ "Cannot get cell info: operation not supported");
+ handle_get_cell_info_context_free (ctx);
+ return;
+ }
+
+ if (mm_iface_modem_abort_invocation_if_state_not_reached (ctx->self, ctx->invocation, MM_MODEM_STATE_ENABLED)) {
+ handle_get_cell_info_context_free (ctx);
+ return;
+ }
+
+ MM_IFACE_MODEM_GET_INTERFACE (self)->get_cell_info (ctx->self,
+ (GAsyncReadyCallback)get_cell_info_ready,
+ ctx);
+}
+
+static gboolean
+handle_get_cell_info (MmGdbusModem *skeleton,
+ GDBusMethodInvocation *invocation,
+ MMIfaceModem *self)
+{
+ HandleGetCellInfoContext *ctx;
+
+ ctx = g_new (HandleGetCellInfoContext, 1);
+ ctx->skeleton = g_object_ref (skeleton);
+ ctx->invocation = g_object_ref (invocation);
+ ctx->self = g_object_ref (self);
+
+ mm_base_modem_authorize (MM_BASE_MODEM (self),
+ invocation,
+ MM_AUTHORIZATION_DEVICE_CONTROL,
+ (GAsyncReadyCallback)handle_get_cell_info_auth_ready,
+ ctx);
+ return TRUE;
+}
+
+/*****************************************************************************/
+
void
mm_iface_modem_update_access_technologies (MMIfaceModem *self,
MMModemAccessTechnology new_access_tech,
@@ -5891,6 +6000,7 @@ interface_initialization_step (GTask *task)
"signal::handle-set-current-bands", G_CALLBACK (handle_set_current_bands), self,
"signal::handle-set-current-modes", G_CALLBACK (handle_set_current_modes), self,
"signal::handle-set-primary-sim-slot", G_CALLBACK (handle_set_primary_sim_slot), self,
+ "signal::handle-get-cell-info", G_CALLBACK (handle_get_cell_info), self,
NULL);
/* Finally, export the new interface, even if we got errors, but only if not
diff --git a/src/mm-iface-modem.h b/src/mm-iface-modem.h
index 2abadf27..1e934c99 100644
--- a/src/mm-iface-modem.h
+++ b/src/mm-iface-modem.h
@@ -405,6 +405,14 @@ struct _MMIfaceModem {
gboolean (* setup_carrier_config_finish) (MMIfaceModem *self,
GAsyncResult *res,
GError **error);
+
+ /* Asynchronous cell info retrieval operation */
+ void (* get_cell_info) (MMIfaceModem *self,
+ GAsyncReadyCallback callback,
+ gpointer user_data);
+ GList * (* get_cell_info_finish) (MMIfaceModem *self,
+ GAsyncResult *res,
+ GError **error);
};
GType mm_iface_modem_get_type (void);