5 * Copyright (C) 2013 Intel Corporation. All rights reserved.
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; either version 2 of the License, or
10 * (at your option) any later version.
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
17 * You should have received a copy of the GNU General Public License
18 * along with this program; if not, write to the Free Software
19 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
28 #include "dbus_helpers.h"
30 #define TIMEOUT 120000
32 void __connmanctl_dbus_print(DBusMessageIter *iter, const char *pre,
33 const char *dict, const char *sep)
44 DBusMessageIter entry;
49 while ((arg_type = dbus_message_iter_get_arg_type(iter))
50 != DBUS_TYPE_INVALID) {
52 fprintf(stdout, "%s", pre);
55 case DBUS_TYPE_STRUCT:
56 fprintf(stdout, "{ ");
57 dbus_message_iter_recurse(iter, &entry);
58 __connmanctl_dbus_print(&entry, "", "=", " ");
59 fprintf(stdout, " }");
63 fprintf(stdout, "[ ");
65 dbus_message_iter_recurse(iter, &entry);
66 __connmanctl_dbus_print(&entry, "", "=", ", ");
68 fprintf(stdout, " ]");
71 case DBUS_TYPE_DICT_ENTRY:
73 dbus_message_iter_recurse(iter, &entry);
74 __connmanctl_dbus_print(&entry, "", dict, dict);
77 case DBUS_TYPE_STRING:
78 case DBUS_TYPE_OBJECT_PATH:
79 dbus_message_iter_get_basic(iter, &str);
80 fprintf(stdout, "%s", str);
83 case DBUS_TYPE_VARIANT:
84 dbus_message_iter_recurse(iter, &entry);
85 __connmanctl_dbus_print(&entry, pre, dict, sep);
88 case DBUS_TYPE_BOOLEAN:
89 dbus_message_iter_get_basic(iter, &b);
91 fprintf(stdout, "False");
93 fprintf(stdout, "True");
97 dbus_message_iter_get_basic(iter, &c);
98 fprintf(stdout, "%d", c);
101 case DBUS_TYPE_UINT16:
102 dbus_message_iter_get_basic(iter, &u16);
103 fprintf(stdout, "%u", u16);
106 case DBUS_TYPE_UINT32:
107 dbus_message_iter_get_basic(iter, &u);
108 fprintf(stdout, "%d", u);
111 case DBUS_TYPE_INT32:
112 dbus_message_iter_get_basic(iter, &i);
113 fprintf(stdout, "%d", i);
116 case DBUS_TYPE_DOUBLE:
117 dbus_message_iter_get_basic(iter, &d);
118 fprintf(stdout, "%f", d);
122 fprintf(stdout, "<type %c>", arg_type);
126 if (dbus_message_iter_has_next(iter))
127 fprintf(stdout, "%s", sep);
129 dbus_message_iter_next(iter);
133 struct dbus_callback {
134 connmanctl_dbus_method_return_func_t cb;
138 static void dbus_method_reply(DBusPendingCall *call, void *user_data)
140 struct dbus_callback *callback = user_data;
143 DBusMessageIter iter;
145 __connmanctl_save_rl();
147 reply = dbus_pending_call_steal_reply(call);
148 if (dbus_message_get_type(reply) == DBUS_MESSAGE_TYPE_ERROR) {
151 dbus_error_init(&err);
152 dbus_set_error_from_message(&err, reply);
154 callback->cb(NULL, err.message, callback->user_data);
156 dbus_error_free(&err);
160 dbus_message_iter_init(reply, &iter);
161 res = callback->cb(&iter, NULL, callback->user_data);
164 __connmanctl_redraw_rl();
165 if (__connmanctl_is_interactive() == false && res != -EINPROGRESS)
169 dbus_message_unref(reply);
172 static int send_method_call(DBusConnection *connection,
173 DBusMessage *message, connmanctl_dbus_method_return_func_t cb,
177 DBusPendingCall *call;
178 struct dbus_callback *callback;
180 if (!dbus_connection_send_with_reply(connection, message, &call, TIMEOUT))
187 callback = g_new0(struct dbus_callback, 1);
189 callback->user_data = user_data;
190 dbus_pending_call_set_notify(call, dbus_method_reply,
196 dbus_message_unref(message);
200 static int append_variant(DBusMessageIter *iter, const char *property,
201 int type, void *value)
203 DBusMessageIter variant;
207 case DBUS_TYPE_BOOLEAN:
208 type_str = DBUS_TYPE_BOOLEAN_AS_STRING;
211 type_str = DBUS_TYPE_BYTE_AS_STRING;
213 case DBUS_TYPE_STRING:
214 type_str = DBUS_TYPE_STRING_AS_STRING;
216 case DBUS_TYPE_INT32:
217 type_str = DBUS_TYPE_INT32_AS_STRING;
223 dbus_message_iter_append_basic(iter, DBUS_TYPE_STRING, &property);
224 dbus_message_iter_open_container(iter, DBUS_TYPE_VARIANT, type_str,
226 dbus_message_iter_append_basic(&variant, type, value);
227 dbus_message_iter_close_container(iter, &variant);
232 int __connmanctl_dbus_method_call(DBusConnection *connection,
233 const char *service, const char *path, const char *interface,
234 const char *method, connmanctl_dbus_method_return_func_t cb,
235 void *user_data, connmanctl_dbus_append_func_t append_func,
238 DBusMessage *message;
239 DBusMessageIter iter;
241 message = dbus_message_new_method_call(service, path, interface,
248 dbus_message_iter_init_append(message, &iter);
249 append_func(&iter, append_data);
252 return send_method_call(connection, message, cb, user_data);
255 int __connmanctl_dbus_set_property(DBusConnection *connection,
256 const char *path, const char *interface,
257 connmanctl_dbus_method_return_func_t cb, void * user_data,
258 const char *property, int type, void *value)
260 DBusMessage *message;
261 DBusMessageIter iter;
263 message = dbus_message_new_method_call("net.connman", path,
264 interface, "SetProperty");
269 dbus_message_iter_init_append(message, &iter);
271 if (append_variant(&iter, property, type, value) < 0) {
272 dbus_message_unref(message);
276 return send_method_call(connection, message, cb, user_data);
279 void __connmanctl_dbus_append_dict(DBusMessageIter *iter,
280 connmanctl_dbus_append_func_t append_fn, void *append_data)
282 DBusMessageIter dict;
284 dbus_message_iter_open_container(iter, DBUS_TYPE_ARRAY,
285 DBUS_DICT_ENTRY_BEGIN_CHAR_AS_STRING
286 DBUS_TYPE_STRING_AS_STRING DBUS_TYPE_VARIANT_AS_STRING
287 DBUS_DICT_ENTRY_END_CHAR_AS_STRING, &dict);
290 append_fn(&dict, append_data);
292 dbus_message_iter_close_container(iter, &dict);
295 void __connmanctl_dbus_append_dict_entry(DBusMessageIter *iter,
296 const char *property, int type, void *value)
298 DBusMessageIter dict_entry;
300 dbus_message_iter_open_container(iter, DBUS_TYPE_DICT_ENTRY, NULL,
303 append_variant(&dict_entry, property, type, value);
305 dbus_message_iter_close_container(iter, &dict_entry);
308 int __connmanctl_dbus_set_property_dict(DBusConnection *connection,
309 const char *path, const char *interface,
310 connmanctl_dbus_method_return_func_t cb, void *user_data,
311 const char *property, int type,
312 connmanctl_dbus_append_func_t append_fn,
313 void *append_user_data)
315 DBusMessage *message;
316 DBusMessageIter iter, variant, dict;
318 message = dbus_message_new_method_call("net.connman", path,
319 interface, "SetProperty");
324 dbus_message_iter_init_append(message, &iter);
325 dbus_message_iter_append_basic(&iter, DBUS_TYPE_STRING, &property);
326 dbus_message_iter_open_container(&iter, DBUS_TYPE_VARIANT,
327 DBUS_TYPE_ARRAY_AS_STRING
328 DBUS_DICT_ENTRY_BEGIN_CHAR_AS_STRING
329 DBUS_TYPE_STRING_AS_STRING
330 DBUS_TYPE_VARIANT_AS_STRING
331 DBUS_DICT_ENTRY_END_CHAR_AS_STRING,
334 dbus_message_iter_open_container(&variant, DBUS_TYPE_ARRAY,
335 DBUS_DICT_ENTRY_BEGIN_CHAR_AS_STRING
336 DBUS_TYPE_STRING_AS_STRING
337 DBUS_TYPE_VARIANT_AS_STRING
338 DBUS_DICT_ENTRY_END_CHAR_AS_STRING,
341 append_fn(&dict, append_user_data);
343 dbus_message_iter_close_container(&variant, &dict);
344 dbus_message_iter_close_container(&iter, &variant);
346 return send_method_call(connection, message, cb, user_data);
349 static void append_variant_array(DBusMessageIter *iter, const char *property,
350 connmanctl_dbus_append_func_t append_fn,
351 void *append_user_data)
353 DBusMessageIter variant, array;
355 dbus_message_iter_append_basic(iter, DBUS_TYPE_STRING, &property);
356 dbus_message_iter_open_container(iter, DBUS_TYPE_VARIANT,
357 DBUS_TYPE_ARRAY_AS_STRING
358 DBUS_TYPE_STRING_AS_STRING,
361 dbus_message_iter_open_container(&variant, DBUS_TYPE_ARRAY,
362 DBUS_TYPE_STRING_AS_STRING, &array);
364 append_fn(&array, append_user_data);
366 dbus_message_iter_close_container(&variant, &array);
367 dbus_message_iter_close_container(iter, &variant);
370 void __connmanctl_dbus_append_dict_string_array(DBusMessageIter *iter,
371 const char *property, connmanctl_dbus_append_func_t append_fn,
372 void *append_user_data)
374 DBusMessageIter dict_entry;
376 dbus_message_iter_open_container(iter, DBUS_TYPE_DICT_ENTRY, NULL,
379 append_variant_array(&dict_entry, property, append_fn,
382 dbus_message_iter_close_container(iter, &dict_entry);
385 int __connmanctl_dbus_set_property_array(DBusConnection *connection,
386 const char *path, const char *interface,
387 connmanctl_dbus_method_return_func_t cb, void *user_data,
388 const char *property, int type,
389 connmanctl_dbus_append_func_t append_fn,
390 void *append_user_data)
392 DBusMessage *message;
393 DBusMessageIter iter;
395 if (type != DBUS_TYPE_STRING)
398 message = dbus_message_new_method_call("net.connman", path,
399 interface, "SetProperty");
404 dbus_message_iter_init_append(message, &iter);
406 append_variant_array(&iter, property, append_fn, append_user_data);
408 return send_method_call(connection, message, cb, user_data);
411 int __connmanctl_dbus_session_change(DBusConnection *connection,
412 const char *session_path,
413 connmanctl_dbus_method_return_func_t cb, void * user_data,
414 const char *property, int type, void *value)
416 DBusMessage *message;
417 DBusMessageIter iter;
419 message = dbus_message_new_method_call("net.connman", session_path,
420 "net.connman.Session", "Change");
425 dbus_message_iter_init_append(message, &iter);
427 if (append_variant(&iter, property, type, value) < 0) {
428 dbus_message_unref(message);
432 return send_method_call(connection, message, cb, user_data);
435 int __connmanctl_dbus_session_change_array(DBusConnection *connection,
436 const char *session_path,
437 connmanctl_dbus_method_return_func_t cb, void *user_data,
438 const char *property,
439 connmanctl_dbus_append_func_t append_fn,
440 void *append_user_data)
442 DBusMessage *message;
443 DBusMessageIter iter;
445 message = dbus_message_new_method_call("net.connman", session_path,
446 "net.connman.Session", "Change");
451 dbus_message_iter_init_append(message, &iter);
453 append_variant_array(&iter, property, append_fn, append_user_data);
455 return send_method_call(connection, message, cb, user_data);