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