3 * WPA supplicant library with GLib integration
5 * Copyright (C) 2012 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 version 2 as
9 * published by the Free Software Foundation.
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.
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
29 #include <dbus/dbus.h>
35 static DBusConnection *connection;
37 void supplicant_dbus_setup(DBusConnection *conn)
42 void supplicant_dbus_array_foreach(DBusMessageIter *iter,
43 supplicant_dbus_array_function function,
46 DBusMessageIter entry;
48 if (dbus_message_iter_get_arg_type(iter) != DBUS_TYPE_ARRAY)
51 dbus_message_iter_recurse(iter, &entry);
53 while (dbus_message_iter_get_arg_type(&entry) != DBUS_TYPE_INVALID) {
55 function(&entry, user_data);
57 dbus_message_iter_next(&entry);
61 void supplicant_dbus_property_foreach(DBusMessageIter *iter,
62 supplicant_dbus_property_function function,
67 if (dbus_message_iter_get_arg_type(iter) != DBUS_TYPE_ARRAY)
70 dbus_message_iter_recurse(iter, &dict);
72 while (dbus_message_iter_get_arg_type(&dict) == DBUS_TYPE_DICT_ENTRY) {
73 DBusMessageIter entry, value;
76 dbus_message_iter_recurse(&dict, &entry);
78 if (dbus_message_iter_get_arg_type(&entry) != DBUS_TYPE_STRING)
81 dbus_message_iter_get_basic(&entry, &key);
82 dbus_message_iter_next(&entry);
84 if (dbus_message_iter_get_arg_type(&entry) != DBUS_TYPE_VARIANT)
87 dbus_message_iter_recurse(&entry, &value);
90 if (strcmp(key, "Properties") == 0)
91 supplicant_dbus_property_foreach(&value,
93 else if (function != NULL)
94 function(key, &value, user_data);
97 dbus_message_iter_next(&dict);
101 struct property_get_data {
102 supplicant_dbus_property_function function;
106 static void property_get_all_reply(DBusPendingCall *call, void *user_data)
108 struct property_get_data *data = user_data;
110 DBusMessageIter iter;
112 reply = dbus_pending_call_steal_reply(call);
114 if (dbus_message_get_type(reply) == DBUS_MESSAGE_TYPE_ERROR)
117 if (dbus_message_iter_init(reply, &iter) == FALSE)
120 supplicant_dbus_property_foreach(&iter, data->function,
123 if (data->function != NULL)
124 data->function(NULL, NULL, data->user_data);
127 dbus_message_unref(reply);
129 dbus_pending_call_unref(call);
132 int supplicant_dbus_property_get_all(const char *path, const char *interface,
133 supplicant_dbus_property_function function,
136 struct property_get_data *data;
137 DBusMessage *message;
138 DBusPendingCall *call;
140 if (connection == NULL)
143 if (path == NULL || interface == NULL)
146 data = dbus_malloc0(sizeof(*data));
150 message = dbus_message_new_method_call(SUPPLICANT_SERVICE, path,
151 DBUS_INTERFACE_PROPERTIES, "GetAll");
152 if (message == NULL) {
157 dbus_message_set_auto_start(message, FALSE);
159 dbus_message_append_args(message, DBUS_TYPE_STRING, &interface, NULL);
161 if (dbus_connection_send_with_reply(connection, message,
162 &call, TIMEOUT) == FALSE) {
163 dbus_message_unref(message);
169 dbus_message_unref(message);
174 data->function = function;
175 data->user_data = user_data;
177 dbus_pending_call_set_notify(call, property_get_all_reply,
180 dbus_message_unref(message);
185 static void property_get_reply(DBusPendingCall *call, void *user_data)
187 struct property_get_data *data = user_data;
189 DBusMessageIter iter;
191 reply = dbus_pending_call_steal_reply(call);
193 if (dbus_message_get_type(reply) == DBUS_MESSAGE_TYPE_ERROR)
196 if (dbus_message_iter_init(reply, &iter) == FALSE)
199 if (dbus_message_iter_get_arg_type(&iter) == DBUS_TYPE_VARIANT) {
200 DBusMessageIter variant;
202 dbus_message_iter_recurse(&iter, &variant);
204 if (data->function != NULL)
205 data->function(NULL, &variant, data->user_data);
208 dbus_message_unref(reply);
210 dbus_pending_call_unref(call);
213 int supplicant_dbus_property_get(const char *path, const char *interface,
215 supplicant_dbus_property_function function,
218 struct property_get_data *data;
219 DBusMessage *message;
220 DBusPendingCall *call;
222 if (connection == NULL)
225 if (path == NULL || interface == NULL || method == NULL)
228 data = dbus_malloc0(sizeof(*data));
232 message = dbus_message_new_method_call(SUPPLICANT_SERVICE, path,
233 DBUS_INTERFACE_PROPERTIES, "Get");
235 if (message == NULL) {
240 dbus_message_set_auto_start(message, FALSE);
242 dbus_message_append_args(message, DBUS_TYPE_STRING, &interface,
243 DBUS_TYPE_STRING, &method, NULL);
245 if (dbus_connection_send_with_reply(connection, message,
246 &call, TIMEOUT) == FALSE) {
247 dbus_message_unref(message);
253 dbus_message_unref(message);
258 data->function = function;
259 data->user_data = user_data;
261 dbus_pending_call_set_notify(call, property_get_reply,
264 dbus_message_unref(message);
269 struct property_set_data {
270 supplicant_dbus_result_function function;
274 static void property_set_reply(DBusPendingCall *call, void *user_data)
276 struct property_set_data *data = user_data;
278 DBusMessageIter iter;
281 reply = dbus_pending_call_steal_reply(call);
283 if (dbus_message_get_type(reply) == DBUS_MESSAGE_TYPE_ERROR)
284 error = dbus_message_get_error_name(reply);
288 dbus_message_iter_init(reply, &iter);
290 if (data->function != NULL)
291 data->function(error, &iter, data->user_data);
293 dbus_message_unref(reply);
295 dbus_pending_call_unref(call);
298 int supplicant_dbus_property_set(const char *path, const char *interface,
299 const char *key, const char *signature,
300 supplicant_dbus_setup_function setup,
301 supplicant_dbus_result_function function,
304 struct property_set_data *data;
305 DBusMessage *message;
306 DBusMessageIter iter, value;
307 DBusPendingCall *call;
309 if (connection == NULL)
312 if (path == NULL || interface == NULL)
315 if (key == NULL || signature == NULL || setup == NULL)
318 data = dbus_malloc0(sizeof(*data));
322 message = dbus_message_new_method_call(SUPPLICANT_SERVICE, path,
323 DBUS_INTERFACE_PROPERTIES, "Set");
324 if (message == NULL) {
329 dbus_message_set_auto_start(message, FALSE);
331 dbus_message_iter_init_append(message, &iter);
332 dbus_message_iter_append_basic(&iter, DBUS_TYPE_STRING, &interface);
333 dbus_message_iter_append_basic(&iter, DBUS_TYPE_STRING, &key);
335 dbus_message_iter_open_container(&iter, DBUS_TYPE_VARIANT,
337 setup(&value, user_data);
338 dbus_message_iter_close_container(&iter, &value);
340 if (dbus_connection_send_with_reply(connection, message,
341 &call, TIMEOUT) == FALSE) {
342 dbus_message_unref(message);
348 dbus_message_unref(message);
353 data->function = function;
354 data->user_data = user_data;
356 dbus_pending_call_set_notify(call, property_set_reply,
359 dbus_message_unref(message);
364 struct method_call_data {
365 supplicant_dbus_result_function function;
369 static void method_call_reply(DBusPendingCall *call, void *user_data)
371 struct method_call_data *data = user_data;
373 DBusMessageIter iter;
376 reply = dbus_pending_call_steal_reply(call);
378 if (dbus_message_get_type(reply) == DBUS_MESSAGE_TYPE_ERROR)
379 error = dbus_message_get_error_name(reply);
383 dbus_message_iter_init(reply, &iter);
385 if (data->function != NULL)
386 data->function(error, &iter, data->user_data);
388 dbus_message_unref(reply);
390 dbus_pending_call_unref(call);
393 int supplicant_dbus_method_call(const char *path,
394 const char *interface, const char *method,
395 supplicant_dbus_setup_function setup,
396 supplicant_dbus_result_function function,
399 struct method_call_data *data;
400 DBusMessage *message;
401 DBusMessageIter iter;
402 DBusPendingCall *call;
404 if (connection == NULL)
407 if (path == NULL || interface == NULL || method == NULL)
410 data = dbus_malloc0(sizeof(*data));
414 message = dbus_message_new_method_call(SUPPLICANT_SERVICE, path,
416 if (message == NULL) {
421 dbus_message_set_auto_start(message, FALSE);
423 dbus_message_iter_init_append(message, &iter);
425 setup(&iter, user_data);
427 if (dbus_connection_send_with_reply(connection, message,
428 &call, TIMEOUT) == FALSE) {
429 dbus_message_unref(message);
435 dbus_message_unref(message);
440 data->function = function;
441 data->user_data = user_data;
443 dbus_pending_call_set_notify(call, method_call_reply,
446 dbus_message_unref(message);
451 void supplicant_dbus_property_append_basic(DBusMessageIter *iter,
452 const char *key, int type, void *val)
454 DBusMessageIter value;
455 const char *signature;
457 dbus_message_iter_append_basic(iter, DBUS_TYPE_STRING, &key);
460 case DBUS_TYPE_BOOLEAN:
461 signature = DBUS_TYPE_BOOLEAN_AS_STRING;
463 case DBUS_TYPE_STRING:
464 signature = DBUS_TYPE_STRING_AS_STRING;
467 signature = DBUS_TYPE_BYTE_AS_STRING;
469 case DBUS_TYPE_UINT16:
470 signature = DBUS_TYPE_UINT16_AS_STRING;
472 case DBUS_TYPE_INT16:
473 signature = DBUS_TYPE_INT16_AS_STRING;
475 case DBUS_TYPE_UINT32:
476 signature = DBUS_TYPE_UINT32_AS_STRING;
478 case DBUS_TYPE_INT32:
479 signature = DBUS_TYPE_INT32_AS_STRING;
481 case DBUS_TYPE_OBJECT_PATH:
482 signature = DBUS_TYPE_OBJECT_PATH_AS_STRING;
485 signature = DBUS_TYPE_VARIANT_AS_STRING;
489 dbus_message_iter_open_container(iter, DBUS_TYPE_VARIANT,
491 dbus_message_iter_append_basic(&value, type, val);
492 dbus_message_iter_close_container(iter, &value);
495 void supplicant_dbus_property_append_fixed_array(DBusMessageIter *iter,
496 const char *key, int type, void *val, int len)
498 DBusMessageIter value, array;
499 const char *variant_sig, *array_sig;
503 variant_sig = DBUS_TYPE_ARRAY_AS_STRING
504 DBUS_TYPE_BYTE_AS_STRING;
505 array_sig = DBUS_TYPE_BYTE_AS_STRING;
511 dbus_message_iter_append_basic(iter, DBUS_TYPE_STRING, &key);
513 dbus_message_iter_open_container(iter, DBUS_TYPE_VARIANT,
514 variant_sig, &value);
516 dbus_message_iter_open_container(&value, DBUS_TYPE_ARRAY,
518 dbus_message_iter_append_fixed_array(&array, type, val, len);
519 dbus_message_iter_close_container(&value, &array);
521 dbus_message_iter_close_container(iter, &value);
524 void supplicant_dbus_property_append_array(DBusMessageIter *iter,
525 const char *key, int type,
526 supplicant_dbus_array_function function,
529 DBusMessageIter value, array;
530 const char *variant_sig, *array_sig;
533 case DBUS_TYPE_STRING:
534 variant_sig = DBUS_TYPE_ARRAY_AS_STRING
535 DBUS_TYPE_ARRAY_AS_STRING
536 DBUS_TYPE_BYTE_AS_STRING;
537 array_sig = DBUS_TYPE_ARRAY_AS_STRING DBUS_TYPE_BYTE_AS_STRING;
543 dbus_message_iter_append_basic(iter, DBUS_TYPE_STRING, &key);
545 dbus_message_iter_open_container(iter, DBUS_TYPE_VARIANT,
546 variant_sig, &value);
548 dbus_message_iter_open_container(&value, DBUS_TYPE_ARRAY,
551 function(&array, user_data);
553 dbus_message_iter_close_container(&value, &array);
555 dbus_message_iter_close_container(iter, &value);