From a1bde349db6bdb483f0396d1ba79f9078a3df431 Mon Sep 17 00:00:00 2001 From: Vlad Pruteanu Date: Thu, 29 Aug 2024 12:52:01 +0300 Subject: [PATCH] gdbus: Add g_dbus_proxy_set_property_dict This adds a new gdbus function to allow for the setting of a dictionary-type property (a{sv}). It receives the name of the property, the name of the first entry to be set from the dictionary, it's type and value, followed by the second pair of entry_name, type, value, and so on, marking the end of the entries with NULL. Additionally, if the type is an array, the type of the array and it's length must also be proviedd. These values are passed as a dict entry, to the set method associated with the property. There, it must be parsed and the appropriate entry updated. Example of usage: g_dbus_proxy_set_property_dict(proxy, "dict_property_name", cb, user_data, NULL, "entry_1", DBUS_TYPE_ARRAY, DBUS_TYPE_BYTE, value_1_len, value_1, "entry_2", DBUS_TYPE_BYTE, value_2, NULL) --- gdbus/client.c | 115 +++++++++++++++++++++++++++++++++++++++++++++++++ gdbus/gdbus.h | 6 +++ 2 files changed, 121 insertions(+) diff --git a/gdbus/client.c b/gdbus/client.c index 3b7faa4e4..deeb01dab 100644 --- a/gdbus/client.c +++ b/gdbus/client.c @@ -4,6 +4,7 @@ * D-Bus helper library * * Copyright (C) 2004-2011 Marcel Holtmann + * Copyright 2024 NXP * * */ @@ -15,6 +16,7 @@ #define _GNU_SOURCE #include #include +#include #include #include @@ -208,6 +210,44 @@ void g_dbus_dict_append_array(DBusMessageIter *dict, n_elements); } +static void append_dict_variant(DBusMessageIter *iter, char *entry, int type, + void *val, ...) +{ + DBusMessageIter variant, dict; + va_list args; + int array_type, size; + + dbus_message_iter_open_container(iter, DBUS_TYPE_VARIANT, + DBUS_TYPE_ARRAY_AS_STRING + DBUS_DICT_ENTRY_BEGIN_CHAR_AS_STRING + DBUS_TYPE_STRING_AS_STRING + DBUS_TYPE_VARIANT_AS_STRING + DBUS_DICT_ENTRY_END_CHAR_AS_STRING, + &variant); + + dbus_message_iter_open_container(&variant, DBUS_TYPE_ARRAY, + DBUS_DICT_ENTRY_BEGIN_CHAR_AS_STRING + DBUS_TYPE_STRING_AS_STRING + DBUS_TYPE_VARIANT_AS_STRING + DBUS_DICT_ENTRY_END_CHAR_AS_STRING, + &dict); + + va_start(args, val); + + if (type == DBUS_TYPE_ARRAY) { + array_type = va_arg(args, int); + size = va_arg(args, int); + g_dbus_dict_append_array(&dict, entry, array_type, val, size); + } else + g_dbus_dict_append_entry(&dict, entry, type, val); + + va_end(args); + + dbus_message_iter_close_container(&variant, &dict); + + dbus_message_iter_close_container(iter, &variant); +} + static void iter_append_iter(DBusMessageIter *base, DBusMessageIter *iter) { int type; @@ -885,6 +925,81 @@ gboolean g_dbus_proxy_set_property_basic(GDBusProxy *proxy, return TRUE; } +gboolean g_dbus_proxy_set_property_dict(GDBusProxy *proxy, + const char *name, GDBusResultFunction function, + void *user_data, GDBusDestroyFunction destroy, + char *entry, ...) +{ + struct set_property_data *data; + GDBusClient *client; + DBusMessage *msg; + DBusMessageIter iter; + DBusPendingCall *call; + va_list args; + int type, array_type, size; + void *value; + + if (proxy == NULL || name == NULL) + return FALSE; + + client = proxy->client; + if (client == NULL) + return FALSE; + + data = g_try_new0(struct set_property_data, 1); + if (data == NULL) + return FALSE; + + data->function = function; + data->user_data = user_data; + data->destroy = destroy; + + msg = dbus_message_new_method_call(client->service_name, + proxy->obj_path, DBUS_INTERFACE_PROPERTIES, "Set"); + if (msg == NULL) { + g_free(data); + return FALSE; + } + + dbus_message_iter_init_append(msg, &iter); + dbus_message_iter_append_basic(&iter, DBUS_TYPE_STRING, + &proxy->interface); + dbus_message_iter_append_basic(&iter, DBUS_TYPE_STRING, &name); + + va_start(args, entry); + + while (entry != NULL) { + type = va_arg(args, int); + if (type == DBUS_TYPE_ARRAY) { + array_type = va_arg(args, int); + size = va_arg(args, int); + value = va_arg(args, void *); + append_dict_variant(&iter, entry, type, &value, + array_type, size); + } else { + value = va_arg(args, void *); + append_dict_variant(&iter, entry, type, &value); + } + entry = va_arg(args, char *); + } + + va_end(args); + + if (g_dbus_send_message_with_reply(client->dbus_conn, msg, + &call, -1) == FALSE) { + dbus_message_unref(msg); + g_free(data); + return FALSE; + } + + dbus_pending_call_set_notify(call, set_property_reply, data, g_free); + dbus_pending_call_unref(call); + + dbus_message_unref(msg); + + return TRUE; +} + gboolean g_dbus_proxy_set_property_array(GDBusProxy *proxy, const char *name, int type, const void *value, size_t size, GDBusResultFunction function, diff --git a/gdbus/gdbus.h b/gdbus/gdbus.h index 6fe09b743..d7be17661 100644 --- a/gdbus/gdbus.h +++ b/gdbus/gdbus.h @@ -4,6 +4,7 @@ * D-Bus helper library * * Copyright (C) 2004-2011 Marcel Holtmann + * Copyright 2024 NXP * * */ @@ -362,6 +363,11 @@ gboolean g_dbus_proxy_set_property_basic(GDBusProxy *proxy, GDBusResultFunction function, void *user_data, GDBusDestroyFunction destroy); +gboolean g_dbus_proxy_set_property_dict(GDBusProxy *proxy, + const char *name, GDBusResultFunction function, + void *user_data, GDBusDestroyFunction destroy, + char *entry, ...); + gboolean g_dbus_proxy_set_property_array(GDBusProxy *proxy, const char *name, int type, const void *value, size_t size, GDBusResultFunction function, -- 2.47.3