3 * WPA supplicant library with GLib integration
5 * Copyright (C) 2010 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 if (dbus_message_iter_init(reply, &iter) == FALSE)
291 if (data->function != NULL)
292 data->function(error, &iter, data->user_data);
295 dbus_message_unref(reply);
297 dbus_pending_call_unref(call);
300 int supplicant_dbus_property_set(const char *path, const char *interface,
301 const char *key, const char *signature,
302 supplicant_dbus_setup_function setup,
303 supplicant_dbus_result_function function,
306 struct property_set_data *data;
307 DBusMessage *message;
308 DBusMessageIter iter, value;
309 DBusPendingCall *call;
311 if (connection == NULL)
314 if (path == NULL || interface == NULL)
317 if (key == NULL || signature == NULL || setup == NULL)
320 data = dbus_malloc0(sizeof(*data));
324 message = dbus_message_new_method_call(SUPPLICANT_SERVICE, path,
325 DBUS_INTERFACE_PROPERTIES, "Set");
326 if (message == NULL) {
331 dbus_message_set_auto_start(message, FALSE);
333 dbus_message_iter_init_append(message, &iter);
334 dbus_message_iter_append_basic(&iter, DBUS_TYPE_STRING, &interface);
335 dbus_message_iter_append_basic(&iter, DBUS_TYPE_STRING, &key);
337 dbus_message_iter_open_container(&iter, DBUS_TYPE_VARIANT,
339 setup(&value, user_data);
340 dbus_message_iter_close_container(&iter, &value);
342 if (dbus_connection_send_with_reply(connection, message,
343 &call, TIMEOUT) == FALSE) {
344 dbus_message_unref(message);
350 dbus_message_unref(message);
355 data->function = function;
356 data->user_data = user_data;
358 dbus_pending_call_set_notify(call, property_set_reply,
361 dbus_message_unref(message);
366 struct method_call_data {
367 supplicant_dbus_result_function function;
371 static void method_call_reply(DBusPendingCall *call, void *user_data)
373 struct method_call_data *data = user_data;
375 DBusMessageIter iter;
378 reply = dbus_pending_call_steal_reply(call);
380 if (dbus_message_get_type(reply) == DBUS_MESSAGE_TYPE_ERROR)
381 error = dbus_message_get_error_name(reply);
385 dbus_message_iter_init(reply, &iter);
387 if (data->function != NULL)
388 data->function(error, &iter, data->user_data);
390 dbus_message_unref(reply);
392 dbus_pending_call_unref(call);
395 int supplicant_dbus_method_call(const char *path,
396 const char *interface, const char *method,
397 supplicant_dbus_setup_function setup,
398 supplicant_dbus_result_function function,
401 struct method_call_data *data;
402 DBusMessage *message;
403 DBusMessageIter iter;
404 DBusPendingCall *call;
406 if (connection == NULL)
409 if (path == NULL || interface == NULL || method == NULL)
412 data = dbus_malloc0(sizeof(*data));
416 message = dbus_message_new_method_call(SUPPLICANT_SERVICE, path,
418 if (message == NULL) {
423 dbus_message_set_auto_start(message, FALSE);
425 dbus_message_iter_init_append(message, &iter);
427 setup(&iter, user_data);
429 if (dbus_connection_send_with_reply(connection, message,
430 &call, TIMEOUT) == FALSE) {
431 dbus_message_unref(message);
437 dbus_message_unref(message);
442 data->function = function;
443 data->user_data = user_data;
445 dbus_pending_call_set_notify(call, method_call_reply,
448 dbus_message_unref(message);
453 void supplicant_dbus_property_append_basic(DBusMessageIter *iter,
454 const char *key, int type, void *val)
456 DBusMessageIter value;
457 const char *signature;
459 dbus_message_iter_append_basic(iter, DBUS_TYPE_STRING, &key);
462 case DBUS_TYPE_BOOLEAN:
463 signature = DBUS_TYPE_BOOLEAN_AS_STRING;
465 case DBUS_TYPE_STRING:
466 signature = DBUS_TYPE_STRING_AS_STRING;
469 signature = DBUS_TYPE_BYTE_AS_STRING;
471 case DBUS_TYPE_UINT16:
472 signature = DBUS_TYPE_UINT16_AS_STRING;
474 case DBUS_TYPE_INT16:
475 signature = DBUS_TYPE_INT16_AS_STRING;
477 case DBUS_TYPE_UINT32:
478 signature = DBUS_TYPE_UINT32_AS_STRING;
480 case DBUS_TYPE_INT32:
481 signature = DBUS_TYPE_INT32_AS_STRING;
483 case DBUS_TYPE_OBJECT_PATH:
484 signature = DBUS_TYPE_OBJECT_PATH_AS_STRING;
487 signature = DBUS_TYPE_VARIANT_AS_STRING;
491 dbus_message_iter_open_container(iter, DBUS_TYPE_VARIANT,
493 dbus_message_iter_append_basic(&value, type, val);
494 dbus_message_iter_close_container(iter, &value);
497 void supplicant_dbus_property_append_fixed_array(DBusMessageIter *iter,
498 const char *key, int type, void *val, int len)
500 DBusMessageIter value, array;
501 const char *variant_sig, *array_sig;
505 variant_sig = DBUS_TYPE_ARRAY_AS_STRING
506 DBUS_TYPE_BYTE_AS_STRING;
507 array_sig = DBUS_TYPE_BYTE_AS_STRING;
513 dbus_message_iter_append_basic(iter, DBUS_TYPE_STRING, &key);
515 dbus_message_iter_open_container(iter, DBUS_TYPE_VARIANT,
516 variant_sig, &value);
518 dbus_message_iter_open_container(&value, DBUS_TYPE_ARRAY,
520 dbus_message_iter_append_fixed_array(&array, type, val, len);
521 dbus_message_iter_close_container(&value, &array);
523 dbus_message_iter_close_container(iter, &value);