object.c revision 5cf1ae29510f5ec975080c793c692fedc10d86d8
1ee6b2930a0519021232f92f615f6a8fd9cd61805Marcel Holtmann/*
2ee6b2930a0519021232f92f615f6a8fd9cd61805Marcel Holtmann *
3ee6b2930a0519021232f92f615f6a8fd9cd61805Marcel Holtmann *  BlueZ - Bluetooth protocol stack for Linux
4ee6b2930a0519021232f92f615f6a8fd9cd61805Marcel Holtmann *
5ee6b2930a0519021232f92f615f6a8fd9cd61805Marcel Holtmann *  Copyright (C) 2004-2007  Marcel Holtmann <marcel@holtmann.org>
6ee6b2930a0519021232f92f615f6a8fd9cd61805Marcel Holtmann *
7ee6b2930a0519021232f92f615f6a8fd9cd61805Marcel Holtmann *
8ee6b2930a0519021232f92f615f6a8fd9cd61805Marcel Holtmann *  This program is free software; you can redistribute it and/or modify
9ee6b2930a0519021232f92f615f6a8fd9cd61805Marcel Holtmann *  it under the terms of the GNU General Public License as published by
10ee6b2930a0519021232f92f615f6a8fd9cd61805Marcel Holtmann *  the Free Software Foundation; either version 2 of the License, or
11ee6b2930a0519021232f92f615f6a8fd9cd61805Marcel Holtmann *  (at your option) any later version.
12ee6b2930a0519021232f92f615f6a8fd9cd61805Marcel Holtmann *
13ee6b2930a0519021232f92f615f6a8fd9cd61805Marcel Holtmann *  This program is distributed in the hope that it will be useful,
14ee6b2930a0519021232f92f615f6a8fd9cd61805Marcel Holtmann *  but WITHOUT ANY WARRANTY; without even the implied warranty of
15ee6b2930a0519021232f92f615f6a8fd9cd61805Marcel Holtmann *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16ee6b2930a0519021232f92f615f6a8fd9cd61805Marcel Holtmann *  GNU General Public License for more details.
17ee6b2930a0519021232f92f615f6a8fd9cd61805Marcel Holtmann *
18ee6b2930a0519021232f92f615f6a8fd9cd61805Marcel Holtmann *  You should have received a copy of the GNU General Public License
19ee6b2930a0519021232f92f615f6a8fd9cd61805Marcel Holtmann *  along with this program; if not, write to the Free Software
20ee6b2930a0519021232f92f615f6a8fd9cd61805Marcel Holtmann *  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
21ee6b2930a0519021232f92f615f6a8fd9cd61805Marcel Holtmann *
22ee6b2930a0519021232f92f615f6a8fd9cd61805Marcel Holtmann */
23ee6b2930a0519021232f92f615f6a8fd9cd61805Marcel Holtmann
24ee6b2930a0519021232f92f615f6a8fd9cd61805Marcel Holtmann#ifdef HAVE_CONFIG_H
25ee6b2930a0519021232f92f615f6a8fd9cd61805Marcel Holtmann#include <config.h>
26ee6b2930a0519021232f92f615f6a8fd9cd61805Marcel Holtmann#endif
27ee6b2930a0519021232f92f615f6a8fd9cd61805Marcel Holtmann
28ee6b2930a0519021232f92f615f6a8fd9cd61805Marcel Holtmann#include <stdlib.h>
29ee6b2930a0519021232f92f615f6a8fd9cd61805Marcel Holtmann#include <string.h>
30ee6b2930a0519021232f92f615f6a8fd9cd61805Marcel Holtmann
318cc5595d9091b484b9a4abe314c0f3ec055e0581Marcel Holtmann#include <glib.h>
328cc5595d9091b484b9a4abe314c0f3ec055e0581Marcel Holtmann
33ee6b2930a0519021232f92f615f6a8fd9cd61805Marcel Holtmann#include <dbus/dbus.h>
34ee6b2930a0519021232f92f615f6a8fd9cd61805Marcel Holtmann
35ee6b2930a0519021232f92f615f6a8fd9cd61805Marcel Holtmann#include "logging.h"
36ee6b2930a0519021232f92f615f6a8fd9cd61805Marcel Holtmann
37ee6b2930a0519021232f92f615f6a8fd9cd61805Marcel Holtmann#include "dbus-helper.h"
38ee6b2930a0519021232f92f615f6a8fd9cd61805Marcel Holtmann
39ee6b2930a0519021232f92f615f6a8fd9cd61805Marcel Holtmannstruct generic_data {
40ee6b2930a0519021232f92f615f6a8fd9cd61805Marcel Holtmann	void *user_data;
41ee6b2930a0519021232f92f615f6a8fd9cd61805Marcel Holtmann	DBusObjectPathUnregisterFunction unregister_function;
42f7c027662d2066b3862f41dbae3b68e5c1bafce7Marcel Holtmann	GSList *interfaces;
43f7c027662d2066b3862f41dbae3b68e5c1bafce7Marcel Holtmann	char *introspect;
44f7c027662d2066b3862f41dbae3b68e5c1bafce7Marcel Holtmann};
45f7c027662d2066b3862f41dbae3b68e5c1bafce7Marcel Holtmann
46f7c027662d2066b3862f41dbae3b68e5c1bafce7Marcel Holtmannstruct interface_data {
4730957bc2890f3db99907178304046610e77c7efaJohan Hedberg	char *name;
48ee6b2930a0519021232f92f615f6a8fd9cd61805Marcel Holtmann	DBusMethodVTable *methods;
4930957bc2890f3db99907178304046610e77c7efaJohan Hedberg	DBusSignalVTable *signals;
5030957bc2890f3db99907178304046610e77c7efaJohan Hedberg	DBusPropertyVTable *properties;
51ee6b2930a0519021232f92f615f6a8fd9cd61805Marcel Holtmann};
52ee6b2930a0519021232f92f615f6a8fd9cd61805Marcel Holtmann
53ee6b2930a0519021232f92f615f6a8fd9cd61805Marcel HoltmannDBusHandlerResult dbus_connection_send_and_unref(DBusConnection *connection,
54ee6b2930a0519021232f92f615f6a8fd9cd61805Marcel Holtmann							DBusMessage *message)
55ee6b2930a0519021232f92f615f6a8fd9cd61805Marcel Holtmann{
56ee6b2930a0519021232f92f615f6a8fd9cd61805Marcel Holtmann	if (message) {
57ee6b2930a0519021232f92f615f6a8fd9cd61805Marcel Holtmann		dbus_connection_send(connection, message, NULL);
58ee6b2930a0519021232f92f615f6a8fd9cd61805Marcel Holtmann		dbus_message_unref(message);
59ee6b2930a0519021232f92f615f6a8fd9cd61805Marcel Holtmann	}
60ee6b2930a0519021232f92f615f6a8fd9cd61805Marcel Holtmann
61ee6b2930a0519021232f92f615f6a8fd9cd61805Marcel Holtmann	return DBUS_HANDLER_RESULT_HANDLED;
62ee6b2930a0519021232f92f615f6a8fd9cd61805Marcel Holtmann}
63ee6b2930a0519021232f92f615f6a8fd9cd61805Marcel Holtmann
64ee6b2930a0519021232f92f615f6a8fd9cd61805Marcel Holtmannstatic DBusHandlerResult introspect(DBusConnection *connection,
65ee6b2930a0519021232f92f615f6a8fd9cd61805Marcel Holtmann				DBusMessage *message, struct generic_data *data)
66ee6b2930a0519021232f92f615f6a8fd9cd61805Marcel Holtmann{
67ee6b2930a0519021232f92f615f6a8fd9cd61805Marcel Holtmann	DBusMessage *reply;
68ee6b2930a0519021232f92f615f6a8fd9cd61805Marcel Holtmann
69ee6b2930a0519021232f92f615f6a8fd9cd61805Marcel Holtmann	if (dbus_message_has_signature(message,
70ee6b2930a0519021232f92f615f6a8fd9cd61805Marcel Holtmann				DBUS_TYPE_INVALID_AS_STRING) == FALSE) {
71ee6b2930a0519021232f92f615f6a8fd9cd61805Marcel Holtmann		error("Unexpected signature to introspect call");
72ee6b2930a0519021232f92f615f6a8fd9cd61805Marcel Holtmann		return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
73ee6b2930a0519021232f92f615f6a8fd9cd61805Marcel Holtmann	}
74ee6b2930a0519021232f92f615f6a8fd9cd61805Marcel Holtmann
75ee6b2930a0519021232f92f615f6a8fd9cd61805Marcel Holtmann	if (!data->introspect)
76ee6b2930a0519021232f92f615f6a8fd9cd61805Marcel Holtmann		return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
77ee6b2930a0519021232f92f615f6a8fd9cd61805Marcel Holtmann
78ee6b2930a0519021232f92f615f6a8fd9cd61805Marcel Holtmann	reply = dbus_message_new_method_return(message);
79ee6b2930a0519021232f92f615f6a8fd9cd61805Marcel Holtmann	if (!reply)
80ee6b2930a0519021232f92f615f6a8fd9cd61805Marcel Holtmann		return DBUS_HANDLER_RESULT_NEED_MEMORY;
81ee6b2930a0519021232f92f615f6a8fd9cd61805Marcel Holtmann
82ee6b2930a0519021232f92f615f6a8fd9cd61805Marcel Holtmann	dbus_message_append_args(reply, DBUS_TYPE_STRING, &data->introspect,
83ee6b2930a0519021232f92f615f6a8fd9cd61805Marcel Holtmann					DBUS_TYPE_INVALID);
84ee6b2930a0519021232f92f615f6a8fd9cd61805Marcel Holtmann
85ee6b2930a0519021232f92f615f6a8fd9cd61805Marcel Holtmann	return dbus_connection_send_and_unref(connection, reply);
86ee6b2930a0519021232f92f615f6a8fd9cd61805Marcel Holtmann}
87ee6b2930a0519021232f92f615f6a8fd9cd61805Marcel Holtmann
88ee6b2930a0519021232f92f615f6a8fd9cd61805Marcel Holtmannstatic void generic_unregister(DBusConnection *connection, void *user_data)
89ee6b2930a0519021232f92f615f6a8fd9cd61805Marcel Holtmann{
90ee6b2930a0519021232f92f615f6a8fd9cd61805Marcel Holtmann	struct generic_data *data = user_data;
91ee6b2930a0519021232f92f615f6a8fd9cd61805Marcel Holtmann
92ee6b2930a0519021232f92f615f6a8fd9cd61805Marcel Holtmann	if (data->unregister_function)
93ee6b2930a0519021232f92f615f6a8fd9cd61805Marcel Holtmann		data->unregister_function(connection, data->user_data);
94ee6b2930a0519021232f92f615f6a8fd9cd61805Marcel Holtmann
95d370964fbe6a9e32837037dcf193a216a0a75077Johan Hedberg	g_free(data->introspect);
963d16152fd30f2570ad8e9bb2427045e6fd317ce3Johan Hedberg	g_free(data);
97ee6b2930a0519021232f92f615f6a8fd9cd61805Marcel Holtmann}
98ee6b2930a0519021232f92f615f6a8fd9cd61805Marcel Holtmann
99f7c027662d2066b3862f41dbae3b68e5c1bafce7Marcel Holtmannstatic struct interface_data *find_interface(GSList *interfaces,
10030957bc2890f3db99907178304046610e77c7efaJohan Hedberg						const char *name)
101f7c027662d2066b3862f41dbae3b68e5c1bafce7Marcel Holtmann{
102f7c027662d2066b3862f41dbae3b68e5c1bafce7Marcel Holtmann	GSList *list;
103f7c027662d2066b3862f41dbae3b68e5c1bafce7Marcel Holtmann
104f7c027662d2066b3862f41dbae3b68e5c1bafce7Marcel Holtmann	for (list = interfaces; list; list = list->next) {
105f7c027662d2066b3862f41dbae3b68e5c1bafce7Marcel Holtmann		struct interface_data *iface = list->data;
10630957bc2890f3db99907178304046610e77c7efaJohan Hedberg		if (!strcmp(name, iface->name))
107f7c027662d2066b3862f41dbae3b68e5c1bafce7Marcel Holtmann			return iface;
108f7c027662d2066b3862f41dbae3b68e5c1bafce7Marcel Holtmann	}
109f7c027662d2066b3862f41dbae3b68e5c1bafce7Marcel Holtmann
110f7c027662d2066b3862f41dbae3b68e5c1bafce7Marcel Holtmann	return NULL;
111f7c027662d2066b3862f41dbae3b68e5c1bafce7Marcel Holtmann}
112f7c027662d2066b3862f41dbae3b68e5c1bafce7Marcel Holtmann
113ee6b2930a0519021232f92f615f6a8fd9cd61805Marcel Holtmannstatic DBusHandlerResult generic_message(DBusConnection *connection,
114ee6b2930a0519021232f92f615f6a8fd9cd61805Marcel Holtmann					DBusMessage *message, void *user_data)
115ee6b2930a0519021232f92f615f6a8fd9cd61805Marcel Holtmann{
116ee6b2930a0519021232f92f615f6a8fd9cd61805Marcel Holtmann	struct generic_data *data = user_data;
117f7c027662d2066b3862f41dbae3b68e5c1bafce7Marcel Holtmann	struct interface_data *iface;
118ee6b2930a0519021232f92f615f6a8fd9cd61805Marcel Holtmann	DBusMethodVTable *current;
119f7c027662d2066b3862f41dbae3b68e5c1bafce7Marcel Holtmann	const char *interface;
120ee6b2930a0519021232f92f615f6a8fd9cd61805Marcel Holtmann
121ee6b2930a0519021232f92f615f6a8fd9cd61805Marcel Holtmann	if (dbus_message_is_method_call(message, DBUS_INTERFACE_INTROSPECTABLE,
122ee6b2930a0519021232f92f615f6a8fd9cd61805Marcel Holtmann							"Introspect") == TRUE)
123ee6b2930a0519021232f92f615f6a8fd9cd61805Marcel Holtmann		return introspect(connection, message, data);
124ee6b2930a0519021232f92f615f6a8fd9cd61805Marcel Holtmann
125f7c027662d2066b3862f41dbae3b68e5c1bafce7Marcel Holtmann	interface = dbus_message_get_interface(message);
126f7c027662d2066b3862f41dbae3b68e5c1bafce7Marcel Holtmann
127f7c027662d2066b3862f41dbae3b68e5c1bafce7Marcel Holtmann	iface = find_interface(data->interfaces, interface);
128f7c027662d2066b3862f41dbae3b68e5c1bafce7Marcel Holtmann	if (!iface)
129f7c027662d2066b3862f41dbae3b68e5c1bafce7Marcel Holtmann		return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
130f7c027662d2066b3862f41dbae3b68e5c1bafce7Marcel Holtmann
131f7c027662d2066b3862f41dbae3b68e5c1bafce7Marcel Holtmann	for (current = iface->methods;
132ee6b2930a0519021232f92f615f6a8fd9cd61805Marcel Holtmann			current->name && current->message_function; current++) {
133ee6b2930a0519021232f92f615f6a8fd9cd61805Marcel Holtmann		if (dbus_message_is_method_call(message,
13430957bc2890f3db99907178304046610e77c7efaJohan Hedberg				iface->name, current->name) == FALSE)
135ee6b2930a0519021232f92f615f6a8fd9cd61805Marcel Holtmann			continue;
136ee6b2930a0519021232f92f615f6a8fd9cd61805Marcel Holtmann
137ee6b2930a0519021232f92f615f6a8fd9cd61805Marcel Holtmann		if (dbus_message_has_signature(message,
138ee6b2930a0519021232f92f615f6a8fd9cd61805Marcel Holtmann				current->signature) == TRUE)
139ee6b2930a0519021232f92f615f6a8fd9cd61805Marcel Holtmann			return current->message_function(connection,
140ee6b2930a0519021232f92f615f6a8fd9cd61805Marcel Holtmann						message, data->user_data);
141ee6b2930a0519021232f92f615f6a8fd9cd61805Marcel Holtmann	}
142ee6b2930a0519021232f92f615f6a8fd9cd61805Marcel Holtmann
143ee6b2930a0519021232f92f615f6a8fd9cd61805Marcel Holtmann	return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
144ee6b2930a0519021232f92f615f6a8fd9cd61805Marcel Holtmann}
145ee6b2930a0519021232f92f615f6a8fd9cd61805Marcel Holtmann
146ee6b2930a0519021232f92f615f6a8fd9cd61805Marcel Holtmannstatic DBusObjectPathVTable generic_table = {
147ee6b2930a0519021232f92f615f6a8fd9cd61805Marcel Holtmann	.unregister_function	= generic_unregister,
148ee6b2930a0519021232f92f615f6a8fd9cd61805Marcel Holtmann	.message_function	= generic_message,
149ee6b2930a0519021232f92f615f6a8fd9cd61805Marcel Holtmann};
150ee6b2930a0519021232f92f615f6a8fd9cd61805Marcel Holtmann
151d370964fbe6a9e32837037dcf193a216a0a75077Johan Hedbergstatic void print_arguments(GString *gstr, const char *sig, const char *direction)
152d370964fbe6a9e32837037dcf193a216a0a75077Johan Hedberg{
153d370964fbe6a9e32837037dcf193a216a0a75077Johan Hedberg	int i;
154d370964fbe6a9e32837037dcf193a216a0a75077Johan Hedberg
155d370964fbe6a9e32837037dcf193a216a0a75077Johan Hedberg	for (i = 0; sig[i]; i++) {
156223aa9581953c03f371a10b3f0555f7fa132f690Johan Hedberg		char type[32];
157223aa9581953c03f371a10b3f0555f7fa132f690Johan Hedberg		int len, struct_level, dict_level;
158223aa9581953c03f371a10b3f0555f7fa132f690Johan Hedberg		gboolean complete;
159223aa9581953c03f371a10b3f0555f7fa132f690Johan Hedberg
160223aa9581953c03f371a10b3f0555f7fa132f690Johan Hedberg		complete = FALSE;
161223aa9581953c03f371a10b3f0555f7fa132f690Johan Hedberg		struct_level = dict_level = 0;
162223aa9581953c03f371a10b3f0555f7fa132f690Johan Hedberg		memset(type, 0, sizeof(type));
163223aa9581953c03f371a10b3f0555f7fa132f690Johan Hedberg
164223aa9581953c03f371a10b3f0555f7fa132f690Johan Hedberg		/* Gather enough data to have a single complete type */
165223aa9581953c03f371a10b3f0555f7fa132f690Johan Hedberg		for (len = 0; len < (sizeof(type) - 1) && sig[i]; len++, i++) {
166223aa9581953c03f371a10b3f0555f7fa132f690Johan Hedberg			switch (sig[i]){
167223aa9581953c03f371a10b3f0555f7fa132f690Johan Hedberg			case '(':
168223aa9581953c03f371a10b3f0555f7fa132f690Johan Hedberg				struct_level++;
169223aa9581953c03f371a10b3f0555f7fa132f690Johan Hedberg				break;
170223aa9581953c03f371a10b3f0555f7fa132f690Johan Hedberg			case ')':
171223aa9581953c03f371a10b3f0555f7fa132f690Johan Hedberg				struct_level--;
172223aa9581953c03f371a10b3f0555f7fa132f690Johan Hedberg				if (struct_level <= 0 && dict_level <= 0)
173223aa9581953c03f371a10b3f0555f7fa132f690Johan Hedberg					complete = TRUE;
174223aa9581953c03f371a10b3f0555f7fa132f690Johan Hedberg				break;
175223aa9581953c03f371a10b3f0555f7fa132f690Johan Hedberg			case '{':
176223aa9581953c03f371a10b3f0555f7fa132f690Johan Hedberg				dict_level++;
177223aa9581953c03f371a10b3f0555f7fa132f690Johan Hedberg				break;
178223aa9581953c03f371a10b3f0555f7fa132f690Johan Hedberg			case '}':
179223aa9581953c03f371a10b3f0555f7fa132f690Johan Hedberg				dict_level--;
180223aa9581953c03f371a10b3f0555f7fa132f690Johan Hedberg				if (struct_level <= 0 && dict_level <= 0)
181223aa9581953c03f371a10b3f0555f7fa132f690Johan Hedberg					complete = TRUE;
182223aa9581953c03f371a10b3f0555f7fa132f690Johan Hedberg				break;
183223aa9581953c03f371a10b3f0555f7fa132f690Johan Hedberg			case 'a':
184223aa9581953c03f371a10b3f0555f7fa132f690Johan Hedberg				break;
185223aa9581953c03f371a10b3f0555f7fa132f690Johan Hedberg			default:
186223aa9581953c03f371a10b3f0555f7fa132f690Johan Hedberg				if (struct_level <= 0 && dict_level <= 0)
187223aa9581953c03f371a10b3f0555f7fa132f690Johan Hedberg					complete = TRUE;
188223aa9581953c03f371a10b3f0555f7fa132f690Johan Hedberg				break;
189223aa9581953c03f371a10b3f0555f7fa132f690Johan Hedberg			}
190223aa9581953c03f371a10b3f0555f7fa132f690Johan Hedberg
191223aa9581953c03f371a10b3f0555f7fa132f690Johan Hedberg			type[len] = sig[i];
192223aa9581953c03f371a10b3f0555f7fa132f690Johan Hedberg
193223aa9581953c03f371a10b3f0555f7fa132f690Johan Hedberg			if (complete)
194223aa9581953c03f371a10b3f0555f7fa132f690Johan Hedberg				break;
195223aa9581953c03f371a10b3f0555f7fa132f690Johan Hedberg		}
196223aa9581953c03f371a10b3f0555f7fa132f690Johan Hedberg
197223aa9581953c03f371a10b3f0555f7fa132f690Johan Hedberg
198d370964fbe6a9e32837037dcf193a216a0a75077Johan Hedberg		if (direction)
199d370964fbe6a9e32837037dcf193a216a0a75077Johan Hedberg			g_string_append_printf(gstr,
200223aa9581953c03f371a10b3f0555f7fa132f690Johan Hedberg					"\t\t\t<arg type=\"%s\" direction=\"%s\"/>\n",
201223aa9581953c03f371a10b3f0555f7fa132f690Johan Hedberg					type, direction);
202d370964fbe6a9e32837037dcf193a216a0a75077Johan Hedberg		else
203d370964fbe6a9e32837037dcf193a216a0a75077Johan Hedberg			g_string_append_printf(gstr,
204223aa9581953c03f371a10b3f0555f7fa132f690Johan Hedberg					"\t\t\t<arg type=\"%s\"/>\n",
205223aa9581953c03f371a10b3f0555f7fa132f690Johan Hedberg					type);
206d370964fbe6a9e32837037dcf193a216a0a75077Johan Hedberg	}
207d370964fbe6a9e32837037dcf193a216a0a75077Johan Hedberg}
208d370964fbe6a9e32837037dcf193a216a0a75077Johan Hedberg
2095cf1ae29510f5ec975080c793c692fedc10d86d8Johan Hedbergstatic void update_introspection_data(DBusConnection *conn, struct generic_data *data, const char *path)
210d370964fbe6a9e32837037dcf193a216a0a75077Johan Hedberg{
211d370964fbe6a9e32837037dcf193a216a0a75077Johan Hedberg	GSList *list;
212d370964fbe6a9e32837037dcf193a216a0a75077Johan Hedberg	GString *gstr;
2135cf1ae29510f5ec975080c793c692fedc10d86d8Johan Hedberg	char **children;
2145cf1ae29510f5ec975080c793c692fedc10d86d8Johan Hedberg	int i;
215d370964fbe6a9e32837037dcf193a216a0a75077Johan Hedberg
216d370964fbe6a9e32837037dcf193a216a0a75077Johan Hedberg	g_free(data->introspect);
217d370964fbe6a9e32837037dcf193a216a0a75077Johan Hedberg
218d370964fbe6a9e32837037dcf193a216a0a75077Johan Hedberg	gstr = g_string_new(DBUS_INTROSPECT_1_0_XML_DOCTYPE_DECL_NODE);
219d370964fbe6a9e32837037dcf193a216a0a75077Johan Hedberg
220d370964fbe6a9e32837037dcf193a216a0a75077Johan Hedberg	g_string_append_printf(gstr, "<node name=\"%s\">\n", path);
221d370964fbe6a9e32837037dcf193a216a0a75077Johan Hedberg
222d370964fbe6a9e32837037dcf193a216a0a75077Johan Hedberg	for (list = data->interfaces; list; list = list->next) {
223d370964fbe6a9e32837037dcf193a216a0a75077Johan Hedberg		struct interface_data *iface = list->data;
224d370964fbe6a9e32837037dcf193a216a0a75077Johan Hedberg		DBusMethodVTable *method;
225d370964fbe6a9e32837037dcf193a216a0a75077Johan Hedberg		DBusSignalVTable *signal;
226d370964fbe6a9e32837037dcf193a216a0a75077Johan Hedberg		DBusPropertyVTable *property;
227d370964fbe6a9e32837037dcf193a216a0a75077Johan Hedberg
228d370964fbe6a9e32837037dcf193a216a0a75077Johan Hedberg		g_string_append_printf(gstr, "\t<interface name=\"%s\">\n", iface->name);
229d370964fbe6a9e32837037dcf193a216a0a75077Johan Hedberg
230d370964fbe6a9e32837037dcf193a216a0a75077Johan Hedberg		for (method = iface->methods; method && method->name; method++) {
23146564396bfb21f61f839aa7f8fe9cb954c10af14Johan Hedberg			debug("%s: adding method %s.%s",
23246564396bfb21f61f839aa7f8fe9cb954c10af14Johan Hedberg					path, iface->name, method->name);
23346564396bfb21f61f839aa7f8fe9cb954c10af14Johan Hedberg			if (!strlen(method->signature) && !strlen(method->reply))
23446564396bfb21f61f839aa7f8fe9cb954c10af14Johan Hedberg				g_string_append_printf(gstr, "\t\t<method name=\"%s\"/>\n",
23546564396bfb21f61f839aa7f8fe9cb954c10af14Johan Hedberg							method->name);
23646564396bfb21f61f839aa7f8fe9cb954c10af14Johan Hedberg			else {
23746564396bfb21f61f839aa7f8fe9cb954c10af14Johan Hedberg				g_string_append_printf(gstr, "\t\t<method name=\"%s\">\n",
23846564396bfb21f61f839aa7f8fe9cb954c10af14Johan Hedberg							method->name);
23946564396bfb21f61f839aa7f8fe9cb954c10af14Johan Hedberg				print_arguments(gstr, method->signature, "in");
24046564396bfb21f61f839aa7f8fe9cb954c10af14Johan Hedberg				print_arguments(gstr, method->reply, "out");
24146564396bfb21f61f839aa7f8fe9cb954c10af14Johan Hedberg				g_string_append_printf(gstr, "\t\t</method>\n");
24246564396bfb21f61f839aa7f8fe9cb954c10af14Johan Hedberg			}
243d370964fbe6a9e32837037dcf193a216a0a75077Johan Hedberg		}
244d370964fbe6a9e32837037dcf193a216a0a75077Johan Hedberg
245d370964fbe6a9e32837037dcf193a216a0a75077Johan Hedberg		for (signal = iface->signals; signal && signal->name; signal++) {
24646564396bfb21f61f839aa7f8fe9cb954c10af14Johan Hedberg			debug("%s: adding signal %s.%s",
24746564396bfb21f61f839aa7f8fe9cb954c10af14Johan Hedberg					path, iface->name, signal->name);
24846564396bfb21f61f839aa7f8fe9cb954c10af14Johan Hedberg			if (!strlen(signal->signature))
24946564396bfb21f61f839aa7f8fe9cb954c10af14Johan Hedberg				g_string_append_printf(gstr, "\t\t<signal name=\"%s\"/>\n",
25046564396bfb21f61f839aa7f8fe9cb954c10af14Johan Hedberg							signal->name);
25146564396bfb21f61f839aa7f8fe9cb954c10af14Johan Hedberg			else {
25246564396bfb21f61f839aa7f8fe9cb954c10af14Johan Hedberg				g_string_append_printf(gstr, "\t\t<signal name=\"%s\">\n",
25346564396bfb21f61f839aa7f8fe9cb954c10af14Johan Hedberg							signal->name);
25446564396bfb21f61f839aa7f8fe9cb954c10af14Johan Hedberg				print_arguments(gstr, signal->signature, NULL);
25546564396bfb21f61f839aa7f8fe9cb954c10af14Johan Hedberg				g_string_append_printf(gstr, "\t\t</signal>\n");
25646564396bfb21f61f839aa7f8fe9cb954c10af14Johan Hedberg			}
257d370964fbe6a9e32837037dcf193a216a0a75077Johan Hedberg		}
258d370964fbe6a9e32837037dcf193a216a0a75077Johan Hedberg
259d370964fbe6a9e32837037dcf193a216a0a75077Johan Hedberg		for (property = iface->properties; property && property->name; property++) {
26046564396bfb21f61f839aa7f8fe9cb954c10af14Johan Hedberg			debug("%s: adding property %s.%s",
26146564396bfb21f61f839aa7f8fe9cb954c10af14Johan Hedberg					path, iface->name, property->name);
262d370964fbe6a9e32837037dcf193a216a0a75077Johan Hedberg		}
263d370964fbe6a9e32837037dcf193a216a0a75077Johan Hedberg
264d370964fbe6a9e32837037dcf193a216a0a75077Johan Hedberg		g_string_append_printf(gstr, "\t</interface>\n");
265d370964fbe6a9e32837037dcf193a216a0a75077Johan Hedberg	}
266d370964fbe6a9e32837037dcf193a216a0a75077Johan Hedberg
2675cf1ae29510f5ec975080c793c692fedc10d86d8Johan Hedberg	if (!dbus_connection_list_registered(conn, path, &children))
2685cf1ae29510f5ec975080c793c692fedc10d86d8Johan Hedberg		goto done;
2695cf1ae29510f5ec975080c793c692fedc10d86d8Johan Hedberg
2705cf1ae29510f5ec975080c793c692fedc10d86d8Johan Hedberg	for (i = 0; children[i]; i++)
2715cf1ae29510f5ec975080c793c692fedc10d86d8Johan Hedberg		g_string_append_printf(gstr, "\t<node name=\"%s\"/>\n", children[i]);
2725cf1ae29510f5ec975080c793c692fedc10d86d8Johan Hedberg
2735cf1ae29510f5ec975080c793c692fedc10d86d8Johan Hedberg	dbus_free_string_array(children);
2745cf1ae29510f5ec975080c793c692fedc10d86d8Johan Hedberg
2755cf1ae29510f5ec975080c793c692fedc10d86d8Johan Hedbergdone:
276d370964fbe6a9e32837037dcf193a216a0a75077Johan Hedberg	g_string_append_printf(gstr, "</node>\n");
277d370964fbe6a9e32837037dcf193a216a0a75077Johan Hedberg
278d370964fbe6a9e32837037dcf193a216a0a75077Johan Hedberg	data->introspect = g_string_free(gstr, FALSE);
279d370964fbe6a9e32837037dcf193a216a0a75077Johan Hedberg}
280f7c027662d2066b3862f41dbae3b68e5c1bafce7Marcel Holtmann
2815cf1ae29510f5ec975080c793c692fedc10d86d8Johan Hedbergstatic void update_parent_data(DBusConnection *conn, const char *child_path)
2825cf1ae29510f5ec975080c793c692fedc10d86d8Johan Hedberg{
2835cf1ae29510f5ec975080c793c692fedc10d86d8Johan Hedberg	struct generic_data *data;
2845cf1ae29510f5ec975080c793c692fedc10d86d8Johan Hedberg	char *parent_path, *slash;
2855cf1ae29510f5ec975080c793c692fedc10d86d8Johan Hedberg
2865cf1ae29510f5ec975080c793c692fedc10d86d8Johan Hedberg	parent_path = g_strdup(child_path);
2875cf1ae29510f5ec975080c793c692fedc10d86d8Johan Hedberg	slash = strrchr(parent_path, '/');
2885cf1ae29510f5ec975080c793c692fedc10d86d8Johan Hedberg	if (!slash)
2895cf1ae29510f5ec975080c793c692fedc10d86d8Johan Hedberg		goto done;
2905cf1ae29510f5ec975080c793c692fedc10d86d8Johan Hedberg
2915cf1ae29510f5ec975080c793c692fedc10d86d8Johan Hedberg	*slash = '\0';
2925cf1ae29510f5ec975080c793c692fedc10d86d8Johan Hedberg	if (!strlen(parent_path))
2935cf1ae29510f5ec975080c793c692fedc10d86d8Johan Hedberg		goto done;
2945cf1ae29510f5ec975080c793c692fedc10d86d8Johan Hedberg
2955cf1ae29510f5ec975080c793c692fedc10d86d8Johan Hedberg	if (!dbus_connection_get_object_path_data(conn, parent_path,
2965cf1ae29510f5ec975080c793c692fedc10d86d8Johan Hedberg						(void *) &data))
2975cf1ae29510f5ec975080c793c692fedc10d86d8Johan Hedberg		goto done;
2985cf1ae29510f5ec975080c793c692fedc10d86d8Johan Hedberg
2995cf1ae29510f5ec975080c793c692fedc10d86d8Johan Hedberg	if (!data)
3005cf1ae29510f5ec975080c793c692fedc10d86d8Johan Hedberg		goto done;
3015cf1ae29510f5ec975080c793c692fedc10d86d8Johan Hedberg
3025cf1ae29510f5ec975080c793c692fedc10d86d8Johan Hedberg	update_introspection_data(conn, data, parent_path);
3035cf1ae29510f5ec975080c793c692fedc10d86d8Johan Hedberg
3045cf1ae29510f5ec975080c793c692fedc10d86d8Johan Hedbergdone:
3055cf1ae29510f5ec975080c793c692fedc10d86d8Johan Hedberg	g_free(parent_path);
3065cf1ae29510f5ec975080c793c692fedc10d86d8Johan Hedberg}
3075cf1ae29510f5ec975080c793c692fedc10d86d8Johan Hedberg
308ee6b2930a0519021232f92f615f6a8fd9cd61805Marcel Holtmanndbus_bool_t dbus_connection_create_object_path(DBusConnection *connection,
309ee6b2930a0519021232f92f615f6a8fd9cd61805Marcel Holtmann					const char *path, void *user_data,
310ee6b2930a0519021232f92f615f6a8fd9cd61805Marcel Holtmann					DBusObjectPathUnregisterFunction function)
311ee6b2930a0519021232f92f615f6a8fd9cd61805Marcel Holtmann{
312ee6b2930a0519021232f92f615f6a8fd9cd61805Marcel Holtmann	struct generic_data *data;
313ee6b2930a0519021232f92f615f6a8fd9cd61805Marcel Holtmann
3143d16152fd30f2570ad8e9bb2427045e6fd317ce3Johan Hedberg	data = g_new0(struct generic_data, 1);
315ee6b2930a0519021232f92f615f6a8fd9cd61805Marcel Holtmann
316ee6b2930a0519021232f92f615f6a8fd9cd61805Marcel Holtmann	data->user_data = user_data;
317ee6b2930a0519021232f92f615f6a8fd9cd61805Marcel Holtmann	data->unregister_function = function;
318ee6b2930a0519021232f92f615f6a8fd9cd61805Marcel Holtmann
319d370964fbe6a9e32837037dcf193a216a0a75077Johan Hedberg	data->introspect = g_strdup(DBUS_INTROSPECT_1_0_XML_DOCTYPE_DECL_NODE "<node></node>");
320f7c027662d2066b3862f41dbae3b68e5c1bafce7Marcel Holtmann
321ee6b2930a0519021232f92f615f6a8fd9cd61805Marcel Holtmann	if (dbus_connection_register_object_path(connection, path,
322ee6b2930a0519021232f92f615f6a8fd9cd61805Marcel Holtmann					&generic_table, data) == FALSE) {
3233d16152fd30f2570ad8e9bb2427045e6fd317ce3Johan Hedberg		g_free(data);
324ee6b2930a0519021232f92f615f6a8fd9cd61805Marcel Holtmann		return FALSE;
325ee6b2930a0519021232f92f615f6a8fd9cd61805Marcel Holtmann	}
326ee6b2930a0519021232f92f615f6a8fd9cd61805Marcel Holtmann
3275cf1ae29510f5ec975080c793c692fedc10d86d8Johan Hedberg	update_parent_data(connection, path);
3285cf1ae29510f5ec975080c793c692fedc10d86d8Johan Hedberg
329ee6b2930a0519021232f92f615f6a8fd9cd61805Marcel Holtmann	return TRUE;
330ee6b2930a0519021232f92f615f6a8fd9cd61805Marcel Holtmann}
331ee6b2930a0519021232f92f615f6a8fd9cd61805Marcel Holtmann
332ee6b2930a0519021232f92f615f6a8fd9cd61805Marcel Holtmanndbus_bool_t dbus_connection_destroy_object_path(DBusConnection *connection,
333ee6b2930a0519021232f92f615f6a8fd9cd61805Marcel Holtmann							const char *path)
334ee6b2930a0519021232f92f615f6a8fd9cd61805Marcel Holtmann{
3355cf1ae29510f5ec975080c793c692fedc10d86d8Johan Hedberg	if (!dbus_connection_unregister_object_path(connection, path))
3365cf1ae29510f5ec975080c793c692fedc10d86d8Johan Hedberg		return FALSE;
3375cf1ae29510f5ec975080c793c692fedc10d86d8Johan Hedberg
3385cf1ae29510f5ec975080c793c692fedc10d86d8Johan Hedberg	update_parent_data(connection, path);
3395cf1ae29510f5ec975080c793c692fedc10d86d8Johan Hedberg
3405cf1ae29510f5ec975080c793c692fedc10d86d8Johan Hedberg	return TRUE;
341ee6b2930a0519021232f92f615f6a8fd9cd61805Marcel Holtmann}
342ee6b2930a0519021232f92f615f6a8fd9cd61805Marcel Holtmann
34316dceb4c2f7a8ed91c88b1c1353b6bd5ccc68cbfJohan Hedbergdbus_bool_t dbus_connection_get_object_user_data(DBusConnection *connection,
34416dceb4c2f7a8ed91c88b1c1353b6bd5ccc68cbfJohan Hedberg							const char *path,
34516dceb4c2f7a8ed91c88b1c1353b6bd5ccc68cbfJohan Hedberg							void **data_p)
34616dceb4c2f7a8ed91c88b1c1353b6bd5ccc68cbfJohan Hedberg{
34716dceb4c2f7a8ed91c88b1c1353b6bd5ccc68cbfJohan Hedberg	struct generic_data *data;
34816dceb4c2f7a8ed91c88b1c1353b6bd5ccc68cbfJohan Hedberg
34916dceb4c2f7a8ed91c88b1c1353b6bd5ccc68cbfJohan Hedberg	if (dbus_connection_get_object_path_data(connection, path,
35016dceb4c2f7a8ed91c88b1c1353b6bd5ccc68cbfJohan Hedberg						(void *) &data) == FALSE)
35116dceb4c2f7a8ed91c88b1c1353b6bd5ccc68cbfJohan Hedberg		return FALSE;
35216dceb4c2f7a8ed91c88b1c1353b6bd5ccc68cbfJohan Hedberg
35316dceb4c2f7a8ed91c88b1c1353b6bd5ccc68cbfJohan Hedberg	*data_p = data->user_data;
35416dceb4c2f7a8ed91c88b1c1353b6bd5ccc68cbfJohan Hedberg
35516dceb4c2f7a8ed91c88b1c1353b6bd5ccc68cbfJohan Hedberg	return TRUE;
35616dceb4c2f7a8ed91c88b1c1353b6bd5ccc68cbfJohan Hedberg}
35716dceb4c2f7a8ed91c88b1c1353b6bd5ccc68cbfJohan Hedberg
358ee6b2930a0519021232f92f615f6a8fd9cd61805Marcel Holtmanndbus_bool_t dbus_connection_register_interface(DBusConnection *connection,
35930957bc2890f3db99907178304046610e77c7efaJohan Hedberg					const char *path, const char *name,
360ee6b2930a0519021232f92f615f6a8fd9cd61805Marcel Holtmann					DBusMethodVTable *methods,
36130957bc2890f3db99907178304046610e77c7efaJohan Hedberg					DBusSignalVTable *signals,
362ee6b2930a0519021232f92f615f6a8fd9cd61805Marcel Holtmann					DBusPropertyVTable *properties)
363ee6b2930a0519021232f92f615f6a8fd9cd61805Marcel Holtmann{
364ee6b2930a0519021232f92f615f6a8fd9cd61805Marcel Holtmann	struct generic_data *data;
365f7c027662d2066b3862f41dbae3b68e5c1bafce7Marcel Holtmann	struct interface_data *iface;
366ee6b2930a0519021232f92f615f6a8fd9cd61805Marcel Holtmann
367ee6b2930a0519021232f92f615f6a8fd9cd61805Marcel Holtmann	if (dbus_connection_get_object_path_data(connection, path,
368ee6b2930a0519021232f92f615f6a8fd9cd61805Marcel Holtmann						(void *) &data) == FALSE)
369ee6b2930a0519021232f92f615f6a8fd9cd61805Marcel Holtmann		return FALSE;
370ee6b2930a0519021232f92f615f6a8fd9cd61805Marcel Holtmann
371d370964fbe6a9e32837037dcf193a216a0a75077Johan Hedberg	if (find_interface(data->interfaces, name))
372d370964fbe6a9e32837037dcf193a216a0a75077Johan Hedberg		return FALSE;
373d370964fbe6a9e32837037dcf193a216a0a75077Johan Hedberg
3743d16152fd30f2570ad8e9bb2427045e6fd317ce3Johan Hedberg	iface = g_new0(struct interface_data, 1);
375f7c027662d2066b3862f41dbae3b68e5c1bafce7Marcel Holtmann
37630957bc2890f3db99907178304046610e77c7efaJohan Hedberg	iface->name = g_strdup(name);
377f7c027662d2066b3862f41dbae3b68e5c1bafce7Marcel Holtmann	iface->methods = methods;
37830957bc2890f3db99907178304046610e77c7efaJohan Hedberg	iface->signals = signals;
37930957bc2890f3db99907178304046610e77c7efaJohan Hedberg	iface->properties = properties;
38030957bc2890f3db99907178304046610e77c7efaJohan Hedberg
381f7c027662d2066b3862f41dbae3b68e5c1bafce7Marcel Holtmann	data->interfaces = g_slist_append(data->interfaces, iface);
382ee6b2930a0519021232f92f615f6a8fd9cd61805Marcel Holtmann
3835cf1ae29510f5ec975080c793c692fedc10d86d8Johan Hedberg	update_introspection_data(connection, data, path);
384d370964fbe6a9e32837037dcf193a216a0a75077Johan Hedberg
385ee6b2930a0519021232f92f615f6a8fd9cd61805Marcel Holtmann	return TRUE;
386ee6b2930a0519021232f92f615f6a8fd9cd61805Marcel Holtmann}
387f7c027662d2066b3862f41dbae3b68e5c1bafce7Marcel Holtmann
388f7c027662d2066b3862f41dbae3b68e5c1bafce7Marcel Holtmanndbus_bool_t dbus_connection_unregister_interface(DBusConnection *connection,
38930957bc2890f3db99907178304046610e77c7efaJohan Hedberg					const char *path, const char *name)
390f7c027662d2066b3862f41dbae3b68e5c1bafce7Marcel Holtmann{
391d370964fbe6a9e32837037dcf193a216a0a75077Johan Hedberg	struct generic_data *data;
392d370964fbe6a9e32837037dcf193a216a0a75077Johan Hedberg	struct interface_data *iface;
393d370964fbe6a9e32837037dcf193a216a0a75077Johan Hedberg
394d370964fbe6a9e32837037dcf193a216a0a75077Johan Hedberg	if (dbus_connection_get_object_path_data(connection, path,
395d370964fbe6a9e32837037dcf193a216a0a75077Johan Hedberg						(void *) &data) == FALSE)
396d370964fbe6a9e32837037dcf193a216a0a75077Johan Hedberg		return FALSE;
397d370964fbe6a9e32837037dcf193a216a0a75077Johan Hedberg
398d370964fbe6a9e32837037dcf193a216a0a75077Johan Hedberg	iface = find_interface(data->interfaces, name);
399d370964fbe6a9e32837037dcf193a216a0a75077Johan Hedberg	if (!iface)
400d370964fbe6a9e32837037dcf193a216a0a75077Johan Hedberg		return FALSE;
401d370964fbe6a9e32837037dcf193a216a0a75077Johan Hedberg
402d370964fbe6a9e32837037dcf193a216a0a75077Johan Hedberg	data->interfaces = g_slist_remove(data->interfaces, iface);
403d370964fbe6a9e32837037dcf193a216a0a75077Johan Hedberg
404d370964fbe6a9e32837037dcf193a216a0a75077Johan Hedberg	g_free(iface->name);
405d370964fbe6a9e32837037dcf193a216a0a75077Johan Hedberg	g_free(iface);
406d370964fbe6a9e32837037dcf193a216a0a75077Johan Hedberg
4075cf1ae29510f5ec975080c793c692fedc10d86d8Johan Hedberg	update_introspection_data(connection, data, path);
408d370964fbe6a9e32837037dcf193a216a0a75077Johan Hedberg
409f7c027662d2066b3862f41dbae3b68e5c1bafce7Marcel Holtmann	return TRUE;
410f7c027662d2066b3862f41dbae3b68e5c1bafce7Marcel Holtmann}
41128a77bb7c841ce428071f6b6edd3539e1f8dc16aLuiz Augusto von Dentz
41228a77bb7c841ce428071f6b6edd3539e1f8dc16aLuiz Augusto von Dentzvoid dbus_message_iter_append_dict_entry(DBusMessageIter *dict,
41328a77bb7c841ce428071f6b6edd3539e1f8dc16aLuiz Augusto von Dentz					const char *key, int type, void *val)
41428a77bb7c841ce428071f6b6edd3539e1f8dc16aLuiz Augusto von Dentz{
41528a77bb7c841ce428071f6b6edd3539e1f8dc16aLuiz Augusto von Dentz	DBusMessageIter entry;
41628a77bb7c841ce428071f6b6edd3539e1f8dc16aLuiz Augusto von Dentz	DBusMessageIter value;
41728a77bb7c841ce428071f6b6edd3539e1f8dc16aLuiz Augusto von Dentz	char *sig;
41828a77bb7c841ce428071f6b6edd3539e1f8dc16aLuiz Augusto von Dentz
41928a77bb7c841ce428071f6b6edd3539e1f8dc16aLuiz Augusto von Dentz	dbus_message_iter_open_container(dict, DBUS_TYPE_DICT_ENTRY, NULL, &entry);
42028a77bb7c841ce428071f6b6edd3539e1f8dc16aLuiz Augusto von Dentz
42128a77bb7c841ce428071f6b6edd3539e1f8dc16aLuiz Augusto von Dentz	dbus_message_iter_append_basic(&entry, DBUS_TYPE_STRING, &key);
42228a77bb7c841ce428071f6b6edd3539e1f8dc16aLuiz Augusto von Dentz
42328a77bb7c841ce428071f6b6edd3539e1f8dc16aLuiz Augusto von Dentz	switch (type) {
42428a77bb7c841ce428071f6b6edd3539e1f8dc16aLuiz Augusto von Dentz	case DBUS_TYPE_STRING:
42528a77bb7c841ce428071f6b6edd3539e1f8dc16aLuiz Augusto von Dentz		sig = DBUS_TYPE_STRING_AS_STRING;
42628a77bb7c841ce428071f6b6edd3539e1f8dc16aLuiz Augusto von Dentz		break;
42728a77bb7c841ce428071f6b6edd3539e1f8dc16aLuiz Augusto von Dentz	case DBUS_TYPE_UINT32:
42828a77bb7c841ce428071f6b6edd3539e1f8dc16aLuiz Augusto von Dentz		sig = DBUS_TYPE_UINT32_AS_STRING;
42928a77bb7c841ce428071f6b6edd3539e1f8dc16aLuiz Augusto von Dentz		break;
43028a77bb7c841ce428071f6b6edd3539e1f8dc16aLuiz Augusto von Dentz	case DBUS_TYPE_BOOLEAN:
43128a77bb7c841ce428071f6b6edd3539e1f8dc16aLuiz Augusto von Dentz		sig = DBUS_TYPE_BOOLEAN_AS_STRING;
43228a77bb7c841ce428071f6b6edd3539e1f8dc16aLuiz Augusto von Dentz		break;
43328a77bb7c841ce428071f6b6edd3539e1f8dc16aLuiz Augusto von Dentz	default:
43428a77bb7c841ce428071f6b6edd3539e1f8dc16aLuiz Augusto von Dentz		sig = DBUS_TYPE_VARIANT_AS_STRING;
43528a77bb7c841ce428071f6b6edd3539e1f8dc16aLuiz Augusto von Dentz		break;
43628a77bb7c841ce428071f6b6edd3539e1f8dc16aLuiz Augusto von Dentz	}
43728a77bb7c841ce428071f6b6edd3539e1f8dc16aLuiz Augusto von Dentz
43828a77bb7c841ce428071f6b6edd3539e1f8dc16aLuiz Augusto von Dentz	dbus_message_iter_open_container(&entry, DBUS_TYPE_VARIANT, sig, &value);
43928a77bb7c841ce428071f6b6edd3539e1f8dc16aLuiz Augusto von Dentz
44028a77bb7c841ce428071f6b6edd3539e1f8dc16aLuiz Augusto von Dentz	dbus_message_iter_append_basic(&value, type, val);
44128a77bb7c841ce428071f6b6edd3539e1f8dc16aLuiz Augusto von Dentz
44228a77bb7c841ce428071f6b6edd3539e1f8dc16aLuiz Augusto von Dentz	dbus_message_iter_close_container(&entry, &value);
44328a77bb7c841ce428071f6b6edd3539e1f8dc16aLuiz Augusto von Dentz
44428a77bb7c841ce428071f6b6edd3539e1f8dc16aLuiz Augusto von Dentz	dbus_message_iter_close_container(dict, &entry);
44528a77bb7c841ce428071f6b6edd3539e1f8dc16aLuiz Augusto von Dentz}
446