5 * Copyright (C) 2007-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>
31 #include "supplicant-dbus.h"
35 static DBusConnection *connection = NULL;
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 struct property_set_data {
186 supplicant_dbus_result_function function;
190 static void property_set_reply(DBusPendingCall *call, void *user_data)
192 struct property_set_data *data = user_data;
194 DBusMessageIter iter;
197 reply = dbus_pending_call_steal_reply(call);
199 if (dbus_message_get_type(reply) == DBUS_MESSAGE_TYPE_ERROR)
200 error = dbus_message_get_error_name(reply);
204 if (dbus_message_iter_init(reply, &iter) == FALSE)
207 if (data->function != NULL)
208 data->function(error, &iter, data->user_data);
211 dbus_message_unref(reply);
213 dbus_pending_call_unref(call);
216 int supplicant_dbus_property_set(const char *path, const char *interface,
217 const char *key, const char *signature,
218 supplicant_dbus_setup_function setup,
219 supplicant_dbus_result_function function,
222 struct property_set_data *data;
223 DBusMessage *message;
224 DBusMessageIter iter, value;
225 DBusPendingCall *call;
227 if (connection == NULL)
230 if (path == NULL || interface == NULL)
233 if (key == NULL || signature == NULL || setup == NULL)
236 data = dbus_malloc0(sizeof(*data));
240 message = dbus_message_new_method_call(SUPPLICANT_SERVICE, path,
241 DBUS_INTERFACE_PROPERTIES, "Set");
242 if (message == NULL) {
247 dbus_message_set_auto_start(message, FALSE);
249 dbus_message_iter_init_append(message, &iter);
250 dbus_message_iter_append_basic(&iter, DBUS_TYPE_STRING, &interface);
251 dbus_message_iter_append_basic(&iter, DBUS_TYPE_STRING, &key);
253 dbus_message_iter_open_container(&iter, DBUS_TYPE_VARIANT,
255 setup(&value, user_data);
256 dbus_message_iter_close_container(&iter, &value);
258 if (dbus_connection_send_with_reply(connection, message,
259 &call, TIMEOUT) == FALSE) {
260 dbus_message_unref(message);
266 dbus_message_unref(message);
271 data->function = function;
272 data->user_data = user_data;
274 dbus_pending_call_set_notify(call, property_set_reply,
277 dbus_message_unref(message);
282 struct method_call_data {
283 supplicant_dbus_result_function function;
287 static void method_call_reply(DBusPendingCall *call, void *user_data)
289 struct method_call_data *data = user_data;
291 DBusMessageIter iter;
294 reply = dbus_pending_call_steal_reply(call);
296 if (dbus_message_get_type(reply) == DBUS_MESSAGE_TYPE_ERROR)
297 error = dbus_message_get_error_name(reply);
301 dbus_message_iter_init(reply, &iter);
303 if (data->function != NULL)
304 data->function(error, &iter, data->user_data);
306 dbus_message_unref(reply);
308 dbus_pending_call_unref(call);
311 int supplicant_dbus_method_call(const char *path,
312 const char *interface, const char *method,
313 supplicant_dbus_setup_function setup,
314 supplicant_dbus_result_function function,
317 struct method_call_data *data;
318 DBusMessage *message;
319 DBusMessageIter iter;
320 DBusPendingCall *call;
322 if (connection == NULL)
325 if (path == NULL || interface == NULL || method == NULL)
328 data = dbus_malloc0(sizeof(*data));
332 message = dbus_message_new_method_call(SUPPLICANT_SERVICE, path,
334 if (message == NULL) {
339 dbus_message_set_auto_start(message, FALSE);
341 dbus_message_iter_init_append(message, &iter);
343 setup(&iter, user_data);
345 if (dbus_connection_send_with_reply(connection, message,
346 &call, TIMEOUT) == FALSE) {
347 dbus_message_unref(message);
353 dbus_message_unref(message);
358 data->function = function;
359 data->user_data = user_data;
361 dbus_pending_call_set_notify(call, method_call_reply,
364 dbus_message_unref(message);
369 void supplicant_dbus_property_append_basic(DBusMessageIter *iter,
370 const char *key, int type, void *val)
372 DBusMessageIter value;
373 const char *signature;
375 dbus_message_iter_append_basic(iter, DBUS_TYPE_STRING, &key);
378 case DBUS_TYPE_BOOLEAN:
379 signature = DBUS_TYPE_BOOLEAN_AS_STRING;
381 case DBUS_TYPE_STRING:
382 signature = DBUS_TYPE_STRING_AS_STRING;
385 signature = DBUS_TYPE_BYTE_AS_STRING;
387 case DBUS_TYPE_UINT16:
388 signature = DBUS_TYPE_UINT16_AS_STRING;
390 case DBUS_TYPE_INT16:
391 signature = DBUS_TYPE_INT16_AS_STRING;
393 case DBUS_TYPE_UINT32:
394 signature = DBUS_TYPE_UINT32_AS_STRING;
396 case DBUS_TYPE_INT32:
397 signature = DBUS_TYPE_INT32_AS_STRING;
399 case DBUS_TYPE_OBJECT_PATH:
400 signature = DBUS_TYPE_OBJECT_PATH_AS_STRING;
403 signature = DBUS_TYPE_VARIANT_AS_STRING;
407 dbus_message_iter_open_container(iter, DBUS_TYPE_VARIANT,
409 dbus_message_iter_append_basic(&value, type, val);
410 dbus_message_iter_close_container(iter, &value);