diff mbox series

[BlueZ,v2,3/8] gdbus: Add g_dbus_proxy_set_property_dict

Message ID 20240829095206.91150-4-vlad.pruteanu@nxp.com
State New
Headers show
Series Add support for setting bcode on bcast sink | expand

Commit Message

Vlad Pruteanu Aug. 29, 2024, 9:52 a.m. UTC
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 mbox series

Patch

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 <marcel@holtmann.org>
+ *  Copyright 2024 NXP
  *
  *
  */
@@ -15,6 +16,7 @@ 
 #define _GNU_SOURCE
 #include <stdio.h>
 #include <string.h>
+#include <stdarg.h>
 #include <glib.h>
 #include <dbus/dbus.h>
 
@@ -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 <marcel@holtmann.org>
+ *  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,