upgrade obexd to 0.47
[profile/ivi/obexd.git] / client / dbus.c
1 /*
2  *
3  *  OBEX Client
4  *
5  *  Copyright (C) 2008-2011  Intel Corporation. All rights reserved.
6  *
7  *  This program is free software; you can redistribute it and/or modify
8  *  it under the terms of the GNU General Public License version 2 as
9  *  published by the Free Software Foundation.
10  *
11  *  This program is distributed in the hope that it will be useful,
12  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
13  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14  *  GNU General Public License for more details.
15  *
16  *  You should have received a copy of the GNU General Public License
17  *  along with this program; if not, write to the Free Software
18  *  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
19  *
20  */
21
22 #ifdef HAVE_CONFIG_H
23 #include <config.h>
24 #endif
25
26 #include <glib.h>
27 #include <gdbus.h>
28
29 #include "log.h"
30 #include "dbus.h"
31
32 static void append_variant(DBusMessageIter *iter,
33                                 int type, void *value)
34 {
35         char sig[2];
36         DBusMessageIter valueiter;
37
38         sig[0] = type;
39         sig[1] = 0;
40
41         dbus_message_iter_open_container(iter, DBUS_TYPE_VARIANT,
42                                                 sig, &valueiter);
43
44         dbus_message_iter_append_basic(&valueiter, type, value);
45
46         dbus_message_iter_close_container(iter, &valueiter);
47 }
48
49 void obex_dbus_dict_append(DBusMessageIter *dict,
50                         const char *key, int type, void *value)
51 {
52         DBusMessageIter keyiter;
53
54         if (type == DBUS_TYPE_STRING) {
55                 const char *str = *((const char **) value);
56                 if (str == NULL)
57                         return;
58         }
59
60         dbus_message_iter_open_container(dict, DBUS_TYPE_DICT_ENTRY,
61                                                         NULL, &keyiter);
62
63         dbus_message_iter_append_basic(&keyiter, DBUS_TYPE_STRING, &key);
64
65         append_variant(&keyiter, type, value);
66
67         dbus_message_iter_close_container(dict, &keyiter);
68 }
69
70 static void append_array_variant(DBusMessageIter *iter, int type, void *val)
71 {
72         DBusMessageIter variant, array;
73         char typesig[2];
74         char arraysig[3];
75         const char **str_array = *(const char ***) val;
76         int i;
77
78         arraysig[0] = DBUS_TYPE_ARRAY;
79         arraysig[1] = typesig[0] = type;
80         arraysig[2] = typesig[1] = '\0';
81
82         dbus_message_iter_open_container(iter, DBUS_TYPE_VARIANT,
83                                                 arraysig, &variant);
84
85         dbus_message_iter_open_container(&variant, DBUS_TYPE_ARRAY,
86                                                 typesig, &array);
87
88         for (i = 0; str_array[i]; i++)
89                 dbus_message_iter_append_basic(&array, type,
90                                                 &(str_array[i]));
91
92         dbus_message_iter_close_container(&variant, &array);
93
94         dbus_message_iter_close_container(iter, &variant);
95 }
96
97 void obex_dbus_dict_append_array(DBusMessageIter *dict, const char *key,
98                                 int type, void *val)
99 {
100         DBusMessageIter entry;
101
102         dbus_message_iter_open_container(dict, DBUS_TYPE_DICT_ENTRY,
103                                                 NULL, &entry);
104
105         dbus_message_iter_append_basic(&entry, DBUS_TYPE_STRING, &key);
106
107         append_array_variant(&entry, type, val);
108
109         dbus_message_iter_close_container(dict, &entry);
110 }
111
112 static void append_dict_variant(DBusMessageIter *iter, int type, void *val)
113 {
114         DBusMessageIter variant, array, entry;
115         char typesig[5];
116         char arraysig[6];
117         const void **val_array = *(const void ***) val;
118         int i;
119
120         arraysig[0] = DBUS_TYPE_ARRAY;
121         arraysig[1] = typesig[0] = DBUS_DICT_ENTRY_BEGIN_CHAR;
122         arraysig[2] = typesig[1] = DBUS_TYPE_STRING;
123         arraysig[3] = typesig[2] = type;
124         arraysig[4] = typesig[3] = DBUS_DICT_ENTRY_END_CHAR;
125         arraysig[5] = typesig[4] = '\0';
126
127         dbus_message_iter_open_container(iter, DBUS_TYPE_VARIANT,
128                                                 arraysig, &variant);
129
130         dbus_message_iter_open_container(&variant, DBUS_TYPE_ARRAY,
131                                                 typesig, &array);
132
133         for (i = 0; val_array[i]; i += 2) {
134                 dbus_message_iter_open_container(&array, DBUS_TYPE_DICT_ENTRY,
135                                                         NULL, &entry);
136
137                 dbus_message_iter_append_basic(&entry, DBUS_TYPE_STRING,
138                                                 &(val_array[i + 0]));
139
140                 /*
141                  * D-Bus expects a char** or uint8* depending on the type
142                  * given. Since we are dealing with an array through a void**
143                  * (and thus val_array[i] is a pointer) we need to
144                  * differentiate DBUS_TYPE_STRING from the others. The other
145                  * option would be the user to pass the exact type to this
146                  * function, instead of a pointer to it. However in this case
147                  * a cast from type to void* would be needed, which is not
148                  * good.
149                  */
150                 if (type == DBUS_TYPE_STRING) {
151                         dbus_message_iter_append_basic(&entry, type,
152                                                         &(val_array[i + 1]));
153                 } else {
154                         dbus_message_iter_append_basic(&entry, type,
155                                                         val_array[i + 1]);
156                 }
157
158                 dbus_message_iter_close_container(&array, &entry);
159         }
160
161         dbus_message_iter_close_container(&variant, &array);
162
163         dbus_message_iter_close_container(iter, &variant);
164 }
165
166 void obex_dbus_dict_append_dict(DBusMessageIter *dict, const char *key,
167                                 int type, void *val)
168 {
169         DBusMessageIter entry;
170
171         dbus_message_iter_open_container(dict, DBUS_TYPE_DICT_ENTRY,
172                                                 NULL, &entry);
173
174         dbus_message_iter_append_basic(&entry, DBUS_TYPE_STRING, &key);
175
176         append_dict_variant(&entry, type, val);
177
178         dbus_message_iter_close_container(dict, &entry);
179 }
180
181 int obex_dbus_signal_property_changed(DBusConnection *conn,
182                                         const char *path,
183                                         const char *interface,
184                                         const char *name,
185                                         int type, void *value)
186 {
187         DBusMessage *signal;
188         DBusMessageIter iter;
189
190         signal = dbus_message_new_signal(path, interface, "PropertyChanged");
191         if (signal == NULL) {
192                 error("Unable to allocate new %s.PropertyChanged signal",
193                                 interface);
194                 return -1;
195         }
196
197         dbus_message_iter_init_append(signal, &iter);
198
199         dbus_message_iter_append_basic(&iter, DBUS_TYPE_STRING, &name);
200
201         append_variant(&iter, type, value);
202
203         return g_dbus_send_message(conn, signal);
204 }
205
206 int obex_dbus_signal_array_property_changed(DBusConnection *conn,
207                                                 const char *path,
208                                                 const char *interface,
209                                                 const char *name,
210                                                 int type, void *value)
211
212 {
213         DBusMessage *signal;
214         DBusMessageIter iter;
215
216         signal = dbus_message_new_signal(path, interface, "PropertyChanged");
217         if (signal == NULL) {
218                 error("Unable to allocate new %s.PropertyChanged signal",
219                                 interface);
220                 return -1;
221         }
222
223         dbus_message_iter_init_append(signal, &iter);
224
225         dbus_message_iter_append_basic(&iter, DBUS_TYPE_STRING, &name);
226
227         append_array_variant(&iter, type, value);
228
229         return g_dbus_send_message(conn, signal);
230 }
231
232 int obex_dbus_signal_dict_property_changed(DBusConnection *conn,
233                                                 const char *path,
234                                                 const char *interface,
235                                                 const char *name,
236                                                 int type, void *value)
237
238 {
239         DBusMessage *signal;
240         DBusMessageIter iter;
241
242         signal = dbus_message_new_signal(path, interface, "PropertyChanged");
243         if (signal == NULL) {
244                 error("Unable to allocate new %s.PropertyChanged signal",
245                                 interface);
246                 return -1;
247         }
248
249         dbus_message_iter_init_append(signal, &iter);
250
251         dbus_message_iter_append_basic(&iter, DBUS_TYPE_STRING, &name);
252
253         append_dict_variant(&iter, type, value);
254
255         return g_dbus_send_message(conn, signal);
256 }