2 * WPA Supplicant / dbus-based control interface
3 * Copyright (c) 2006, Dan Williams <dcbw@redhat.com> and Red Hat, Inc.
4 * Copyright (c) 2009, Witold Sowa <witold.sowa@gmail.com>
5 * Copyright (c) 2009, Jouni Malinen <j@w1.fi>
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 * Alternatively, this software may be distributed under the terms of BSD
14 * See README and COPYING for more details.
20 #include "common/ieee802_11_defs.h"
21 #include "eap_peer/eap_methods.h"
22 #include "eapol_supp/eapol_supp_sm.h"
23 #include "../config.h"
24 #include "../wpa_supplicant_i.h"
25 #include "../driver_i.h"
26 #include "../notify.h"
27 #include "../wpas_glue.h"
30 #include "dbus_new_helpers.h"
32 #include "dbus_new_handlers.h"
33 #include "dbus_dict_helpers.h"
35 extern int wpa_debug_level;
36 extern int wpa_debug_show_keys;
37 extern int wpa_debug_timestamp;
39 static const char *debug_strings[] = {
40 "msgdump", "debug", "info", "warning", "error", NULL
45 * wpas_dbus_new_decompose_object_path - Decompose an interface object path into parts
46 * @path: The dbus object path
47 * @network: (out) the configured network this object path refers to, if any
48 * @bssid: (out) the scanned bssid this object path refers to, if any
49 * Returns: The object path of the network interface this path refers to
51 * For a given object path, decomposes the object path into object id, network,
52 * and BSSID parts, if those parts exist.
54 static char * wpas_dbus_new_decompose_object_path(const char *path,
58 const unsigned int dev_path_prefix_len =
59 strlen(WPAS_DBUS_NEW_PATH_INTERFACES "/");
63 /* Be a bit paranoid about path */
64 if (!path || os_strncmp(path, WPAS_DBUS_NEW_PATH_INTERFACES "/",
68 /* Ensure there's something at the end of the path */
69 if ((path + dev_path_prefix_len)[0] == '\0')
72 obj_path_only = os_strdup(path);
73 if (obj_path_only == NULL)
76 next_sep = os_strchr(obj_path_only + dev_path_prefix_len, '/');
77 if (next_sep != NULL) {
78 const char *net_part = os_strstr(
79 next_sep, WPAS_DBUS_NEW_NETWORKS_PART "/");
80 const char *bssid_part = os_strstr(
81 next_sep, WPAS_DBUS_NEW_BSSIDS_PART "/");
83 if (network && net_part) {
84 /* Deal with a request for a configured network */
85 const char *net_name = net_part +
86 os_strlen(WPAS_DBUS_NEW_NETWORKS_PART "/");
88 if (os_strlen(net_name))
89 *network = os_strdup(net_name);
90 } else if (bssid && bssid_part) {
91 /* Deal with a request for a scanned BSSID */
92 const char *bssid_name = bssid_part +
93 os_strlen(WPAS_DBUS_NEW_BSSIDS_PART "/");
94 if (strlen(bssid_name))
95 *bssid = os_strdup(bssid_name);
100 /* Cut off interface object path before "/" */
104 return obj_path_only;
109 * wpas_dbus_error_unknown_error - Return a new InvalidArgs error message
110 * @message: Pointer to incoming dbus message this error refers to
111 * @arg: Optional string appended to error message
112 * Returns: a dbus error message
114 * Convenience function to create and return an UnknownError
116 DBusMessage * wpas_dbus_error_unknown_error(DBusMessage *message,
119 return dbus_message_new_error(message, WPAS_DBUS_ERROR_UNKNOWN_ERROR,
125 * wpas_dbus_error_iface_unknown - Return a new invalid interface error message
126 * @message: Pointer to incoming dbus message this error refers to
127 * Returns: A dbus error message
129 * Convenience function to create and return an invalid interface error
131 static DBusMessage * wpas_dbus_error_iface_unknown(DBusMessage *message)
133 return dbus_message_new_error(message, WPAS_DBUS_ERROR_IFACE_UNKNOWN,
134 "wpa_supplicant knows nothing about "
140 * wpas_dbus_error_network_unknown - Return a new NetworkUnknown error message
141 * @message: Pointer to incoming dbus message this error refers to
142 * Returns: a dbus error message
144 * Convenience function to create and return an invalid network error
146 static DBusMessage * wpas_dbus_error_network_unknown(DBusMessage *message)
148 return dbus_message_new_error(message, WPAS_DBUS_ERROR_NETWORK_UNKNOWN,
149 "There is no such a network in this "
155 * wpas_dbus_error_invalid_args - Return a new InvalidArgs error message
156 * @message: Pointer to incoming dbus message this error refers to
157 * Returns: a dbus error message
159 * Convenience function to create and return an invalid options error
161 DBusMessage * wpas_dbus_error_invalid_args(DBusMessage *message,
166 reply = dbus_message_new_error(message, WPAS_DBUS_ERROR_INVALID_ARGS,
167 "Did not receive correct message "
170 dbus_message_append_args(reply, DBUS_TYPE_STRING, &arg,
177 static const char *dont_quote[] = {
178 "key_mgmt", "proto", "pairwise", "auth_alg", "group", "eap",
179 "opensc_engine_path", "pkcs11_engine_path", "pkcs11_module_path",
183 static dbus_bool_t should_quote_opt(const char *key)
186 while (dont_quote[i] != NULL) {
187 if (os_strcmp(key, dont_quote[i]) == 0)
195 * get_iface_by_dbus_path - Get a new network interface
196 * @global: Pointer to global data from wpa_supplicant_init()
197 * @path: Pointer to a dbus object path representing an interface
198 * Returns: Pointer to the interface or %NULL if not found
200 static struct wpa_supplicant * get_iface_by_dbus_path(
201 struct wpa_global *global, const char *path)
203 struct wpa_supplicant *wpa_s;
205 for (wpa_s = global->ifaces; wpa_s; wpa_s = wpa_s->next) {
206 if (os_strcmp(wpa_s->dbus_new_path, path) == 0)
214 * set_network_properties - Set properties of a configured network
215 * @message: Pointer to incoming dbus message
216 * @ssid: wpa_ssid structure for a configured network
217 * @iter: DBus message iterator containing dictionary of network
219 * Returns: NULL when succeed or DBus error on failure
221 * Sets network configuration with parameters given id DBus dictionary
223 static DBusMessage * set_network_properties(DBusMessage *message,
224 struct wpa_ssid *ssid,
225 DBusMessageIter *iter)
228 struct wpa_dbus_dict_entry entry = { .type = DBUS_TYPE_STRING };
229 DBusMessage *reply = NULL;
230 DBusMessageIter iter_dict;
232 if (!wpa_dbus_dict_open_read(iter, &iter_dict))
233 return wpas_dbus_error_invalid_args(message, NULL);
235 while (wpa_dbus_dict_has_dict_entry(&iter_dict)) {
239 if (!wpa_dbus_dict_get_entry(&iter_dict, &entry)) {
240 reply = wpas_dbus_error_invalid_args(message, NULL);
243 if (entry.type == DBUS_TYPE_ARRAY &&
244 entry.array_type == DBUS_TYPE_BYTE) {
245 if (entry.array_len <= 0)
248 size = entry.array_len * 2 + 1;
249 value = os_zalloc(size);
253 ret = wpa_snprintf_hex(value, size,
254 (u8 *) entry.bytearray_value,
258 } else if (entry.type == DBUS_TYPE_STRING) {
259 if (should_quote_opt(entry.key)) {
260 size = os_strlen(entry.str_value);
265 value = os_zalloc(size);
269 ret = os_snprintf(value, size, "\"%s\"",
271 if (ret < 0 || (size_t) ret != (size - 1))
274 value = os_strdup(entry.str_value);
278 } else if (entry.type == DBUS_TYPE_UINT32) {
279 value = os_zalloc(size);
283 ret = os_snprintf(value, size, "%u",
287 } else if (entry.type == DBUS_TYPE_INT32) {
288 value = os_zalloc(size);
292 ret = os_snprintf(value, size, "%d",
299 if (wpa_config_set(ssid, entry.key, value, 0) < 0)
302 if ((os_strcmp(entry.key, "psk") == 0 &&
303 value[0] == '"' && ssid->ssid_len) ||
304 (strcmp(entry.key, "ssid") == 0 && ssid->passphrase))
305 wpa_config_update_psk(ssid);
308 wpa_dbus_dict_entry_clear(&entry);
313 reply = wpas_dbus_error_invalid_args(message, entry.key);
314 wpa_dbus_dict_entry_clear(&entry);
323 * wpas_dbus_simple_property_getter - Get basic type property
324 * @message: Pointer to incoming dbus message
325 * @type: DBus type of property (must be basic type)
326 * @val: pointer to place holding property value
327 * Returns: The DBus message containing response for Properties.Get call
328 * or DBus error message if error occurred.
330 * Generic getter for basic type properties. Type is required to be basic.
332 DBusMessage * wpas_dbus_simple_property_getter(DBusMessage *message,
333 const int type, const void *val)
335 DBusMessage *reply = NULL;
336 DBusMessageIter iter, variant_iter;
338 if (!dbus_type_is_basic(type)) {
339 wpa_printf(MSG_ERROR, "dbus: wpas_dbus_simple_property_getter:"
340 " given type is not basic");
341 return wpas_dbus_error_unknown_error(message, NULL);
345 reply = dbus_message_new(DBUS_MESSAGE_TYPE_SIGNAL);
347 reply = dbus_message_new_method_return(message);
350 dbus_message_iter_init_append(reply, &iter);
351 if (!dbus_message_iter_open_container(
352 &iter, DBUS_TYPE_VARIANT,
353 wpa_dbus_type_as_string(type), &variant_iter) ||
354 !dbus_message_iter_append_basic(&variant_iter, type,
356 !dbus_message_iter_close_container(&iter, &variant_iter)) {
357 wpa_printf(MSG_ERROR, "dbus: "
358 "wpas_dbus_simple_property_getter: out of "
359 "memory to put property value into "
361 dbus_message_unref(reply);
362 reply = dbus_message_new_error(message,
363 DBUS_ERROR_NO_MEMORY,
367 wpa_printf(MSG_ERROR, "dbus: wpas_dbus_simple_property_getter:"
368 " out of memory to return property value");
369 reply = dbus_message_new_error(message, DBUS_ERROR_NO_MEMORY,
378 * wpas_dbus_simple_property_setter - Set basic type property
379 * @message: Pointer to incoming dbus message
380 * @type: DBus type of property (must be basic type)
381 * @val: pointer to place where value being set will be stored
382 * Returns: NULL or DBus error message if error occurred.
384 * Generic setter for basic type properties. Type is required to be basic.
386 DBusMessage * wpas_dbus_simple_property_setter(DBusMessage *message,
387 const int type, void *val)
389 DBusMessageIter iter, variant_iter;
391 if (!dbus_type_is_basic(type)) {
392 wpa_printf(MSG_ERROR, "dbus: wpas_dbus_simple_property_setter:"
393 " given type is not basic");
394 return wpas_dbus_error_unknown_error(message, NULL);
397 if (!dbus_message_iter_init(message, &iter)) {
398 wpa_printf(MSG_ERROR, "dbus: wpas_dbus_simple_property_setter:"
399 " out of memory to return scanning state");
400 return dbus_message_new_error(message, DBUS_ERROR_NO_MEMORY,
404 /* omit first and second argument and get value from third */
405 dbus_message_iter_next(&iter);
406 dbus_message_iter_next(&iter);
407 dbus_message_iter_recurse(&iter, &variant_iter);
409 if (dbus_message_iter_get_arg_type(&variant_iter) != type) {
410 wpa_printf(MSG_DEBUG, "dbus: wpas_dbus_simple_property_setter:"
411 " wrong property type");
412 return wpas_dbus_error_invalid_args(message,
413 "wrong property type");
415 dbus_message_iter_get_basic(&variant_iter, val);
422 * wpas_dbus_simple_array_property_getter - Get array type property
423 * @message: Pointer to incoming dbus message
424 * @type: DBus type of property array elements (must be basic type)
425 * @array: pointer to array of elements to put into response message
426 * @array_len: length of above array
427 * Returns: The DBus message containing response for Properties.Get call
428 * or DBus error message if error occurred.
430 * Generic getter for array type properties. Array elements type is
431 * required to be basic.
433 DBusMessage * wpas_dbus_simple_array_property_getter(DBusMessage *message,
438 DBusMessage *reply = NULL;
439 DBusMessageIter iter, variant_iter, array_iter;
440 char type_str[] = "a?"; /* ? will be replaced with subtype letter; */
441 const char *sub_type_str;
442 size_t element_size, i;
444 if (!dbus_type_is_basic(type)) {
445 wpa_printf(MSG_ERROR, "dbus: "
446 "wpas_dbus_simple_array_property_getter: given "
447 "type is not basic");
448 return wpas_dbus_error_unknown_error(message, NULL);
451 sub_type_str = wpa_dbus_type_as_string(type);
452 type_str[1] = sub_type_str[0];
455 reply = dbus_message_new(DBUS_MESSAGE_TYPE_SIGNAL);
457 reply = dbus_message_new_method_return(message);
459 wpa_printf(MSG_ERROR, "dbus: "
460 "wpas_dbus_simple_array_property_getter: out of "
461 "memory to create return message");
462 return dbus_message_new_error(message, DBUS_ERROR_NO_MEMORY,
466 dbus_message_iter_init_append(reply, &iter);
468 if (!dbus_message_iter_open_container(&iter, DBUS_TYPE_VARIANT,
469 type_str, &variant_iter) ||
470 !dbus_message_iter_open_container(&variant_iter, DBUS_TYPE_ARRAY,
471 sub_type_str, &array_iter)) {
472 wpa_printf(MSG_ERROR, "dbus: "
473 "wpas_dbus_simple_array_property_getter: out of "
474 "memory to open container");
475 dbus_message_unref(reply);
476 return dbus_message_new_error(message, DBUS_ERROR_NO_MEMORY,
482 case DBUS_TYPE_BOOLEAN:
485 case DBUS_TYPE_INT16:
486 case DBUS_TYPE_UINT16:
487 element_size = sizeof(uint16_t);
489 case DBUS_TYPE_INT32:
490 case DBUS_TYPE_UINT32:
491 element_size = sizeof(uint32_t);
493 case DBUS_TYPE_INT64:
494 case DBUS_TYPE_UINT64:
495 element_size = sizeof(uint64_t);
497 case DBUS_TYPE_DOUBLE:
498 element_size = sizeof(double);
500 case DBUS_TYPE_STRING:
501 case DBUS_TYPE_OBJECT_PATH:
502 element_size = sizeof(char *);
505 wpa_printf(MSG_ERROR, "dbus: "
506 "wpas_dbus_simple_array_property_getter: "
507 "fatal: unknown element type");
512 for (i = 0; i < array_len; i++) {
513 dbus_message_iter_append_basic(&array_iter, type,
514 array + i * element_size);
517 if (!dbus_message_iter_close_container(&variant_iter, &array_iter) ||
518 !dbus_message_iter_close_container(&iter, &variant_iter)) {
519 wpa_printf(MSG_ERROR, "dbus: "
520 "wpas_dbus_simple_array_property_getter: out of "
521 "memory to close container");
522 dbus_message_unref(reply);
523 return dbus_message_new_error(message, DBUS_ERROR_NO_MEMORY,
532 * wpas_dbus_handler_create_interface - Request registration of a network iface
533 * @message: Pointer to incoming dbus message
534 * @global: %wpa_supplicant global data structure
535 * Returns: The object path of the new interface object,
536 * or a dbus error message with more information
538 * Handler function for "CreateInterface" method call. Handles requests
539 * by dbus clients to register a network interface that wpa_supplicant
542 DBusMessage * wpas_dbus_handler_create_interface(DBusMessage *message,
543 struct wpa_global *global)
545 DBusMessageIter iter_dict;
546 DBusMessage *reply = NULL;
547 DBusMessageIter iter;
548 struct wpa_dbus_dict_entry entry;
551 char *bridge_ifname = NULL;
553 dbus_message_iter_init(message, &iter);
555 if (!wpa_dbus_dict_open_read(&iter, &iter_dict))
557 while (wpa_dbus_dict_has_dict_entry(&iter_dict)) {
558 if (!wpa_dbus_dict_get_entry(&iter_dict, &entry))
560 if (!strcmp(entry.key, "Driver") &&
561 (entry.type == DBUS_TYPE_STRING)) {
562 driver = os_strdup(entry.str_value);
563 wpa_dbus_dict_entry_clear(&entry);
566 } else if (!strcmp(entry.key, "Ifname") &&
567 (entry.type == DBUS_TYPE_STRING)) {
568 ifname = os_strdup(entry.str_value);
569 wpa_dbus_dict_entry_clear(&entry);
572 } else if (!strcmp(entry.key, "BridgeIfname") &&
573 (entry.type == DBUS_TYPE_STRING)) {
574 bridge_ifname = os_strdup(entry.str_value);
575 wpa_dbus_dict_entry_clear(&entry);
576 if (bridge_ifname == NULL)
579 wpa_dbus_dict_entry_clear(&entry);
585 goto error; /* Required Ifname argument missing */
588 * Try to get the wpa_supplicant record for this iface, return
589 * an error if we already control it.
591 if (wpa_supplicant_get_iface(global, ifname) != NULL) {
592 reply = dbus_message_new_error(message,
593 WPAS_DBUS_ERROR_IFACE_EXISTS,
594 "wpa_supplicant already "
595 "controls this interface.");
597 struct wpa_supplicant *wpa_s;
598 struct wpa_interface iface;
599 os_memset(&iface, 0, sizeof(iface));
600 iface.driver = driver;
601 iface.ifname = ifname;
602 iface.bridge_ifname = bridge_ifname;
603 /* Otherwise, have wpa_supplicant attach to it. */
604 if ((wpa_s = wpa_supplicant_add_iface(global, &iface))) {
605 const char *path = wpa_s->dbus_new_path;
606 reply = dbus_message_new_method_return(message);
607 dbus_message_append_args(reply, DBUS_TYPE_OBJECT_PATH,
608 &path, DBUS_TYPE_INVALID);
610 reply = wpas_dbus_error_unknown_error(
611 message, "wpa_supplicant couldn't grab this "
619 os_free(bridge_ifname);
623 reply = wpas_dbus_error_invalid_args(message, NULL);
629 * wpas_dbus_handler_remove_interface - Request deregistration of an interface
630 * @message: Pointer to incoming dbus message
631 * @global: wpa_supplicant global data structure
632 * Returns: a dbus message containing a UINT32 indicating success (1) or
633 * failure (0), or returns a dbus error message with more information
635 * Handler function for "removeInterface" method call. Handles requests
636 * by dbus clients to deregister a network interface that wpa_supplicant
639 DBusMessage * wpas_dbus_handler_remove_interface(DBusMessage *message,
640 struct wpa_global *global)
642 struct wpa_supplicant *wpa_s;
644 DBusMessage *reply = NULL;
646 dbus_message_get_args(message, NULL, DBUS_TYPE_OBJECT_PATH, &path,
649 wpa_s = get_iface_by_dbus_path(global, path);
651 reply = wpas_dbus_error_iface_unknown(message);
652 else if (wpa_supplicant_remove_iface(global, wpa_s)) {
653 reply = wpas_dbus_error_unknown_error(
654 message, "wpa_supplicant couldn't remove this "
663 * wpas_dbus_handler_get_interface - Get the object path for an interface name
664 * @message: Pointer to incoming dbus message
665 * @global: %wpa_supplicant global data structure
666 * Returns: The object path of the interface object,
667 * or a dbus error message with more information
669 * Handler function for "getInterface" method call.
671 DBusMessage * wpas_dbus_handler_get_interface(DBusMessage *message,
672 struct wpa_global *global)
674 DBusMessage *reply = NULL;
677 struct wpa_supplicant *wpa_s;
679 dbus_message_get_args(message, NULL, DBUS_TYPE_STRING, &ifname,
682 wpa_s = wpa_supplicant_get_iface(global, ifname);
684 return wpas_dbus_error_iface_unknown(message);
686 path = wpa_s->dbus_new_path;
687 reply = dbus_message_new_method_return(message);
689 return dbus_message_new_error(message, DBUS_ERROR_NO_MEMORY,
691 if (!dbus_message_append_args(reply, DBUS_TYPE_OBJECT_PATH, &path,
692 DBUS_TYPE_INVALID)) {
693 dbus_message_unref(reply);
694 return dbus_message_new_error(message, DBUS_ERROR_NO_MEMORY,
703 * wpas_dbus_getter_debug_level - Get debug level
704 * @message: Pointer to incoming dbus message
705 * @global: %wpa_supplicant global data structure
706 * Returns: DBus message with value of debug level
708 * Getter for "DebugLevel" property.
710 DBusMessage * wpas_dbus_getter_debug_level(DBusMessage *message,
711 struct wpa_global *global)
714 int idx = wpa_debug_level;
719 str = debug_strings[idx];
720 return wpas_dbus_simple_property_getter(message, DBUS_TYPE_STRING,
726 * wpas_dbus_getter_debug_timestamp - Get debug timestamp
727 * @message: Pointer to incoming dbus message
728 * @global: %wpa_supplicant global data structure
729 * Returns: DBus message with value of debug timestamp
731 * Getter for "DebugTimestamp" property.
733 DBusMessage * wpas_dbus_getter_debug_timestamp(DBusMessage *message,
734 struct wpa_global *global)
736 return wpas_dbus_simple_property_getter(message, DBUS_TYPE_BOOLEAN,
737 &wpa_debug_timestamp);
743 * wpas_dbus_getter_debug_show_keys - Get debug show keys
744 * @message: Pointer to incoming dbus message
745 * @global: %wpa_supplicant global data structure
746 * Returns: DBus message with value of debug show_keys
748 * Getter for "DebugShowKeys" property.
750 DBusMessage * wpas_dbus_getter_debug_show_keys(DBusMessage *message,
751 struct wpa_global *global)
753 return wpas_dbus_simple_property_getter(message, DBUS_TYPE_BOOLEAN,
754 &wpa_debug_show_keys);
759 * wpas_dbus_setter_debug_level - Set debug level
760 * @message: Pointer to incoming dbus message
761 * @global: %wpa_supplicant global data structure
762 * Returns: %NULL or DBus error message
764 * Setter for "DebugLevel" property.
766 DBusMessage * wpas_dbus_setter_debug_level(DBusMessage *message,
767 struct wpa_global *global)
770 const char *str = NULL;
773 reply = wpas_dbus_simple_property_setter(message, DBUS_TYPE_STRING,
778 for (i = 0; debug_strings[i]; i++)
779 if (os_strcmp(debug_strings[i], str) == 0) {
785 wpa_supplicant_set_debug_params(global, val, wpa_debug_timestamp,
786 wpa_debug_show_keys)) {
787 dbus_message_unref(reply);
788 return wpas_dbus_error_invalid_args(
789 message, "Wrong debug level value");
797 * wpas_dbus_setter_debug_timestamp - Set debug timestamp
798 * @message: Pointer to incoming dbus message
799 * @global: %wpa_supplicant global data structure
800 * Returns: %NULL or DBus error message
802 * Setter for "DebugTimestamp" property.
804 DBusMessage * wpas_dbus_setter_debug_timestamp(DBusMessage *message,
805 struct wpa_global *global)
810 reply = wpas_dbus_simple_property_setter(message, DBUS_TYPE_BOOLEAN,
815 wpa_supplicant_set_debug_params(global, wpa_debug_level, val ? 1 : 0,
816 wpa_debug_show_keys);
823 * wpas_dbus_setter_debug_show_keys - Set debug show keys
824 * @message: Pointer to incoming dbus message
825 * @global: %wpa_supplicant global data structure
826 * Returns: %NULL or DBus error message
828 * Setter for "DebugShowKeys" property.
830 DBusMessage * wpas_dbus_setter_debug_show_keys(DBusMessage *message,
831 struct wpa_global *global)
836 reply = wpas_dbus_simple_property_setter(message, DBUS_TYPE_BOOLEAN,
841 wpa_supplicant_set_debug_params(global, wpa_debug_level,
850 * wpas_dbus_getter_interfaces - Request registered interfaces list
851 * @message: Pointer to incoming dbus message
852 * @global: %wpa_supplicant global data structure
853 * Returns: The object paths array containing registered interfaces
854 * objects paths or DBus error on failure
856 * Getter for "Interfaces" property. Handles requests
857 * by dbus clients to return list of registered interfaces objects
860 DBusMessage * wpas_dbus_getter_interfaces(DBusMessage *message,
861 struct wpa_global *global)
863 DBusMessage *reply = NULL;
864 struct wpa_supplicant *wpa_s;
866 unsigned int i = 0, num = 0;
868 for (wpa_s = global->ifaces; wpa_s; wpa_s = wpa_s->next)
871 paths = os_zalloc(num * sizeof(char*));
873 return dbus_message_new_error(message, DBUS_ERROR_NO_MEMORY,
877 for (wpa_s = global->ifaces; wpa_s; wpa_s = wpa_s->next)
878 paths[i] = wpa_s->dbus_new_path;
880 reply = wpas_dbus_simple_array_property_getter(message,
881 DBUS_TYPE_OBJECT_PATH,
890 * wpas_dbus_getter_eap_methods - Request supported EAP methods list
891 * @message: Pointer to incoming dbus message
892 * @nothing: not used argument. may be NULL or anything else
893 * Returns: The object paths array containing supported EAP methods
894 * represented by strings or DBus error on failure
896 * Getter for "EapMethods" property. Handles requests
897 * by dbus clients to return list of strings with supported EAP methods
899 DBusMessage * wpas_dbus_getter_eap_methods(DBusMessage *message, void *nothing)
901 DBusMessage *reply = NULL;
903 size_t num_items = 0;
905 eap_methods = eap_get_names_as_string_array(&num_items);
907 return dbus_message_new_error(message, DBUS_ERROR_NO_MEMORY,
911 reply = wpas_dbus_simple_array_property_getter(message,
913 eap_methods, num_items);
916 os_free(eap_methods[--num_items]);
917 os_free(eap_methods);
922 static int wpas_dbus_get_scan_type(DBusMessage *message, DBusMessageIter *var,
923 char **type, DBusMessage **reply)
925 if (dbus_message_iter_get_arg_type(var) != DBUS_TYPE_STRING) {
926 wpa_printf(MSG_DEBUG, "wpas_dbus_handler_scan[dbus]: "
927 "Type must be a string");
928 *reply = wpas_dbus_error_invalid_args(
929 message, "Wrong Type value type. String required");
932 dbus_message_iter_get_basic(var, type);
937 static int wpas_dbus_get_scan_ssids(DBusMessage *message, DBusMessageIter *var,
938 struct wpa_driver_scan_params *params,
941 struct wpa_driver_scan_ssid *ssids = params->ssids;
942 size_t ssids_num = 0;
944 DBusMessageIter array_iter, sub_array_iter;
948 if (dbus_message_iter_get_arg_type(var) != DBUS_TYPE_ARRAY) {
949 wpa_printf(MSG_DEBUG, "wpas_dbus_handler_scan[dbus]: ssids "
950 "must be an array of arrays of bytes");
951 *reply = wpas_dbus_error_invalid_args(
952 message, "Wrong SSIDs value type. Array of arrays of "
957 dbus_message_iter_recurse(var, &array_iter);
959 if (dbus_message_iter_get_arg_type(&array_iter) != DBUS_TYPE_ARRAY ||
960 dbus_message_iter_get_element_type(&array_iter) != DBUS_TYPE_BYTE)
962 wpa_printf(MSG_DEBUG, "wpas_dbus_handler_scan[dbus]: ssids "
963 "must be an array of arrays of bytes");
964 *reply = wpas_dbus_error_invalid_args(
965 message, "Wrong SSIDs value type. Array of arrays of "
970 while (dbus_message_iter_get_arg_type(&array_iter) == DBUS_TYPE_ARRAY)
972 if (ssids_num >= WPAS_MAX_SCAN_SSIDS) {
973 wpa_printf(MSG_DEBUG, "wpas_dbus_handler_scan[dbus]: "
974 "Too many ssids specified on scan dbus "
976 *reply = wpas_dbus_error_invalid_args(
977 message, "Too many ssids specified. Specify "
982 dbus_message_iter_recurse(&array_iter, &sub_array_iter);
984 dbus_message_iter_get_fixed_array(&sub_array_iter, &val, &len);
986 dbus_message_iter_next(&array_iter);
990 ssid = os_malloc(len);
992 wpa_printf(MSG_DEBUG, "wpas_dbus_handler_scan[dbus]: "
993 "out of memory. Cannot allocate memory for "
995 *reply = dbus_message_new_error(
996 message, DBUS_ERROR_NO_MEMORY, NULL);
999 os_memcpy(ssid, val, len);
1000 ssids[ssids_num].ssid = ssid;
1001 ssids[ssids_num].ssid_len = len;
1003 dbus_message_iter_next(&array_iter);
1007 params->num_ssids = ssids_num;
1012 static int wpas_dbus_get_scan_ies(DBusMessage *message, DBusMessageIter *var,
1013 struct wpa_driver_scan_params *params,
1014 DBusMessage **reply)
1016 u8 *ies = NULL, *nies;
1018 DBusMessageIter array_iter, sub_array_iter;
1022 if (dbus_message_iter_get_arg_type(var) != DBUS_TYPE_ARRAY) {
1023 wpa_printf(MSG_DEBUG, "wpas_dbus_handler_scan[dbus]: ies must "
1024 "be an array of arrays of bytes");
1025 *reply = wpas_dbus_error_invalid_args(
1026 message, "Wrong IEs value type. Array of arrays of "
1031 dbus_message_iter_recurse(var, &array_iter);
1033 if (dbus_message_iter_get_arg_type(&array_iter) != DBUS_TYPE_ARRAY ||
1034 dbus_message_iter_get_element_type(&array_iter) != DBUS_TYPE_BYTE)
1036 wpa_printf(MSG_DEBUG, "wpas_dbus_handler_scan[dbus]: ies must "
1037 "be an array of arrays of bytes");
1038 *reply = wpas_dbus_error_invalid_args(
1039 message, "Wrong IEs value type. Array required");
1043 while (dbus_message_iter_get_arg_type(&array_iter) == DBUS_TYPE_ARRAY)
1045 dbus_message_iter_recurse(&array_iter, &sub_array_iter);
1047 dbus_message_iter_get_fixed_array(&sub_array_iter, &val, &len);
1049 dbus_message_iter_next(&array_iter);
1053 nies = os_realloc(ies, ies_len + len);
1055 wpa_printf(MSG_DEBUG, "wpas_dbus_handler_scan[dbus]: "
1056 "out of memory. Cannot allocate memory for "
1059 *reply = dbus_message_new_error(
1060 message, DBUS_ERROR_NO_MEMORY, NULL);
1064 os_memcpy(ies + ies_len, val, len);
1067 dbus_message_iter_next(&array_iter);
1070 params->extra_ies = ies;
1071 params->extra_ies_len = ies_len;
1076 static int wpas_dbus_get_scan_channels(DBusMessage *message,
1077 DBusMessageIter *var,
1078 struct wpa_driver_scan_params *params,
1079 DBusMessage **reply)
1081 DBusMessageIter array_iter, sub_array_iter;
1082 int *freqs = NULL, *nfreqs;
1085 if (dbus_message_iter_get_arg_type(var) != DBUS_TYPE_ARRAY) {
1086 wpa_printf(MSG_DEBUG, "wpas_dbus_handler_scan[dbus]: "
1087 "Channels must be an array of structs");
1088 *reply = wpas_dbus_error_invalid_args(
1089 message, "Wrong Channels value type. Array of structs "
1094 dbus_message_iter_recurse(var, &array_iter);
1096 if (dbus_message_iter_get_arg_type(&array_iter) != DBUS_TYPE_STRUCT) {
1097 wpa_printf(MSG_DEBUG,
1098 "wpas_dbus_handler_scan[dbus]: Channels must be an "
1099 "array of structs");
1100 *reply = wpas_dbus_error_invalid_args(
1101 message, "Wrong Channels value type. Array of structs "
1106 while (dbus_message_iter_get_arg_type(&array_iter) == DBUS_TYPE_STRUCT)
1110 dbus_message_iter_recurse(&array_iter, &sub_array_iter);
1112 if (dbus_message_iter_get_arg_type(&sub_array_iter) !=
1114 wpa_printf(MSG_DEBUG, "wpas_dbus_handler_scan[dbus]: "
1115 "Channel must by specified by struct of "
1117 dbus_message_iter_get_arg_type(
1119 *reply = wpas_dbus_error_invalid_args(
1120 message, "Wrong Channel struct. Two UINT32s "
1125 dbus_message_iter_get_basic(&sub_array_iter, &freq);
1127 if (!dbus_message_iter_next(&sub_array_iter) ||
1128 dbus_message_iter_get_arg_type(&sub_array_iter) !=
1130 wpa_printf(MSG_DEBUG, "wpas_dbus_handler_scan[dbus]: "
1131 "Channel must by specified by struct of "
1133 *reply = wpas_dbus_error_invalid_args(
1135 "Wrong Channel struct. Two UINT32s required");
1140 dbus_message_iter_get_basic(&sub_array_iter, &width);
1142 #define FREQS_ALLOC_CHUNK 32
1143 if (freqs_num % FREQS_ALLOC_CHUNK == 0) {
1144 nfreqs = os_realloc(freqs, sizeof(int) *
1145 (freqs_num + FREQS_ALLOC_CHUNK));
1150 if (freqs == NULL) {
1151 wpa_printf(MSG_DEBUG, "wpas_dbus_handler_scan[dbus]: "
1152 "out of memory. can't allocate memory for "
1154 *reply = dbus_message_new_error(
1155 message, DBUS_ERROR_NO_MEMORY, NULL);
1159 freqs[freqs_num] = freq;
1162 dbus_message_iter_next(&array_iter);
1165 nfreqs = os_realloc(freqs,
1166 sizeof(int) * (freqs_num + 1));
1170 if (freqs == NULL) {
1171 wpa_printf(MSG_DEBUG, "wpas_dbus_handler_scan[dbus]: "
1172 "out of memory. Can't allocate memory for freqs");
1173 *reply = dbus_message_new_error(
1174 message, DBUS_ERROR_NO_MEMORY, NULL);
1177 freqs[freqs_num] = 0;
1179 params->freqs = freqs;
1185 * wpas_dbus_handler_scan - Request a wireless scan on an interface
1186 * @message: Pointer to incoming dbus message
1187 * @wpa_s: wpa_supplicant structure for a network interface
1188 * Returns: NULL indicating success or DBus error message on failure
1190 * Handler function for "Scan" method call of a network device. Requests
1191 * that wpa_supplicant perform a wireless scan as soon as possible
1192 * on a particular wireless interface.
1194 DBusMessage * wpas_dbus_handler_scan(DBusMessage *message,
1195 struct wpa_supplicant *wpa_s)
1197 DBusMessage *reply = NULL;
1198 DBusMessageIter iter, dict_iter, entry_iter, variant_iter;
1199 char *key = NULL, *type = NULL;
1200 struct wpa_driver_scan_params params;
1203 os_memset(¶ms, 0, sizeof(params));
1205 dbus_message_iter_init(message, &iter);
1207 dbus_message_iter_recurse(&iter, &dict_iter);
1209 while (dbus_message_iter_get_arg_type(&dict_iter) ==
1210 DBUS_TYPE_DICT_ENTRY) {
1211 dbus_message_iter_recurse(&dict_iter, &entry_iter);
1212 dbus_message_iter_get_basic(&entry_iter, &key);
1213 dbus_message_iter_next(&entry_iter);
1214 dbus_message_iter_recurse(&entry_iter, &variant_iter);
1216 if (os_strcmp(key, "Type") == 0) {
1217 if (wpas_dbus_get_scan_type(message, &variant_iter,
1220 } else if (os_strcmp(key, "SSIDs") == 0) {
1221 if (wpas_dbus_get_scan_ssids(message, &variant_iter,
1222 ¶ms, &reply) < 0)
1224 } else if (os_strcmp(key, "IEs") == 0) {
1225 if (wpas_dbus_get_scan_ies(message, &variant_iter,
1226 ¶ms, &reply) < 0)
1228 } else if (os_strcmp(key, "Channels") == 0) {
1229 if (wpas_dbus_get_scan_channels(message, &variant_iter,
1230 ¶ms, &reply) < 0)
1233 wpa_printf(MSG_DEBUG, "wpas_dbus_handler_scan[dbus]: "
1234 "Unknown argument %s", key);
1235 reply = wpas_dbus_error_invalid_args(message, key);
1239 dbus_message_iter_next(&dict_iter);
1243 wpa_printf(MSG_DEBUG, "wpas_dbus_handler_scan[dbus]: "
1244 "Scan type not specified");
1245 reply = wpas_dbus_error_invalid_args(message, key);
1249 if (!os_strcmp(type, "passive")) {
1250 if (params.num_ssids || params.extra_ies_len) {
1251 wpa_printf(MSG_DEBUG, "wpas_dbus_handler_scan[dbus]: "
1252 "SSIDs or IEs specified for passive scan.");
1253 reply = wpas_dbus_error_invalid_args(
1254 message, "You can specify only Channels in "
1257 } else if (params.freqs && params.freqs[0]) {
1260 wpa_supplicant_trigger_scan(wpa_s, ¶ms);
1262 wpa_s->scan_req = 2;
1263 wpa_supplicant_req_scan(wpa_s, 0, 0);
1265 } else if (!os_strcmp(type, "active")) {
1266 wpa_supplicant_trigger_scan(wpa_s, ¶ms);
1268 wpa_printf(MSG_DEBUG, "wpas_dbus_handler_scan[dbus]: "
1269 "Unknown scan type: %s", type);
1270 reply = wpas_dbus_error_invalid_args(message,
1276 for (i = 0; i < WPAS_MAX_SCAN_SSIDS; i++)
1277 os_free((u8 *) params.ssids[i].ssid);
1278 os_free((u8 *) params.extra_ies);
1279 os_free(params.freqs);
1285 * wpas_dbus_handler_disconnect - Terminate the current connection
1286 * @message: Pointer to incoming dbus message
1287 * @wpa_s: wpa_supplicant structure for a network interface
1288 * Returns: NotConnected DBus error message if already not connected
1289 * or NULL otherwise.
1291 * Handler function for "Disconnect" method call of network interface.
1293 DBusMessage * wpas_dbus_handler_disconnect(DBusMessage *message,
1294 struct wpa_supplicant *wpa_s)
1296 if (wpa_s->current_ssid != NULL) {
1297 wpa_s->disconnected = 1;
1298 wpa_supplicant_disassociate(wpa_s, WLAN_REASON_DEAUTH_LEAVING);
1303 return dbus_message_new_error(message, WPAS_DBUS_ERROR_NOT_CONNECTED,
1304 "This interface is not connected");
1309 * wpas_dbus_new_iface_add_network - Add a new configured network
1310 * @message: Pointer to incoming dbus message
1311 * @wpa_s: wpa_supplicant structure for a network interface
1312 * Returns: A dbus message containing the object path of the new network
1314 * Handler function for "AddNetwork" method call of a network interface.
1316 DBusMessage * wpas_dbus_handler_add_network(DBusMessage *message,
1317 struct wpa_supplicant *wpa_s)
1319 DBusMessage *reply = NULL;
1320 DBusMessageIter iter;
1321 struct wpa_ssid *ssid = NULL;
1322 char path_buf[WPAS_DBUS_OBJECT_PATH_MAX], *path = path_buf;
1324 dbus_message_iter_init(message, &iter);
1326 ssid = wpa_config_add_network(wpa_s->conf);
1328 wpa_printf(MSG_ERROR, "wpas_dbus_handler_add_network[dbus]: "
1329 "can't add new interface.");
1330 reply = wpas_dbus_error_unknown_error(
1332 "wpa_supplicant could not add "
1333 "a network on this interface.");
1336 wpas_notify_network_added(wpa_s, ssid);
1338 wpa_config_set_network_defaults(ssid);
1340 reply = set_network_properties(message, ssid, &iter);
1342 wpa_printf(MSG_DEBUG, "wpas_dbus_handler_add_network[dbus]:"
1343 "control interface couldn't set network "
1348 /* Construct the object path for this network. */
1349 os_snprintf(path, WPAS_DBUS_OBJECT_PATH_MAX,
1350 "%s/" WPAS_DBUS_NEW_NETWORKS_PART "/%d",
1351 wpa_s->dbus_new_path, ssid->id);
1353 reply = dbus_message_new_method_return(message);
1354 if (reply == NULL) {
1355 reply = dbus_message_new_error(message, DBUS_ERROR_NO_MEMORY,
1359 if (!dbus_message_append_args(reply, DBUS_TYPE_OBJECT_PATH, &path,
1360 DBUS_TYPE_INVALID)) {
1361 dbus_message_unref(reply);
1362 reply = dbus_message_new_error(message, DBUS_ERROR_NO_MEMORY,
1371 wpas_notify_network_removed(wpa_s, ssid);
1372 wpa_config_remove_network(wpa_s->conf, ssid->id);
1379 * wpas_dbus_handler_remove_network - Remove a configured network
1380 * @message: Pointer to incoming dbus message
1381 * @wpa_s: wpa_supplicant structure for a network interface
1382 * Returns: NULL on success or dbus error on failure
1384 * Handler function for "RemoveNetwork" method call of a network interface.
1386 DBusMessage * wpas_dbus_handler_remove_network(DBusMessage *message,
1387 struct wpa_supplicant *wpa_s)
1389 DBusMessage *reply = NULL;
1391 char *iface = NULL, *net_id = NULL;
1393 struct wpa_ssid *ssid;
1395 dbus_message_get_args(message, NULL, DBUS_TYPE_OBJECT_PATH, &op,
1398 /* Extract the network ID and ensure the network */
1399 /* is actually a child of this interface */
1400 iface = wpas_dbus_new_decompose_object_path(op, &net_id, NULL);
1401 if (iface == NULL || os_strcmp(iface, wpa_s->dbus_new_path) != 0) {
1402 reply = wpas_dbus_error_invalid_args(message, op);
1406 id = strtoul(net_id, NULL, 10);
1407 if (errno == EINVAL) {
1408 reply = wpas_dbus_error_invalid_args(message, op);
1412 ssid = wpa_config_get_network(wpa_s->conf, id);
1414 reply = wpas_dbus_error_network_unknown(message);
1418 wpas_notify_network_removed(wpa_s, ssid);
1420 if (wpa_config_remove_network(wpa_s->conf, id) < 0) {
1421 wpa_printf(MSG_ERROR,
1422 "wpas_dbus_handler_remove_network[dbus]: "
1423 "error occurred when removing network %d", id);
1424 reply = wpas_dbus_error_unknown_error(
1425 message, "error removing the specified network on "
1430 if (ssid == wpa_s->current_ssid)
1431 wpa_supplicant_disassociate(wpa_s, WLAN_REASON_DEAUTH_LEAVING);
1441 * wpas_dbus_handler_select_network - Attempt association with a network
1442 * @message: Pointer to incoming dbus message
1443 * @wpa_s: wpa_supplicant structure for a network interface
1444 * Returns: NULL on success or dbus error on failure
1446 * Handler function for "SelectNetwork" method call of network interface.
1448 DBusMessage * wpas_dbus_handler_select_network(DBusMessage *message,
1449 struct wpa_supplicant *wpa_s)
1451 DBusMessage *reply = NULL;
1453 char *iface = NULL, *net_id = NULL;
1455 struct wpa_ssid *ssid;
1457 dbus_message_get_args(message, NULL, DBUS_TYPE_OBJECT_PATH, &op,
1460 /* Extract the network ID and ensure the network */
1461 /* is actually a child of this interface */
1462 iface = wpas_dbus_new_decompose_object_path(op, &net_id, NULL);
1463 if (iface == NULL || os_strcmp(iface, wpa_s->dbus_new_path) != 0) {
1464 reply = wpas_dbus_error_invalid_args(message, op);
1468 id = strtoul(net_id, NULL, 10);
1469 if (errno == EINVAL) {
1470 reply = wpas_dbus_error_invalid_args(message, op);
1474 ssid = wpa_config_get_network(wpa_s->conf, id);
1476 reply = wpas_dbus_error_network_unknown(message);
1480 /* Finally, associate with the network */
1481 wpa_supplicant_select_network(wpa_s, ssid);
1491 * wpas_dbus_handler_add_blob - Store named binary blob (ie, for certificates)
1492 * @message: Pointer to incoming dbus message
1493 * @wpa_s: %wpa_supplicant data structure
1494 * Returns: A dbus message containing an error on failure or NULL on success
1496 * Asks wpa_supplicant to internally store a binary blobs.
1498 DBusMessage * wpas_dbus_handler_add_blob(DBusMessage *message,
1499 struct wpa_supplicant *wpa_s)
1501 DBusMessage *reply = NULL;
1502 DBusMessageIter iter, array_iter;
1507 struct wpa_config_blob *blob = NULL;
1509 dbus_message_iter_init(message, &iter);
1510 dbus_message_iter_get_basic(&iter, &blob_name);
1512 if (wpa_config_get_blob(wpa_s->conf, blob_name)) {
1513 return dbus_message_new_error(message,
1514 WPAS_DBUS_ERROR_BLOB_EXISTS,
1518 dbus_message_iter_next(&iter);
1519 dbus_message_iter_recurse(&iter, &array_iter);
1521 dbus_message_iter_get_fixed_array(&array_iter, &blob_data, &blob_len);
1523 blob = os_zalloc(sizeof(*blob));
1525 reply = dbus_message_new_error(message, DBUS_ERROR_NO_MEMORY,
1530 blob->data = os_malloc(blob_len);
1532 reply = dbus_message_new_error(message, DBUS_ERROR_NO_MEMORY,
1536 os_memcpy(blob->data, blob_data, blob_len);
1538 blob->len = blob_len;
1539 blob->name = os_strdup(blob_name);
1541 reply = dbus_message_new_error(message, DBUS_ERROR_NO_MEMORY,
1546 wpa_config_set_blob(wpa_s->conf, blob);
1547 wpas_notify_blob_added(wpa_s, blob->name);
1553 os_free(blob->name);
1554 os_free(blob->data);
1562 * wpas_dbus_handler_get_blob - Get named binary blob (ie, for certificates)
1563 * @message: Pointer to incoming dbus message
1564 * @wpa_s: %wpa_supplicant data structure
1565 * Returns: A dbus message containing array of bytes (blob)
1567 * Gets one wpa_supplicant's binary blobs.
1569 DBusMessage * wpas_dbus_handler_get_blob(DBusMessage *message,
1570 struct wpa_supplicant *wpa_s)
1572 DBusMessage *reply = NULL;
1573 DBusMessageIter iter, array_iter;
1576 const struct wpa_config_blob *blob;
1578 dbus_message_get_args(message, NULL, DBUS_TYPE_STRING, &blob_name,
1581 blob = wpa_config_get_blob(wpa_s->conf, blob_name);
1583 return dbus_message_new_error(message,
1584 WPAS_DBUS_ERROR_BLOB_UNKNOWN,
1588 reply = dbus_message_new_method_return(message);
1590 reply = dbus_message_new_error(message, DBUS_ERROR_NO_MEMORY,
1595 dbus_message_iter_init_append(reply, &iter);
1597 if (!dbus_message_iter_open_container(&iter, DBUS_TYPE_ARRAY,
1598 DBUS_TYPE_BYTE_AS_STRING,
1600 dbus_message_unref(reply);
1601 reply = dbus_message_new_error(message, DBUS_ERROR_NO_MEMORY,
1606 if (!dbus_message_iter_append_fixed_array(&array_iter, DBUS_TYPE_BYTE,
1607 &(blob->data), blob->len)) {
1608 dbus_message_unref(reply);
1609 reply = dbus_message_new_error(message, DBUS_ERROR_NO_MEMORY,
1614 if (!dbus_message_iter_close_container(&iter, &array_iter)) {
1615 dbus_message_unref(reply);
1616 reply = dbus_message_new_error(message, DBUS_ERROR_NO_MEMORY,
1627 * wpas_remove_handler_remove_blob - Remove named binary blob
1628 * @message: Pointer to incoming dbus message
1629 * @wpa_s: %wpa_supplicant data structure
1630 * Returns: NULL on success or dbus error
1632 * Asks wpa_supplicant to internally remove a binary blobs.
1634 DBusMessage * wpas_dbus_handler_remove_blob(DBusMessage *message,
1635 struct wpa_supplicant *wpa_s)
1637 DBusMessage *reply = NULL;
1640 dbus_message_get_args(message, NULL, DBUS_TYPE_STRING, &blob_name,
1643 if (wpa_config_remove_blob(wpa_s->conf, blob_name)) {
1644 return dbus_message_new_error(message,
1645 WPAS_DBUS_ERROR_BLOB_UNKNOWN,
1648 wpas_notify_blob_removed(wpa_s, blob_name);
1656 * wpas_dbus_getter_capabilities - Return interface capabilities
1657 * @message: Pointer to incoming dbus message
1658 * @wpa_s: wpa_supplicant structure for a network interface
1659 * Returns: A dbus message containing a dict of strings
1661 * Getter for "Capabilities" property of an interface.
1663 DBusMessage * wpas_dbus_getter_capabilities(DBusMessage *message,
1664 struct wpa_supplicant *wpa_s)
1666 DBusMessage *reply = NULL;
1667 struct wpa_driver_capa capa;
1669 DBusMessageIter iter, iter_dict;
1670 DBusMessageIter iter_dict_entry, iter_dict_val, iter_array,
1672 const char *scans[] = { "active", "passive", "ssid" };
1673 const char *modes[] = { "infrastructure", "ad-hoc", "ap" };
1674 int n = sizeof(modes) / sizeof(char *);
1676 if (message == NULL)
1677 reply = dbus_message_new(DBUS_MESSAGE_TYPE_SIGNAL);
1679 reply = dbus_message_new_method_return(message);
1683 dbus_message_iter_init_append(reply, &iter);
1684 if (!dbus_message_iter_open_container(&iter, DBUS_TYPE_VARIANT,
1685 "a{sv}", &variant_iter))
1688 if (!wpa_dbus_dict_open_write(&variant_iter, &iter_dict))
1691 res = wpa_drv_get_capa(wpa_s, &capa);
1693 /***** pairwise cipher */
1695 const char *args[] = {"ccmp", "tkip", "none"};
1696 if (!wpa_dbus_dict_append_string_array(
1697 &iter_dict, "Pairwise", args,
1698 sizeof(args) / sizeof(char*)))
1701 if (!wpa_dbus_dict_begin_string_array(&iter_dict, "Pairwise",
1707 if (capa.enc & WPA_DRIVER_CAPA_ENC_CCMP) {
1708 if (!wpa_dbus_dict_string_array_add_element(
1709 &iter_array, "ccmp"))
1713 if (capa.enc & WPA_DRIVER_CAPA_ENC_TKIP) {
1714 if (!wpa_dbus_dict_string_array_add_element(
1715 &iter_array, "tkip"))
1719 if (capa.key_mgmt & WPA_DRIVER_CAPA_KEY_MGMT_WPA_NONE) {
1720 if (!wpa_dbus_dict_string_array_add_element(
1721 &iter_array, "none"))
1725 if (!wpa_dbus_dict_end_string_array(&iter_dict,
1732 /***** group cipher */
1734 const char *args[] = {
1735 "ccmp", "tkip", "wep104", "wep40"
1737 if (!wpa_dbus_dict_append_string_array(
1738 &iter_dict, "Group", args,
1739 sizeof(args) / sizeof(char*)))
1742 if (!wpa_dbus_dict_begin_string_array(&iter_dict, "Group",
1748 if (capa.enc & WPA_DRIVER_CAPA_ENC_CCMP) {
1749 if (!wpa_dbus_dict_string_array_add_element(
1750 &iter_array, "ccmp"))
1754 if (capa.enc & WPA_DRIVER_CAPA_ENC_TKIP) {
1755 if (!wpa_dbus_dict_string_array_add_element(
1756 &iter_array, "tkip"))
1760 if (capa.enc & WPA_DRIVER_CAPA_ENC_WEP104) {
1761 if (!wpa_dbus_dict_string_array_add_element(
1762 &iter_array, "wep104"))
1766 if (capa.enc & WPA_DRIVER_CAPA_ENC_WEP40) {
1767 if (!wpa_dbus_dict_string_array_add_element(
1768 &iter_array, "wep40"))
1772 if (!wpa_dbus_dict_end_string_array(&iter_dict,
1779 /***** key management */
1781 const char *args[] = {
1782 "wpa-psk", "wpa-eap", "ieee8021x", "wpa-none",
1785 #endif /* CONFIG_WPS */
1788 if (!wpa_dbus_dict_append_string_array(
1789 &iter_dict, "KeyMgmt", args,
1790 sizeof(args) / sizeof(char*)))
1793 if (!wpa_dbus_dict_begin_string_array(&iter_dict, "KeyMgmt",
1799 if (!wpa_dbus_dict_string_array_add_element(&iter_array,
1803 if (!wpa_dbus_dict_string_array_add_element(&iter_array,
1807 if (capa.key_mgmt & (WPA_DRIVER_CAPA_KEY_MGMT_WPA |
1808 WPA_DRIVER_CAPA_KEY_MGMT_WPA2)) {
1809 if (!wpa_dbus_dict_string_array_add_element(
1810 &iter_array, "wpa-eap"))
1814 if (capa.key_mgmt & (WPA_DRIVER_CAPA_KEY_MGMT_WPA_PSK |
1815 WPA_DRIVER_CAPA_KEY_MGMT_WPA2_PSK)) {
1816 if (!wpa_dbus_dict_string_array_add_element(
1817 &iter_array, "wpa-psk"))
1821 if (capa.key_mgmt & WPA_DRIVER_CAPA_KEY_MGMT_WPA_NONE) {
1822 if (!wpa_dbus_dict_string_array_add_element(
1823 &iter_array, "wpa-none"))
1829 if (!wpa_dbus_dict_string_array_add_element(&iter_array,
1832 #endif /* CONFIG_WPS */
1834 if (!wpa_dbus_dict_end_string_array(&iter_dict,
1841 /***** WPA protocol */
1843 const char *args[] = { "rsn", "wpa" };
1844 if (!wpa_dbus_dict_append_string_array(
1845 &iter_dict, "Protocol", args,
1846 sizeof(args) / sizeof(char*)))
1849 if (!wpa_dbus_dict_begin_string_array(&iter_dict, "Protocol",
1855 if (capa.key_mgmt & (WPA_DRIVER_CAPA_KEY_MGMT_WPA2 |
1856 WPA_DRIVER_CAPA_KEY_MGMT_WPA2_PSK)) {
1857 if (!wpa_dbus_dict_string_array_add_element(
1858 &iter_array, "rsn"))
1862 if (capa.key_mgmt & (WPA_DRIVER_CAPA_KEY_MGMT_WPA |
1863 WPA_DRIVER_CAPA_KEY_MGMT_WPA_PSK)) {
1864 if (!wpa_dbus_dict_string_array_add_element(
1865 &iter_array, "wpa"))
1869 if (!wpa_dbus_dict_end_string_array(&iter_dict,
1878 const char *args[] = { "open", "shared", "leap" };
1879 if (!wpa_dbus_dict_append_string_array(
1880 &iter_dict, "AuthAlg", args,
1881 sizeof(args) / sizeof(char*)))
1884 if (!wpa_dbus_dict_begin_string_array(&iter_dict, "AuthAlg",
1890 if (capa.auth & (WPA_DRIVER_AUTH_OPEN)) {
1891 if (!wpa_dbus_dict_string_array_add_element(
1892 &iter_array, "open"))
1896 if (capa.auth & (WPA_DRIVER_AUTH_SHARED)) {
1897 if (!wpa_dbus_dict_string_array_add_element(
1898 &iter_array, "shared"))
1902 if (capa.auth & (WPA_DRIVER_AUTH_LEAP)) {
1903 if (!wpa_dbus_dict_string_array_add_element(
1904 &iter_array, "leap"))
1908 if (!wpa_dbus_dict_end_string_array(&iter_dict,
1916 if (!wpa_dbus_dict_append_string_array(&iter_dict, "Scan", scans,
1917 sizeof(scans) / sizeof(char *)))
1921 if (res < 0 || !(capa.flags & WPA_DRIVER_FLAGS_AP))
1922 n--; /* exclude ap mode if it is not supported by the driver */
1923 if (!wpa_dbus_dict_append_string_array(&iter_dict, "Modes", modes, n))
1926 if (!wpa_dbus_dict_close_write(&variant_iter, &iter_dict))
1928 if (!dbus_message_iter_close_container(&iter, &variant_iter))
1935 dbus_message_unref(reply);
1937 return dbus_message_new_error(message, DBUS_ERROR_NO_MEMORY, NULL);
1942 * wpas_dbus_getter_state - Get interface state
1943 * @message: Pointer to incoming dbus message
1944 * @wpa_s: wpa_supplicant structure for a network interface
1945 * Returns: A dbus message containing a STRING representing the current
1948 * Getter for "State" property.
1950 DBusMessage * wpas_dbus_getter_state(DBusMessage *message,
1951 struct wpa_supplicant *wpa_s)
1953 DBusMessage *reply = NULL;
1954 const char *str_state;
1955 char *state_ls, *tmp;
1957 str_state = wpa_supplicant_state_txt(wpa_s->wpa_state);
1959 /* make state string lowercase to fit new DBus API convention
1961 state_ls = tmp = os_strdup(str_state);
1963 return dbus_message_new_error(message, DBUS_ERROR_NO_MEMORY,
1967 *tmp = tolower(*tmp);
1971 reply = wpas_dbus_simple_property_getter(message, DBUS_TYPE_STRING,
1981 * wpas_dbus_new_iface_get_scanning - Get interface scanning state
1982 * @message: Pointer to incoming dbus message
1983 * @wpa_s: wpa_supplicant structure for a network interface
1984 * Returns: A dbus message containing whether the interface is scanning
1986 * Getter for "scanning" property.
1988 DBusMessage * wpas_dbus_getter_scanning(DBusMessage *message,
1989 struct wpa_supplicant *wpa_s)
1991 dbus_bool_t scanning = wpa_s->scanning ? TRUE : FALSE;
1992 return wpas_dbus_simple_property_getter(message, DBUS_TYPE_BOOLEAN,
1998 * wpas_dbus_getter_ap_scan - Control roaming mode
1999 * @message: Pointer to incoming dbus message
2000 * @wpa_s: wpa_supplicant structure for a network interface
2001 * Returns: A message containong value of ap_scan variable
2003 * Getter function for "ApScan" property.
2005 DBusMessage * wpas_dbus_getter_ap_scan(DBusMessage *message,
2006 struct wpa_supplicant *wpa_s)
2008 dbus_uint32_t ap_scan = wpa_s->conf->ap_scan;
2009 return wpas_dbus_simple_property_getter(message, DBUS_TYPE_UINT32,
2015 * wpas_dbus_setter_ap_scan - Control roaming mode
2016 * @message: Pointer to incoming dbus message
2017 * @wpa_s: wpa_supplicant structure for a network interface
2020 * Setter function for "ApScan" property.
2022 DBusMessage * wpas_dbus_setter_ap_scan(DBusMessage *message,
2023 struct wpa_supplicant *wpa_s)
2025 DBusMessage *reply = NULL;
2026 dbus_uint32_t ap_scan;
2028 reply = wpas_dbus_simple_property_setter(message, DBUS_TYPE_UINT32,
2033 if (wpa_supplicant_set_ap_scan(wpa_s, ap_scan)) {
2034 return wpas_dbus_error_invalid_args(
2035 message, "ap_scan must equal 0, 1 or 2");
2042 * wpas_dbus_getter_ifname - Get interface name
2043 * @message: Pointer to incoming dbus message
2044 * @wpa_s: wpa_supplicant structure for a network interface
2045 * Returns: A dbus message containing a name of network interface
2046 * associated with with wpa_s
2048 * Getter for "Ifname" property.
2050 DBusMessage * wpas_dbus_getter_ifname(DBusMessage *message,
2051 struct wpa_supplicant *wpa_s)
2053 const char *ifname = wpa_s->ifname;
2054 return wpas_dbus_simple_property_getter(message, DBUS_TYPE_STRING,
2060 * wpas_dbus_getter_driver - Get interface name
2061 * @message: Pointer to incoming dbus message
2062 * @wpa_s: wpa_supplicant structure for a network interface
2063 * Returns: A dbus message containing a name of network interface
2064 * driver associated with with wpa_s
2066 * Getter for "Driver" property.
2068 DBusMessage * wpas_dbus_getter_driver(DBusMessage *message,
2069 struct wpa_supplicant *wpa_s)
2073 if (wpa_s->driver == NULL || wpa_s->driver->name == NULL) {
2074 wpa_printf(MSG_DEBUG, "wpas_dbus_getter_driver[dbus]: "
2075 "wpa_s has no driver set");
2076 return wpas_dbus_error_unknown_error(message, NULL);
2079 driver = wpa_s->driver->name;
2080 return wpas_dbus_simple_property_getter(message, DBUS_TYPE_STRING,
2086 * wpas_dbus_getter_current_bss - Get current bss object path
2087 * @message: Pointer to incoming dbus message
2088 * @wpa_s: wpa_supplicant structure for a network interface
2089 * Returns: A dbus message containing a DBus object path to
2092 * Getter for "CurrentBSS" property.
2094 DBusMessage * wpas_dbus_getter_current_bss(DBusMessage *message,
2095 struct wpa_supplicant *wpa_s)
2098 char path_buf[WPAS_DBUS_OBJECT_PATH_MAX], *bss_obj_path = path_buf;
2100 if (wpa_s->current_bss)
2101 os_snprintf(bss_obj_path, WPAS_DBUS_OBJECT_PATH_MAX,
2102 "%s/" WPAS_DBUS_NEW_BSSIDS_PART "/%u",
2103 wpa_s->dbus_new_path, wpa_s->current_bss->id);
2105 os_snprintf(bss_obj_path, WPAS_DBUS_OBJECT_PATH_MAX, "/");
2107 reply = wpas_dbus_simple_property_getter(message,
2108 DBUS_TYPE_OBJECT_PATH,
2116 * wpas_dbus_getter_current_network - Get current network object path
2117 * @message: Pointer to incoming dbus message
2118 * @wpa_s: wpa_supplicant structure for a network interface
2119 * Returns: A dbus message containing a DBus object path to
2122 * Getter for "CurrentNetwork" property.
2124 DBusMessage * wpas_dbus_getter_current_network(DBusMessage *message,
2125 struct wpa_supplicant *wpa_s)
2128 char path_buf[WPAS_DBUS_OBJECT_PATH_MAX], *net_obj_path = path_buf;
2130 if (wpa_s->current_ssid)
2131 os_snprintf(net_obj_path, WPAS_DBUS_OBJECT_PATH_MAX,
2132 "%s/" WPAS_DBUS_NEW_NETWORKS_PART "/%u",
2133 wpa_s->dbus_new_path, wpa_s->current_ssid->id);
2135 os_snprintf(net_obj_path, WPAS_DBUS_OBJECT_PATH_MAX, "/");
2137 reply = wpas_dbus_simple_property_getter(message,
2138 DBUS_TYPE_OBJECT_PATH,
2146 * wpas_dbus_getter_bridge_ifname - Get interface name
2147 * @message: Pointer to incoming dbus message
2148 * @wpa_s: wpa_supplicant structure for a network interface
2149 * Returns: A dbus message containing a name of bridge network
2150 * interface associated with with wpa_s
2152 * Getter for "BridgeIfname" property.
2154 DBusMessage * wpas_dbus_getter_bridge_ifname(DBusMessage *message,
2155 struct wpa_supplicant *wpa_s)
2157 const char *bridge_ifname = NULL;
2159 bridge_ifname = wpa_s->bridge_ifname;
2160 if (bridge_ifname == NULL) {
2161 wpa_printf(MSG_ERROR, "wpas_dbus_getter_bridge_ifname[dbus]: "
2162 "wpa_s has no bridge interface name set");
2163 return wpas_dbus_error_unknown_error(message, NULL);
2166 return wpas_dbus_simple_property_getter(message, DBUS_TYPE_STRING,
2172 * wpas_dbus_getter_bsss - Get array of BSSs objects
2173 * @message: Pointer to incoming dbus message
2174 * @wpa_s: wpa_supplicant structure for a network interface
2175 * Returns: a dbus message containing an array of all known BSS objects
2178 * Getter for "BSSs" property.
2180 DBusMessage * wpas_dbus_getter_bsss(DBusMessage *message,
2181 struct wpa_supplicant *wpa_s)
2183 DBusMessage *reply = NULL;
2184 struct wpa_bss *bss;
2188 paths = os_zalloc(wpa_s->num_bss * sizeof(char *));
2190 return dbus_message_new_error(message, DBUS_ERROR_NO_MEMORY,
2194 /* Loop through scan results and append each result's object path */
2195 dl_list_for_each(bss, &wpa_s->bss_id, struct wpa_bss, list_id) {
2196 paths[i] = os_zalloc(WPAS_DBUS_OBJECT_PATH_MAX);
2197 if (paths[i] == NULL) {
2198 reply = dbus_message_new_error(message,
2199 DBUS_ERROR_NO_MEMORY,
2203 /* Construct the object path for this BSS. */
2204 os_snprintf(paths[i++], WPAS_DBUS_OBJECT_PATH_MAX,
2205 "%s/" WPAS_DBUS_NEW_BSSIDS_PART "/%u",
2206 wpa_s->dbus_new_path, bss->id);
2209 reply = wpas_dbus_simple_array_property_getter(message,
2210 DBUS_TYPE_OBJECT_PATH,
2211 paths, wpa_s->num_bss);
2215 os_free(paths[--i]);
2222 * wpas_dbus_getter_networks - Get array of networks objects
2223 * @message: Pointer to incoming dbus message
2224 * @wpa_s: wpa_supplicant structure for a network interface
2225 * Returns: a dbus message containing an array of all configured
2226 * networks dbus object paths.
2228 * Getter for "Networks" property.
2230 DBusMessage * wpas_dbus_getter_networks(DBusMessage *message,
2231 struct wpa_supplicant *wpa_s)
2233 DBusMessage *reply = NULL;
2234 struct wpa_ssid *ssid;
2236 unsigned int i = 0, num = 0;
2238 if (wpa_s->conf == NULL) {
2239 wpa_printf(MSG_ERROR, "wpas_dbus_getter_networks[dbus]: "
2240 "An error occurred getting networks list.");
2241 return wpas_dbus_error_unknown_error(message, NULL);
2244 for (ssid = wpa_s->conf->ssid; ssid; ssid = ssid->next)
2247 paths = os_zalloc(num * sizeof(char *));
2249 return dbus_message_new_error(message, DBUS_ERROR_NO_MEMORY,
2253 /* Loop through configured networks and append object path of each */
2254 for (ssid = wpa_s->conf->ssid; ssid; ssid = ssid->next) {
2255 paths[i] = os_zalloc(WPAS_DBUS_OBJECT_PATH_MAX);
2256 if (paths[i] == NULL) {
2257 reply = dbus_message_new_error(message,
2258 DBUS_ERROR_NO_MEMORY,
2263 /* Construct the object path for this network. */
2264 os_snprintf(paths[i++], WPAS_DBUS_OBJECT_PATH_MAX,
2265 "%s/" WPAS_DBUS_NEW_NETWORKS_PART "/%d",
2266 wpa_s->dbus_new_path, ssid->id);
2269 reply = wpas_dbus_simple_array_property_getter(message,
2270 DBUS_TYPE_OBJECT_PATH,
2275 os_free(paths[--i]);
2282 * wpas_dbus_getter_blobs - Get all blobs defined for this interface
2283 * @message: Pointer to incoming dbus message
2284 * @wpa_s: wpa_supplicant structure for a network interface
2285 * Returns: a dbus message containing a dictionary of pairs (blob_name, blob)
2287 * Getter for "Blobs" property.
2289 DBusMessage * wpas_dbus_getter_blobs(DBusMessage *message,
2290 struct wpa_supplicant *wpa_s)
2292 DBusMessage *reply = NULL;
2293 DBusMessageIter iter, variant_iter, dict_iter, entry_iter, array_iter;
2294 struct wpa_config_blob *blob;
2296 if (message == NULL)
2297 reply = dbus_message_new(DBUS_MESSAGE_TYPE_SIGNAL);
2299 reply = dbus_message_new_method_return(message);
2301 return dbus_message_new_error(message, DBUS_ERROR_NO_MEMORY,
2304 dbus_message_iter_init_append(reply, &iter);
2306 if (!dbus_message_iter_open_container(&iter, DBUS_TYPE_VARIANT,
2307 "a{say}", &variant_iter) ||
2308 !dbus_message_iter_open_container(&variant_iter, DBUS_TYPE_ARRAY,
2309 "{say}", &dict_iter)) {
2310 dbus_message_unref(reply);
2311 return dbus_message_new_error(message, DBUS_ERROR_NO_MEMORY,
2315 blob = wpa_s->conf->blobs;
2317 if (!dbus_message_iter_open_container(&dict_iter,
2318 DBUS_TYPE_DICT_ENTRY,
2319 NULL, &entry_iter) ||
2320 !dbus_message_iter_append_basic(&entry_iter,
2323 !dbus_message_iter_open_container(&entry_iter,
2325 DBUS_TYPE_BYTE_AS_STRING,
2327 !dbus_message_iter_append_fixed_array(&array_iter,
2331 !dbus_message_iter_close_container(&entry_iter,
2333 !dbus_message_iter_close_container(&dict_iter,
2335 dbus_message_unref(reply);
2336 return dbus_message_new_error(message,
2337 DBUS_ERROR_NO_MEMORY,
2344 if (!dbus_message_iter_close_container(&variant_iter, &dict_iter) ||
2345 !dbus_message_iter_close_container(&iter, &variant_iter)) {
2346 dbus_message_unref(reply);
2347 return dbus_message_new_error(message, DBUS_ERROR_NO_MEMORY,
2356 * wpas_dbus_getter_bss_bssid - Return the BSSID of a BSS
2357 * @message: Pointer to incoming dbus message
2358 * @bss: a pair of interface describing structure and bss's id
2359 * Returns: a dbus message containing the bssid for the requested bss
2361 * Getter for "BSSID" property.
2363 DBusMessage * wpas_dbus_getter_bss_bssid(DBusMessage *message,
2364 struct bss_handler_args *bss)
2366 struct wpa_bss *res = wpa_bss_get_id(bss->wpa_s, bss->id);
2369 wpa_printf(MSG_ERROR, "wpas_dbus_getter_bss_bssid[dbus]: no "
2370 "bss with id %d found", bss->id);
2374 return wpas_dbus_simple_array_property_getter(message, DBUS_TYPE_BYTE,
2375 res->bssid, ETH_ALEN);
2380 * wpas_dbus_getter_bss_ssid - Return the SSID of a BSS
2381 * @message: Pointer to incoming dbus message
2382 * @bss: a pair of interface describing structure and bss's id
2383 * Returns: a dbus message containing the ssid for the requested bss
2385 * Getter for "SSID" property.
2387 DBusMessage * wpas_dbus_getter_bss_ssid(DBusMessage *message,
2388 struct bss_handler_args *bss)
2390 struct wpa_bss *res = wpa_bss_get_id(bss->wpa_s, bss->id);
2393 wpa_printf(MSG_ERROR, "wpas_dbus_getter_bss_ssid[dbus]: no "
2394 "bss with id %d found", bss->id);
2398 return wpas_dbus_simple_array_property_getter(message, DBUS_TYPE_BYTE,
2405 * wpas_dbus_getter_bss_privacy - Return the privacy flag of a BSS
2406 * @message: Pointer to incoming dbus message
2407 * @bss: a pair of interface describing structure and bss's id
2408 * Returns: a dbus message containing the privacy flag value of requested bss
2410 * Getter for "Privacy" property.
2412 DBusMessage * wpas_dbus_getter_bss_privacy(DBusMessage *message,
2413 struct bss_handler_args *bss)
2415 struct wpa_bss *res = wpa_bss_get_id(bss->wpa_s, bss->id);
2416 dbus_bool_t privacy;
2419 wpa_printf(MSG_ERROR, "wpas_dbus_getter_bss_privacy[dbus]: no "
2420 "bss with id %d found", bss->id);
2424 privacy = res->caps && IEEE80211_CAP_PRIVACY ? TRUE : FALSE;
2425 return wpas_dbus_simple_property_getter(message, DBUS_TYPE_BOOLEAN,
2431 * wpas_dbus_getter_bss_mode - Return the mode of a BSS
2432 * @message: Pointer to incoming dbus message
2433 * @bss: a pair of interface describing structure and bss's id
2434 * Returns: a dbus message containing the mode of requested bss
2436 * Getter for "Mode" property.
2438 DBusMessage * wpas_dbus_getter_bss_mode(DBusMessage *message,
2439 struct bss_handler_args *bss)
2441 struct wpa_bss *res = wpa_bss_get_id(bss->wpa_s, bss->id);
2445 wpa_printf(MSG_ERROR, "wpas_dbus_getter_bss_mode[dbus]: no "
2446 "bss with id %d found", bss->id);
2450 if (res->caps & IEEE80211_CAP_IBSS)
2453 mode = "infrastructure";
2455 return wpas_dbus_simple_property_getter(message, DBUS_TYPE_STRING,
2461 * wpas_dbus_getter_bss_level - Return the signal strength of a BSS
2462 * @message: Pointer to incoming dbus message
2463 * @bss: a pair of interface describing structure and bss's id
2464 * Returns: a dbus message containing the signal strength of requested bss
2466 * Getter for "Level" property.
2468 DBusMessage * wpas_dbus_getter_bss_signal(DBusMessage *message,
2469 struct bss_handler_args *bss)
2471 struct wpa_bss *res = wpa_bss_get_id(bss->wpa_s, bss->id);
2474 wpa_printf(MSG_ERROR, "wpas_dbus_getter_bss_signal[dbus]: no "
2475 "bss with id %d found", bss->id);
2479 return wpas_dbus_simple_property_getter(message, DBUS_TYPE_INT16,
2485 * wpas_dbus_getter_bss_frequency - Return the frequency of a BSS
2486 * @message: Pointer to incoming dbus message
2487 * @bss: a pair of interface describing structure and bss's id
2488 * Returns: a dbus message containing the frequency of requested bss
2490 * Getter for "Frequency" property.
2492 DBusMessage * wpas_dbus_getter_bss_frequency(DBusMessage *message,
2493 struct bss_handler_args *bss)
2495 struct wpa_bss *res = wpa_bss_get_id(bss->wpa_s, bss->id);
2498 wpa_printf(MSG_ERROR, "wpas_dbus_getter_bss_frequency[dbus]: "
2499 "no bss with id %d found", bss->id);
2503 return wpas_dbus_simple_property_getter(message, DBUS_TYPE_UINT16,
2508 static int cmp_u8s_desc(const void *a, const void *b)
2510 return (*(u8 *) b - *(u8 *) a);
2515 * wpas_dbus_getter_bss_rates - Return available bit rates of a BSS
2516 * @message: Pointer to incoming dbus message
2517 * @bss: a pair of interface describing structure and bss's id
2518 * Returns: a dbus message containing sorted array of bit rates
2520 * Getter for "Rates" property.
2522 DBusMessage * wpas_dbus_getter_bss_rates(DBusMessage *message,
2523 struct bss_handler_args *bss)
2526 struct wpa_bss *res = wpa_bss_get_id(bss->wpa_s, bss->id);
2527 u8 *ie_rates = NULL;
2532 wpa_printf(MSG_ERROR, "wpas_dbus_getter_bss_rates[dbus]: "
2533 "no bss with id %d found", bss->id);
2537 rates_num = wpa_bss_get_bit_rates(res, &ie_rates);
2541 qsort(ie_rates, rates_num, 1, cmp_u8s_desc);
2543 real_rates = os_malloc(sizeof(u32) * rates_num);
2546 return dbus_message_new_error(message, DBUS_ERROR_NO_MEMORY,
2550 for (i = 0; i < rates_num; i++)
2551 real_rates[i] = ie_rates[i] * 500000;
2553 reply = wpas_dbus_simple_array_property_getter(message,
2555 real_rates, rates_num);
2558 os_free(real_rates);
2564 * wpas_dbus_getter_bss_wpaie - Return the WPA IE of a BSS
2565 * @message: Pointer to incoming dbus message
2566 * @bss: a pair of interface describing structure and bss's id
2567 * Returns: a dbus message containing the WPA information elements
2570 * Getter for "WPAIE" property.
2572 DBusMessage * wpas_dbus_getter_bss_wpaie(DBusMessage *message,
2573 struct bss_handler_args *bss)
2575 struct wpa_bss *res = wpa_bss_get_id(bss->wpa_s, bss->id);
2579 wpa_printf(MSG_ERROR, "wpas_dbus_getter_bss_wpaie[dbus]: no "
2580 "bss with id %d found", bss->id);
2584 ie = wpa_bss_get_vendor_ie(res, WPA_IE_VENDOR_TYPE);
2587 return wpas_dbus_simple_array_property_getter(message, DBUS_TYPE_BYTE,
2593 * wpas_dbus_getter_bss_rsnie - Return the RSN IE of a BSS
2594 * @message: Pointer to incoming dbus message
2595 * @bss: a pair of interface describing structure and bss's id
2596 * Returns: a dbus message containing the RSN information elements
2599 * Getter for "RSNIE" property.
2601 DBusMessage * wpas_dbus_getter_bss_rsnie(DBusMessage *message,
2602 struct bss_handler_args *bss)
2604 struct wpa_bss *res = wpa_bss_get_id(bss->wpa_s, bss->id);
2608 wpa_printf(MSG_ERROR, "wpas_dbus_getter_bss_rsnie[dbus]: no "
2609 "bss with id %d found", bss->id);
2613 ie = wpa_bss_get_ie(res, WLAN_EID_RSN);
2616 return wpas_dbus_simple_array_property_getter(message, DBUS_TYPE_BYTE,
2622 * wpas_dbus_getter_bss_wpsie - Return the WPS IE of a BSS
2623 * @message: Pointer to incoming dbus message
2624 * @bss: a pair of interface describing structure and bss's id
2625 * Returns: a dbus message containing the WPS information elements
2628 * Getter for "WPSIE" property.
2630 DBusMessage * wpas_dbus_getter_bss_wpsie(DBusMessage *message,
2631 struct bss_handler_args *bss)
2633 struct wpa_bss *res = wpa_bss_get_id(bss->wpa_s, bss->id);
2637 wpa_printf(MSG_ERROR, "wpas_dbus_getter_bss_wpsie[dbus]: no "
2638 "bss with id %d found", bss->id);
2642 ie = wpa_bss_get_vendor_ie(res, WPS_IE_VENDOR_TYPE);
2645 return wpas_dbus_simple_array_property_getter(message, DBUS_TYPE_BYTE,
2651 * wpas_dbus_getter_enabled - Check whether network is enabled or disabled
2652 * @message: Pointer to incoming dbus message
2653 * @wpas_dbus_setter_enabled: wpa_supplicant structure for a network interface
2654 * and wpa_ssid structure for a configured network
2655 * Returns: DBus message with boolean indicating state of configured network
2656 * or DBus error on failure
2658 * Getter for "enabled" property of a configured network.
2660 DBusMessage * wpas_dbus_getter_enabled(DBusMessage *message,
2661 struct network_handler_args *net)
2663 dbus_bool_t enabled = net->ssid->disabled ? FALSE : TRUE;
2664 return wpas_dbus_simple_property_getter(message, DBUS_TYPE_BOOLEAN,
2670 * wpas_dbus_setter_enabled - Mark a configured network as enabled or disabled
2671 * @message: Pointer to incoming dbus message
2672 * @wpas_dbus_setter_enabled: wpa_supplicant structure for a network interface
2673 * and wpa_ssid structure for a configured network
2674 * Returns: NULL indicating success or DBus error on failure
2676 * Setter for "Enabled" property of a configured network.
2678 DBusMessage * wpas_dbus_setter_enabled(DBusMessage *message,
2679 struct network_handler_args *net)
2681 DBusMessage *reply = NULL;
2683 struct wpa_supplicant *wpa_s;
2684 struct wpa_ssid *ssid;
2688 reply = wpas_dbus_simple_property_setter(message, DBUS_TYPE_BOOLEAN,
2698 wpa_supplicant_enable_network(wpa_s, ssid);
2700 wpa_supplicant_disable_network(wpa_s, ssid);
2707 * wpas_dbus_getter_network_properties - Get options for a configured network
2708 * @message: Pointer to incoming dbus message
2709 * @net: wpa_supplicant structure for a network interface and
2710 * wpa_ssid structure for a configured network
2711 * Returns: DBus message with network properties or DBus error on failure
2713 * Getter for "Properties" property of a configured network.
2715 DBusMessage * wpas_dbus_getter_network_properties(
2716 DBusMessage *message, struct network_handler_args *net)
2718 DBusMessage *reply = NULL;
2719 DBusMessageIter iter, variant_iter, dict_iter;
2721 char **props = wpa_config_get_all(net->ssid, 0);
2723 return dbus_message_new_error(message, DBUS_ERROR_NO_MEMORY,
2726 if (message == NULL)
2727 reply = dbus_message_new(DBUS_MESSAGE_TYPE_SIGNAL);
2729 reply = dbus_message_new_method_return(message);
2731 reply = dbus_message_new_error(message, DBUS_ERROR_NO_MEMORY,
2736 dbus_message_iter_init_append(reply, &iter);
2738 if (!dbus_message_iter_open_container(&iter, DBUS_TYPE_VARIANT,
2739 "a{sv}", &variant_iter) ||
2740 !wpa_dbus_dict_open_write(&variant_iter, &dict_iter)) {
2741 dbus_message_unref(reply);
2742 reply = dbus_message_new_error(message, DBUS_ERROR_NO_MEMORY,
2749 if (!wpa_dbus_dict_append_string(&dict_iter, *iterator,
2751 dbus_message_unref(reply);
2752 reply = dbus_message_new_error(message,
2753 DBUS_ERROR_NO_MEMORY,
2761 if (!wpa_dbus_dict_close_write(&variant_iter, &dict_iter) ||
2762 !dbus_message_iter_close_container(&iter, &variant_iter)) {
2763 dbus_message_unref(reply);
2764 reply = dbus_message_new_error(message, DBUS_ERROR_NO_MEMORY,
2781 * wpas_dbus_setter_network_properties - Set options for a configured network
2782 * @message: Pointer to incoming dbus message
2783 * @net: wpa_supplicant structure for a network interface and
2784 * wpa_ssid structure for a configured network
2785 * Returns: NULL indicating success or DBus error on failure
2787 * Setter for "Properties" property of a configured network.
2789 DBusMessage * wpas_dbus_setter_network_properties(
2790 DBusMessage *message, struct network_handler_args *net)
2792 struct wpa_ssid *ssid = net->ssid;
2794 DBusMessage *reply = NULL;
2795 DBusMessageIter iter, variant_iter;
2797 dbus_message_iter_init(message, &iter);
2799 dbus_message_iter_next(&iter);
2800 dbus_message_iter_next(&iter);
2802 dbus_message_iter_recurse(&iter, &variant_iter);
2804 reply = set_network_properties(message, ssid, &variant_iter);
2806 wpa_printf(MSG_DEBUG, "dbus control interface couldn't set "
2807 "network properties");