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
29 #include "dbus_helpers.h"
31 #define TIMEOUT 120000
33 #ifndef DBUS_ERROR_UNKNOWN_METHOD
34 #define DBUS_ERROR_UNKNOWN_METHOD "org.freedesktop.DBus.Error.UnknownMethod"
37 #ifndef DBUS_ERROR_UNKNOWN_PROPERTY
38 #define DBUS_ERROR_UNKNOWN_PROPERTY "org.freedesktop.DBus.Error.UnknownProperty"
41 #ifndef DBUS_ERROR_UNKNOWN_OBJECT
42 #define DBUS_ERROR_UNKNOWN_OBJECT "org.freedesktop.DBus.Error.UnknownObject"
45 static int string2errno(const char *error)
47 if (!g_strcmp0(error, DBUS_ERROR_UNKNOWN_METHOD))
49 if (!g_strcmp0(error, DBUS_ERROR_UNKNOWN_PROPERTY))
51 if (!g_strcmp0(error, DBUS_ERROR_UNKNOWN_OBJECT))
53 if (!g_strcmp0(error, "net.connman.Error.AlreadyEnabled"))
55 if (!g_strcmp0(error, "net.connman.Error.AlreadyDisabled"))
61 void __connmanctl_dbus_print(DBusMessageIter *iter, const char *pre,
62 const char *dict, const char *sep)
74 DBusMessageIter entry;
79 while ((arg_type = dbus_message_iter_get_arg_type(iter))
80 != DBUS_TYPE_INVALID) {
82 fprintf(stdout, "%s", pre);
85 case DBUS_TYPE_STRUCT:
86 fprintf(stdout, "{ ");
87 dbus_message_iter_recurse(iter, &entry);
88 __connmanctl_dbus_print(&entry, "", "=", " ");
89 fprintf(stdout, " }");
93 fprintf(stdout, "[ ");
95 dbus_message_iter_recurse(iter, &entry);
96 __connmanctl_dbus_print(&entry, "", "=", ", ");
98 fprintf(stdout, " ]");
101 case DBUS_TYPE_DICT_ENTRY:
103 dbus_message_iter_recurse(iter, &entry);
104 __connmanctl_dbus_print(&entry, "", dict, dict);
107 case DBUS_TYPE_STRING:
108 case DBUS_TYPE_OBJECT_PATH:
109 dbus_message_iter_get_basic(iter, &str);
110 fprintf(stdout, "%s", str);
113 case DBUS_TYPE_VARIANT:
114 dbus_message_iter_recurse(iter, &entry);
115 __connmanctl_dbus_print(&entry, pre, dict, sep);
118 case DBUS_TYPE_BOOLEAN:
119 dbus_message_iter_get_basic(iter, &b);
121 fprintf(stdout, "False");
123 fprintf(stdout, "True");
127 dbus_message_iter_get_basic(iter, &c);
128 fprintf(stdout, "%d", c);
131 case DBUS_TYPE_UINT16:
132 dbus_message_iter_get_basic(iter, &u16);
133 fprintf(stdout, "%u", u16);
136 case DBUS_TYPE_UINT32:
137 dbus_message_iter_get_basic(iter, &u);
138 fprintf(stdout, "%d", u);
141 case DBUS_TYPE_INT32:
142 dbus_message_iter_get_basic(iter, &i);
143 fprintf(stdout, "%d", i);
146 case DBUS_TYPE_UINT64:
147 dbus_message_iter_get_basic(iter, &u64);
148 fprintf(stdout, "%"PRIu64, u64);
151 case DBUS_TYPE_DOUBLE:
152 dbus_message_iter_get_basic(iter, &d);
153 fprintf(stdout, "%f", d);
157 fprintf(stdout, "<type %c>", arg_type);
161 if (dbus_message_iter_has_next(iter))
162 fprintf(stdout, "%s", sep);
164 dbus_message_iter_next(iter);
168 struct dbus_callback {
169 connmanctl_dbus_method_return_func_t cb;
173 static void dbus_method_reply(DBusPendingCall *call, void *user_data)
175 struct dbus_callback *callback = user_data;
178 DBusMessageIter iter;
180 __connmanctl_save_rl();
182 reply = dbus_pending_call_steal_reply(call);
183 dbus_pending_call_unref(call);
184 if (dbus_message_get_type(reply) == DBUS_MESSAGE_TYPE_ERROR) {
187 dbus_error_init(&err);
188 dbus_set_error_from_message(&err, reply);
190 callback->cb(NULL, string2errno(err.name), err.message,
191 callback->user_data);
193 dbus_error_free(&err);
197 dbus_message_iter_init(reply, &iter);
198 res = callback->cb(&iter, 0, NULL, callback->user_data);
201 __connmanctl_redraw_rl();
202 if (__connmanctl_is_interactive() == false && res != -EINPROGRESS)
206 dbus_message_unref(reply);
209 static int send_method_call(DBusConnection *connection,
210 DBusMessage *message, connmanctl_dbus_method_return_func_t cb,
214 DBusPendingCall *call;
215 struct dbus_callback *callback;
217 if (!dbus_connection_send_with_reply(connection, message, &call, TIMEOUT))
224 callback = g_new0(struct dbus_callback, 1);
226 callback->user_data = user_data;
227 dbus_pending_call_set_notify(call, dbus_method_reply,
233 dbus_message_unref(message);
237 static int append_variant(DBusMessageIter *iter, const char *property,
238 int type, void *value)
240 DBusMessageIter variant;
244 case DBUS_TYPE_BOOLEAN:
245 type_str = DBUS_TYPE_BOOLEAN_AS_STRING;
248 type_str = DBUS_TYPE_BYTE_AS_STRING;
250 case DBUS_TYPE_STRING:
251 type_str = DBUS_TYPE_STRING_AS_STRING;
253 case DBUS_TYPE_INT32:
254 type_str = DBUS_TYPE_INT32_AS_STRING;
256 #if defined TIZEN_EXT_WIFI_MESH
257 case DBUS_TYPE_UINT16:
258 type_str = DBUS_TYPE_UINT16_AS_STRING;
265 dbus_message_iter_append_basic(iter, DBUS_TYPE_STRING, &property);
266 dbus_message_iter_open_container(iter, DBUS_TYPE_VARIANT, type_str,
268 dbus_message_iter_append_basic(&variant, type, value);
269 dbus_message_iter_close_container(iter, &variant);
274 int __connmanctl_dbus_method_call(DBusConnection *connection,
275 const char *service, const char *path, const char *interface,
276 const char *method, connmanctl_dbus_method_return_func_t cb,
277 void *user_data, connmanctl_dbus_append_func_t append_func,
280 DBusMessage *message;
281 DBusMessageIter iter;
283 message = dbus_message_new_method_call(service, path, interface,
290 dbus_message_iter_init_append(message, &iter);
291 append_func(&iter, append_data);
294 return send_method_call(connection, message, cb, user_data);
297 int __connmanctl_dbus_set_property(DBusConnection *connection,
298 const char *path, const char *interface,
299 connmanctl_dbus_method_return_func_t cb, void * user_data,
300 const char *property, int type, void *value)
302 DBusMessage *message;
303 DBusMessageIter iter;
305 message = dbus_message_new_method_call("net.connman", path,
306 interface, "SetProperty");
311 dbus_message_iter_init_append(message, &iter);
313 if (append_variant(&iter, property, type, value) < 0) {
314 dbus_message_unref(message);
318 return send_method_call(connection, message, cb, user_data);
321 void __connmanctl_dbus_append_dict(DBusMessageIter *iter,
322 connmanctl_dbus_append_func_t append_fn, void *append_data)
324 DBusMessageIter dict;
326 dbus_message_iter_open_container(iter, DBUS_TYPE_ARRAY,
327 DBUS_DICT_ENTRY_BEGIN_CHAR_AS_STRING
328 DBUS_TYPE_STRING_AS_STRING DBUS_TYPE_VARIANT_AS_STRING
329 DBUS_DICT_ENTRY_END_CHAR_AS_STRING, &dict);
332 append_fn(&dict, append_data);
334 dbus_message_iter_close_container(iter, &dict);
337 void __connmanctl_dbus_append_dict_entry(DBusMessageIter *iter,
338 const char *property, int type, void *value)
340 DBusMessageIter dict_entry;
342 dbus_message_iter_open_container(iter, DBUS_TYPE_DICT_ENTRY, NULL,
345 append_variant(&dict_entry, property, type, value);
347 dbus_message_iter_close_container(iter, &dict_entry);
350 int __connmanctl_dbus_set_property_dict(DBusConnection *connection,
351 const char *path, const char *interface,
352 connmanctl_dbus_method_return_func_t cb, void *user_data,
353 const char *property, int type,
354 connmanctl_dbus_append_func_t append_fn,
355 void *append_user_data)
357 DBusMessage *message;
358 DBusMessageIter iter, variant, dict;
360 message = dbus_message_new_method_call("net.connman", path,
361 interface, "SetProperty");
366 dbus_message_iter_init_append(message, &iter);
367 dbus_message_iter_append_basic(&iter, DBUS_TYPE_STRING, &property);
368 dbus_message_iter_open_container(&iter, DBUS_TYPE_VARIANT,
369 DBUS_TYPE_ARRAY_AS_STRING
370 DBUS_DICT_ENTRY_BEGIN_CHAR_AS_STRING
371 DBUS_TYPE_STRING_AS_STRING
372 DBUS_TYPE_VARIANT_AS_STRING
373 DBUS_DICT_ENTRY_END_CHAR_AS_STRING,
376 dbus_message_iter_open_container(&variant, DBUS_TYPE_ARRAY,
377 DBUS_DICT_ENTRY_BEGIN_CHAR_AS_STRING
378 DBUS_TYPE_STRING_AS_STRING
379 DBUS_TYPE_VARIANT_AS_STRING
380 DBUS_DICT_ENTRY_END_CHAR_AS_STRING,
383 append_fn(&dict, append_user_data);
385 dbus_message_iter_close_container(&variant, &dict);
386 dbus_message_iter_close_container(&iter, &variant);
388 return send_method_call(connection, message, cb, user_data);
391 #if defined TIZEN_EXT_WIFI_MESH
392 int __connmanctl_dbus_mesh_dict(DBusConnection *connection,
393 const char *path, const char *interface,
394 connmanctl_dbus_method_return_func_t cb, void *user_data,
395 const char *property, int type,
396 connmanctl_dbus_append_func_t append_fn,
397 void *append_user_data)
399 DBusMessage *message;
400 DBusMessageIter iter, variant, dict;
402 message = dbus_message_new_method_call(CONNMAN_SERVICE, path,
403 interface, "MeshCommands");
408 dbus_message_iter_init_append(message, &iter);
409 dbus_message_iter_append_basic(&iter, DBUS_TYPE_STRING, &property);
410 dbus_message_iter_open_container(&iter, DBUS_TYPE_VARIANT,
411 DBUS_TYPE_ARRAY_AS_STRING
412 DBUS_DICT_ENTRY_BEGIN_CHAR_AS_STRING
413 DBUS_TYPE_STRING_AS_STRING
414 DBUS_TYPE_VARIANT_AS_STRING
415 DBUS_DICT_ENTRY_END_CHAR_AS_STRING,
418 dbus_message_iter_open_container(&variant, DBUS_TYPE_ARRAY,
419 DBUS_DICT_ENTRY_BEGIN_CHAR_AS_STRING
420 DBUS_TYPE_STRING_AS_STRING
421 DBUS_TYPE_VARIANT_AS_STRING
422 DBUS_DICT_ENTRY_END_CHAR_AS_STRING,
426 append_fn(&dict, append_user_data);
428 dbus_message_iter_close_container(&variant, &dict);
429 dbus_message_iter_close_container(&iter, &variant);
431 return send_method_call(connection, message, cb, user_data);
435 static void append_variant_array(DBusMessageIter *iter, const char *property,
436 connmanctl_dbus_append_func_t append_fn,
437 void *append_user_data)
439 DBusMessageIter variant, array;
441 dbus_message_iter_append_basic(iter, DBUS_TYPE_STRING, &property);
442 dbus_message_iter_open_container(iter, DBUS_TYPE_VARIANT,
443 DBUS_TYPE_ARRAY_AS_STRING
444 DBUS_TYPE_STRING_AS_STRING,
447 dbus_message_iter_open_container(&variant, DBUS_TYPE_ARRAY,
448 DBUS_TYPE_STRING_AS_STRING, &array);
450 append_fn(&array, append_user_data);
452 dbus_message_iter_close_container(&variant, &array);
453 dbus_message_iter_close_container(iter, &variant);
456 void __connmanctl_dbus_append_dict_string_array(DBusMessageIter *iter,
457 const char *property, connmanctl_dbus_append_func_t append_fn,
458 void *append_user_data)
460 DBusMessageIter dict_entry;
462 dbus_message_iter_open_container(iter, DBUS_TYPE_DICT_ENTRY, NULL,
465 append_variant_array(&dict_entry, property, append_fn,
468 dbus_message_iter_close_container(iter, &dict_entry);
471 int __connmanctl_dbus_set_property_array(DBusConnection *connection,
472 const char *path, const char *interface,
473 connmanctl_dbus_method_return_func_t cb, void *user_data,
474 const char *property, int type,
475 connmanctl_dbus_append_func_t append_fn,
476 void *append_user_data)
478 DBusMessage *message;
479 DBusMessageIter iter;
481 if (type != DBUS_TYPE_STRING)
484 message = dbus_message_new_method_call("net.connman", path,
485 interface, "SetProperty");
490 dbus_message_iter_init_append(message, &iter);
492 append_variant_array(&iter, property, append_fn, append_user_data);
494 return send_method_call(connection, message, cb, user_data);
497 int __connmanctl_dbus_session_change(DBusConnection *connection,
498 const char *session_path,
499 connmanctl_dbus_method_return_func_t cb, void * user_data,
500 const char *property, int type, void *value)
502 DBusMessage *message;
503 DBusMessageIter iter;
505 message = dbus_message_new_method_call("net.connman", session_path,
506 "net.connman.Session", "Change");
511 dbus_message_iter_init_append(message, &iter);
513 if (append_variant(&iter, property, type, value) < 0) {
514 dbus_message_unref(message);
518 return send_method_call(connection, message, cb, user_data);
521 int __connmanctl_dbus_session_change_array(DBusConnection *connection,
522 const char *session_path,
523 connmanctl_dbus_method_return_func_t cb, void *user_data,
524 const char *property,
525 connmanctl_dbus_append_func_t append_fn,
526 void *append_user_data)
528 DBusMessage *message;
529 DBusMessageIter iter;
531 message = dbus_message_new_method_call("net.connman", session_path,
532 "net.connman.Session", "Change");
537 dbus_message_iter_init_append(message, &iter);
539 append_variant_array(&iter, property, append_fn, append_user_data);
541 return send_method_call(connection, message, cb, user_data);