2 * WPA Supplicant / dbus-based control interface
3 * Copyright (c) 2006, Dan Williams <dcbw@redhat.com> and Red Hat, Inc.
4 * Copyright (c) 2009-2010, Witold Sowa <witold.sowa@gmail.com>
5 * Copyright (c) 2009-2015, Jouni Malinen <j@w1.fi>
7 * This software may be distributed under the terms of the BSD license.
8 * See README for more details.
14 #include "common/ieee802_11_defs.h"
15 #include "eap_peer/eap_methods.h"
16 #include "eapol_supp/eapol_supp_sm.h"
17 #include "rsn_supp/wpa.h"
18 #include "../config.h"
19 #include "../wpa_supplicant_i.h"
20 #include "../driver_i.h"
21 #include "../notify.h"
24 #include "../autoscan.h"
25 #include "dbus_new_helpers.h"
27 #include "dbus_new_handlers.h"
28 #include "dbus_dict_helpers.h"
29 #include "dbus_common_i.h"
30 #include "drivers/driver.h"
32 static const char * const debug_strings[] = {
33 "excessive", "msgdump", "debug", "info", "warning", "error", NULL
38 * wpas_dbus_error_unknown_error - Return a new UnknownError error message
39 * @message: Pointer to incoming dbus message this error refers to
40 * @arg: Optional string appended to error message
41 * Returns: a dbus error message
43 * Convenience function to create and return an UnknownError
45 DBusMessage * wpas_dbus_error_unknown_error(DBusMessage *message,
48 return dbus_message_new_error(message, WPAS_DBUS_ERROR_UNKNOWN_ERROR,
54 * wpas_dbus_error_iface_unknown - Return a new invalid interface error message
55 * @message: Pointer to incoming dbus message this error refers to
56 * Returns: A dbus error message
58 * Convenience function to create and return an invalid interface error
60 static DBusMessage * wpas_dbus_error_iface_unknown(DBusMessage *message)
62 return dbus_message_new_error(
63 message, WPAS_DBUS_ERROR_IFACE_UNKNOWN,
64 "wpa_supplicant knows nothing about this interface.");
69 * wpas_dbus_error_network_unknown - Return a new NetworkUnknown error message
70 * @message: Pointer to incoming dbus message this error refers to
71 * Returns: a dbus error message
73 * Convenience function to create and return an invalid network error
75 static DBusMessage * wpas_dbus_error_network_unknown(DBusMessage *message)
77 return dbus_message_new_error(
78 message, WPAS_DBUS_ERROR_NETWORK_UNKNOWN,
79 "There is no such a network in this interface.");
84 * wpas_dbus_error_invalid_args - Return a new InvalidArgs error message
85 * @message: Pointer to incoming dbus message this error refers to
86 * Returns: a dbus error message
88 * Convenience function to create and return an invalid options error
90 DBusMessage * wpas_dbus_error_invalid_args(DBusMessage *message,
95 reply = dbus_message_new_error(
96 message, WPAS_DBUS_ERROR_INVALID_ARGS,
97 "Did not receive correct message arguments.");
99 dbus_message_append_args(reply, DBUS_TYPE_STRING, &arg,
107 * wpas_dbus_error_scan_error - Return a new ScanError error message
108 * @message: Pointer to incoming dbus message this error refers to
109 * @error: Optional string to be used as the error message
110 * Returns: a dbus error message
112 * Convenience function to create and return a scan error
114 static DBusMessage * wpas_dbus_error_scan_error(DBusMessage *message,
117 return dbus_message_new_error(message,
118 WPAS_DBUS_ERROR_IFACE_SCAN_ERROR,
123 DBusMessage * wpas_dbus_error_no_memory(DBusMessage *message)
125 wpa_printf(MSG_DEBUG, "dbus: Failed to allocate memory");
126 return dbus_message_new_error(message, DBUS_ERROR_NO_MEMORY, NULL);
130 static const char * const dont_quote[] = {
131 "key_mgmt", "proto", "pairwise", "auth_alg", "group", "eap",
132 "opensc_engine_path", "pkcs11_engine_path", "pkcs11_module_path",
133 "bssid", "scan_freq", "freq_list", NULL
136 static dbus_bool_t should_quote_opt(const char *key)
140 while (dont_quote[i] != NULL) {
141 if (os_strcmp(key, dont_quote[i]) == 0)
149 * get_iface_by_dbus_path - Get a new network interface
150 * @global: Pointer to global data from wpa_supplicant_init()
151 * @path: Pointer to a dbus object path representing an interface
152 * Returns: Pointer to the interface or %NULL if not found
154 static struct wpa_supplicant * get_iface_by_dbus_path(
155 struct wpa_global *global, const char *path)
157 struct wpa_supplicant *wpa_s;
159 for (wpa_s = global->ifaces; wpa_s; wpa_s = wpa_s->next) {
160 if (wpa_s->dbus_new_path &&
161 os_strcmp(wpa_s->dbus_new_path, path) == 0)
169 * set_network_properties - Set properties of a configured network
170 * @wpa_s: wpa_supplicant structure for a network interface
171 * @ssid: wpa_ssid structure for a configured network
172 * @iter: DBus message iterator containing dictionary of network
174 * @error: On failure, an error describing the failure
175 * Returns: TRUE if the request succeeds, FALSE if it failed
177 * Sets network configuration with parameters given id DBus dictionary
179 dbus_bool_t set_network_properties(struct wpa_supplicant *wpa_s,
180 struct wpa_ssid *ssid,
181 DBusMessageIter *iter,
184 struct wpa_dbus_dict_entry entry = { .type = DBUS_TYPE_STRING };
185 DBusMessageIter iter_dict;
188 if (!wpa_dbus_dict_open_read(iter, &iter_dict, error))
191 while (wpa_dbus_dict_has_dict_entry(&iter_dict)) {
195 if (!wpa_dbus_dict_get_entry(&iter_dict, &entry))
199 if (entry.type == DBUS_TYPE_ARRAY &&
200 entry.array_type == DBUS_TYPE_BYTE) {
201 if (entry.array_len <= 0)
204 size = entry.array_len * 2 + 1;
205 value = os_zalloc(size);
209 ret = wpa_snprintf_hex(value, size,
210 (u8 *) entry.bytearray_value,
214 } else if (entry.type == DBUS_TYPE_STRING) {
215 if (should_quote_opt(entry.key)) {
216 size = os_strlen(entry.str_value);
221 value = os_zalloc(size);
225 ret = os_snprintf(value, size, "\"%s\"",
227 if (os_snprintf_error(size, ret))
230 value = os_strdup(entry.str_value);
234 } else if (entry.type == DBUS_TYPE_UINT32) {
235 value = os_zalloc(size);
239 ret = os_snprintf(value, size, "%u",
241 if (os_snprintf_error(size, ret))
243 } else if (entry.type == DBUS_TYPE_INT32) {
244 value = os_zalloc(size);
248 ret = os_snprintf(value, size, "%d",
250 if (os_snprintf_error(size, ret))
255 if (wpa_config_set(ssid, entry.key, value, 0) < 0)
258 if (os_strcmp(entry.key, "bssid") != 0 &&
259 os_strcmp(entry.key, "priority") != 0)
260 wpa_sm_pmksa_cache_flush(wpa_s->wpa, ssid);
262 if (wpa_s->current_ssid == ssid ||
263 wpa_s->current_ssid == NULL) {
265 * Invalidate the EAP session cache if anything in the
266 * current or previously used configuration changes.
268 eapol_sm_invalidate_cached_session(wpa_s->eapol);
271 if ((os_strcmp(entry.key, "psk") == 0 &&
272 value[0] == '"' && ssid->ssid_len) ||
273 (os_strcmp(entry.key, "ssid") == 0 && ssid->passphrase))
274 wpa_config_update_psk(ssid);
275 else if (os_strcmp(entry.key, "priority") == 0)
276 wpa_config_update_prio_list(wpa_s->conf);
280 wpa_dbus_dict_entry_clear(&entry);
287 wpa_dbus_dict_entry_clear(&entry);
288 dbus_set_error_const(error, DBUS_ERROR_INVALID_ARGS,
289 "invalid message format");
295 * wpas_dbus_simple_property_getter - Get basic type property
296 * @iter: Message iter to use when appending arguments
297 * @type: DBus type of property (must be basic type)
298 * @val: pointer to place holding property value
299 * @error: On failure an error describing the failure
300 * Returns: TRUE if the request was successful, FALSE if it failed
302 * Generic getter for basic type properties. Type is required to be basic.
304 dbus_bool_t wpas_dbus_simple_property_getter(DBusMessageIter *iter,
309 DBusMessageIter variant_iter;
311 if (!dbus_type_is_basic(type)) {
312 dbus_set_error(error, DBUS_ERROR_FAILED,
313 "%s: given type is not basic", __func__);
317 if (!dbus_message_iter_open_container(iter, DBUS_TYPE_VARIANT,
318 wpa_dbus_type_as_string(type),
320 !dbus_message_iter_append_basic(&variant_iter, type, val) ||
321 !dbus_message_iter_close_container(iter, &variant_iter)) {
322 dbus_set_error(error, DBUS_ERROR_FAILED,
323 "%s: error constructing reply", __func__);
332 * wpas_dbus_simple_property_setter - Set basic type property
333 * @message: Pointer to incoming dbus message
334 * @type: DBus type of property (must be basic type)
335 * @val: pointer to place where value being set will be stored
336 * Returns: TRUE if the request was successful, FALSE if it failed
338 * Generic setter for basic type properties. Type is required to be basic.
340 dbus_bool_t wpas_dbus_simple_property_setter(DBusMessageIter *iter,
342 const int type, void *val)
344 DBusMessageIter variant_iter;
346 if (!dbus_type_is_basic(type)) {
347 dbus_set_error(error, DBUS_ERROR_FAILED,
348 "%s: given type is not basic", __func__);
352 /* Look at the new value */
353 dbus_message_iter_recurse(iter, &variant_iter);
354 if (dbus_message_iter_get_arg_type(&variant_iter) != type) {
355 dbus_set_error_const(error, DBUS_ERROR_FAILED,
356 "wrong property type");
359 dbus_message_iter_get_basic(&variant_iter, val);
366 * wpas_dbus_simple_array_property_getter - Get array type property
367 * @iter: Pointer to incoming dbus message iterator
368 * @type: DBus type of property array elements (must be basic type)
369 * @array: pointer to array of elements to put into response message
370 * @array_len: length of above array
371 * @error: a pointer to an error to fill on failure
372 * Returns: TRUE if the request succeeded, FALSE if it failed
374 * Generic getter for array type properties. Array elements type is
375 * required to be basic.
377 dbus_bool_t wpas_dbus_simple_array_property_getter(DBusMessageIter *iter,
383 DBusMessageIter variant_iter, array_iter;
384 char type_str[] = "a?"; /* ? will be replaced with subtype letter; */
385 const char *sub_type_str;
386 size_t element_size, i;
388 if (!dbus_type_is_basic(type)) {
389 dbus_set_error(error, DBUS_ERROR_FAILED,
390 "%s: given type is not basic", __func__);
394 sub_type_str = wpa_dbus_type_as_string(type);
395 type_str[1] = sub_type_str[0];
397 if (!dbus_message_iter_open_container(iter, DBUS_TYPE_VARIANT,
398 type_str, &variant_iter) ||
399 !dbus_message_iter_open_container(&variant_iter, DBUS_TYPE_ARRAY,
400 sub_type_str, &array_iter)) {
401 dbus_set_error(error, DBUS_ERROR_FAILED,
402 "%s: failed to construct message", __func__);
408 case DBUS_TYPE_BOOLEAN:
411 case DBUS_TYPE_INT16:
412 case DBUS_TYPE_UINT16:
413 element_size = sizeof(uint16_t);
415 case DBUS_TYPE_INT32:
416 case DBUS_TYPE_UINT32:
417 element_size = sizeof(uint32_t);
419 case DBUS_TYPE_INT64:
420 case DBUS_TYPE_UINT64:
421 element_size = sizeof(uint64_t);
423 case DBUS_TYPE_DOUBLE:
424 element_size = sizeof(double);
426 case DBUS_TYPE_STRING:
427 case DBUS_TYPE_OBJECT_PATH:
428 element_size = sizeof(char *);
431 dbus_set_error(error, DBUS_ERROR_FAILED,
432 "%s: unknown element type %d", __func__, type);
436 for (i = 0; i < array_len; i++) {
437 if (!dbus_message_iter_append_basic(&array_iter, type,
438 array + i * element_size)) {
439 dbus_set_error(error, DBUS_ERROR_FAILED,
440 "%s: failed to construct message 2.5",
446 if (!dbus_message_iter_close_container(&variant_iter, &array_iter) ||
447 !dbus_message_iter_close_container(iter, &variant_iter)) {
448 dbus_set_error(error, DBUS_ERROR_FAILED,
449 "%s: failed to construct message 3", __func__);
458 * wpas_dbus_simple_array_array_property_getter - Get array array type property
459 * @iter: Pointer to incoming dbus message iterator
460 * @type: DBus type of property array elements (must be basic type)
461 * @array: pointer to array of elements to put into response message
462 * @array_len: length of above array
463 * @error: a pointer to an error to fill on failure
464 * Returns: TRUE if the request succeeded, FALSE if it failed
466 * Generic getter for array type properties. Array elements type is
467 * required to be basic.
469 dbus_bool_t wpas_dbus_simple_array_array_property_getter(DBusMessageIter *iter,
471 struct wpabuf **array,
475 DBusMessageIter variant_iter, array_iter;
476 char type_str[] = "aa?";
477 char inner_type_str[] = "a?";
478 const char *sub_type_str;
481 if (!dbus_type_is_basic(type)) {
482 dbus_set_error(error, DBUS_ERROR_FAILED,
483 "%s: given type is not basic", __func__);
487 sub_type_str = wpa_dbus_type_as_string(type);
488 type_str[2] = sub_type_str[0];
489 inner_type_str[1] = sub_type_str[0];
491 if (!dbus_message_iter_open_container(iter, DBUS_TYPE_VARIANT,
492 type_str, &variant_iter) ||
493 !dbus_message_iter_open_container(&variant_iter, DBUS_TYPE_ARRAY,
494 inner_type_str, &array_iter)) {
495 dbus_set_error(error, DBUS_ERROR_FAILED,
496 "%s: failed to construct message", __func__);
500 for (i = 0; i < array_len && array[i]; i++) {
501 wpa_dbus_dict_bin_array_add_element(&array_iter,
502 wpabuf_head(array[i]),
503 wpabuf_len(array[i]));
507 if (!dbus_message_iter_close_container(&variant_iter, &array_iter) ||
508 !dbus_message_iter_close_container(iter, &variant_iter)) {
509 dbus_set_error(error, DBUS_ERROR_FAILED,
510 "%s: failed to close message", __func__);
519 * wpas_dbus_handler_create_interface - Request registration of a network iface
520 * @message: Pointer to incoming dbus message
521 * @global: %wpa_supplicant global data structure
522 * Returns: The object path of the new interface object,
523 * or a dbus error message with more information
525 * Handler function for "CreateInterface" method call. Handles requests
526 * by dbus clients to register a network interface that wpa_supplicant
529 DBusMessage * wpas_dbus_handler_create_interface(DBusMessage *message,
530 struct wpa_global *global)
532 DBusMessageIter iter_dict;
533 DBusMessage *reply = NULL;
534 DBusMessageIter iter;
535 struct wpa_dbus_dict_entry entry;
538 char *confname = NULL;
539 char *bridge_ifname = NULL;
541 dbus_message_iter_init(message, &iter);
543 if (!wpa_dbus_dict_open_read(&iter, &iter_dict, NULL))
545 while (wpa_dbus_dict_has_dict_entry(&iter_dict)) {
546 if (!wpa_dbus_dict_get_entry(&iter_dict, &entry))
548 if (os_strcmp(entry.key, "Driver") == 0 &&
549 entry.type == DBUS_TYPE_STRING) {
551 driver = os_strdup(entry.str_value);
552 wpa_dbus_dict_entry_clear(&entry);
555 } else if (os_strcmp(entry.key, "Ifname") == 0 &&
556 entry.type == DBUS_TYPE_STRING) {
558 ifname = os_strdup(entry.str_value);
559 wpa_dbus_dict_entry_clear(&entry);
562 } else if (os_strcmp(entry.key, "ConfigFile") == 0 &&
563 entry.type == DBUS_TYPE_STRING) {
565 confname = os_strdup(entry.str_value);
566 wpa_dbus_dict_entry_clear(&entry);
567 if (confname == NULL)
569 } else if (os_strcmp(entry.key, "BridgeIfname") == 0 &&
570 entry.type == DBUS_TYPE_STRING) {
571 os_free(bridge_ifname);
572 bridge_ifname = os_strdup(entry.str_value);
573 wpa_dbus_dict_entry_clear(&entry);
574 if (bridge_ifname == NULL)
577 wpa_dbus_dict_entry_clear(&entry);
583 goto error; /* Required Ifname argument missing */
586 * Try to get the wpa_supplicant record for this iface, return
587 * an error if we already control it.
589 if (wpa_supplicant_get_iface(global, ifname) != NULL) {
590 reply = dbus_message_new_error(
591 message, WPAS_DBUS_ERROR_IFACE_EXISTS,
592 "wpa_supplicant already controls this interface.");
594 struct wpa_supplicant *wpa_s;
595 struct wpa_interface iface;
597 os_memset(&iface, 0, sizeof(iface));
598 iface.driver = driver;
599 iface.ifname = ifname;
600 iface.confname = confname;
601 iface.bridge_ifname = bridge_ifname;
602 /* Otherwise, have wpa_supplicant attach to it. */
603 wpa_s = wpa_supplicant_add_iface(global, &iface, NULL);
604 if (wpa_s && wpa_s->dbus_new_path) {
605 const char *path = wpa_s->dbus_new_path;
607 reply = dbus_message_new_method_return(message);
608 dbus_message_append_args(reply, DBUS_TYPE_OBJECT_PATH,
609 &path, DBUS_TYPE_INVALID);
611 reply = wpas_dbus_error_unknown_error(
613 "wpa_supplicant couldn't grab this interface.");
621 os_free(bridge_ifname);
625 reply = wpas_dbus_error_invalid_args(message, NULL);
628 reply = wpas_dbus_error_no_memory(message);
634 * wpas_dbus_handler_remove_interface - Request deregistration of an interface
635 * @message: Pointer to incoming dbus message
636 * @global: wpa_supplicant global data structure
637 * Returns: a dbus message containing a UINT32 indicating success (1) or
638 * failure (0), or returns a dbus error message with more information
640 * Handler function for "removeInterface" method call. Handles requests
641 * by dbus clients to deregister a network interface that wpa_supplicant
644 DBusMessage * wpas_dbus_handler_remove_interface(DBusMessage *message,
645 struct wpa_global *global)
647 struct wpa_supplicant *wpa_s;
649 DBusMessage *reply = NULL;
651 dbus_message_get_args(message, NULL, DBUS_TYPE_OBJECT_PATH, &path,
654 wpa_s = get_iface_by_dbus_path(global, path);
656 reply = wpas_dbus_error_iface_unknown(message);
657 else if (wpa_supplicant_remove_iface(global, wpa_s, 0)) {
658 reply = wpas_dbus_error_unknown_error(
660 "wpa_supplicant couldn't remove this interface.");
668 * wpas_dbus_handler_get_interface - Get the object path for an interface name
669 * @message: Pointer to incoming dbus message
670 * @global: %wpa_supplicant global data structure
671 * Returns: The object path of the interface object,
672 * or a dbus error message with more information
674 * Handler function for "getInterface" method call.
676 DBusMessage * wpas_dbus_handler_get_interface(DBusMessage *message,
677 struct wpa_global *global)
679 DBusMessage *reply = NULL;
682 struct wpa_supplicant *wpa_s;
684 dbus_message_get_args(message, NULL, DBUS_TYPE_STRING, &ifname,
687 wpa_s = wpa_supplicant_get_iface(global, ifname);
688 if (wpa_s == NULL || wpa_s->dbus_new_path == NULL)
689 return wpas_dbus_error_iface_unknown(message);
691 path = wpa_s->dbus_new_path;
692 reply = dbus_message_new_method_return(message);
694 return wpas_dbus_error_no_memory(message);
695 if (!dbus_message_append_args(reply, DBUS_TYPE_OBJECT_PATH, &path,
696 DBUS_TYPE_INVALID)) {
697 dbus_message_unref(reply);
698 return wpas_dbus_error_no_memory(message);
706 * wpas_dbus_getter_debug_level - Get debug level
707 * @iter: Pointer to incoming dbus message iter
708 * @error: Location to store error on failure
709 * @user_data: Function specific data
710 * Returns: TRUE on success, FALSE on failure
712 * Getter for "DebugLevel" property.
714 dbus_bool_t wpas_dbus_getter_debug_level(
715 const struct wpa_dbus_property_desc *property_desc,
716 DBusMessageIter *iter, DBusError *error, void *user_data)
719 int idx = wpa_debug_level;
725 str = debug_strings[idx];
726 return wpas_dbus_simple_property_getter(iter, DBUS_TYPE_STRING,
732 * wpas_dbus_getter_debug_timestamp - Get debug timestamp
733 * @iter: Pointer to incoming dbus message iter
734 * @error: Location to store error on failure
735 * @user_data: Function specific data
736 * Returns: TRUE on success, FALSE on failure
738 * Getter for "DebugTimestamp" property.
740 dbus_bool_t wpas_dbus_getter_debug_timestamp(
741 const struct wpa_dbus_property_desc *property_desc,
742 DBusMessageIter *iter, DBusError *error, void *user_data)
744 return wpas_dbus_simple_property_getter(iter, DBUS_TYPE_BOOLEAN,
745 &wpa_debug_timestamp, error);
751 * wpas_dbus_getter_debug_show_keys - Get debug show keys
752 * @iter: Pointer to incoming dbus message iter
753 * @error: Location to store error on failure
754 * @user_data: Function specific data
755 * Returns: TRUE on success, FALSE on failure
757 * Getter for "DebugShowKeys" property.
759 dbus_bool_t wpas_dbus_getter_debug_show_keys(
760 const struct wpa_dbus_property_desc *property_desc,
761 DBusMessageIter *iter, DBusError *error, void *user_data)
763 return wpas_dbus_simple_property_getter(iter, DBUS_TYPE_BOOLEAN,
764 &wpa_debug_show_keys, error);
769 * wpas_dbus_setter_debug_level - Set debug level
770 * @iter: Pointer to incoming dbus message iter
771 * @error: Location to store error on failure
772 * @user_data: Function specific data
773 * Returns: TRUE on success, FALSE on failure
775 * Setter for "DebugLevel" property.
777 dbus_bool_t wpas_dbus_setter_debug_level(
778 const struct wpa_dbus_property_desc *property_desc,
779 DBusMessageIter *iter, DBusError *error, void *user_data)
781 struct wpa_global *global = user_data;
782 const char *str = NULL;
785 if (!wpas_dbus_simple_property_setter(iter, error, DBUS_TYPE_STRING,
789 for (i = 0; debug_strings[i]; i++)
790 if (os_strcmp(debug_strings[i], str) == 0) {
796 wpa_supplicant_set_debug_params(global, val, wpa_debug_timestamp,
797 wpa_debug_show_keys)) {
798 dbus_set_error_const(error, DBUS_ERROR_FAILED,
799 "wrong debug level value");
808 * wpas_dbus_setter_debug_timestamp - Set debug timestamp
809 * @iter: Pointer to incoming dbus message iter
810 * @error: Location to store error on failure
811 * @user_data: Function specific data
812 * Returns: TRUE on success, FALSE on failure
814 * Setter for "DebugTimestamp" property.
816 dbus_bool_t wpas_dbus_setter_debug_timestamp(
817 const struct wpa_dbus_property_desc *property_desc,
818 DBusMessageIter *iter, DBusError *error, void *user_data)
820 struct wpa_global *global = user_data;
823 if (!wpas_dbus_simple_property_setter(iter, error, DBUS_TYPE_BOOLEAN,
827 wpa_supplicant_set_debug_params(global, wpa_debug_level, val ? 1 : 0,
828 wpa_debug_show_keys);
834 * wpas_dbus_setter_debug_show_keys - Set debug show keys
835 * @iter: Pointer to incoming dbus message iter
836 * @error: Location to store error on failure
837 * @user_data: Function specific data
838 * Returns: TRUE on success, FALSE on failure
840 * Setter for "DebugShowKeys" property.
842 dbus_bool_t wpas_dbus_setter_debug_show_keys(
843 const struct wpa_dbus_property_desc *property_desc,
844 DBusMessageIter *iter, DBusError *error, void *user_data)
846 struct wpa_global *global = user_data;
849 if (!wpas_dbus_simple_property_setter(iter, error, DBUS_TYPE_BOOLEAN,
853 wpa_supplicant_set_debug_params(global, wpa_debug_level,
861 * wpas_dbus_getter_interfaces - Request registered interfaces list
862 * @iter: Pointer to incoming dbus message iter
863 * @error: Location to store error on failure
864 * @user_data: Function specific data
865 * Returns: TRUE on success, FALSE on failure
867 * Getter for "Interfaces" property. Handles requests
868 * by dbus clients to return list of registered interfaces objects
871 dbus_bool_t wpas_dbus_getter_interfaces(
872 const struct wpa_dbus_property_desc *property_desc,
873 DBusMessageIter *iter, DBusError *error, void *user_data)
875 struct wpa_global *global = user_data;
876 struct wpa_supplicant *wpa_s;
878 unsigned int i = 0, num = 0;
881 for (wpa_s = global->ifaces; wpa_s; wpa_s = wpa_s->next) {
882 if (wpa_s->dbus_new_path)
886 paths = os_calloc(num, sizeof(char *));
888 dbus_set_error_const(error, DBUS_ERROR_NO_MEMORY, "no memory");
892 for (wpa_s = global->ifaces; wpa_s; wpa_s = wpa_s->next) {
893 if (wpa_s->dbus_new_path)
894 paths[i++] = wpa_s->dbus_new_path;
897 success = wpas_dbus_simple_array_property_getter(iter,
898 DBUS_TYPE_OBJECT_PATH,
907 * wpas_dbus_getter_eap_methods - Request supported EAP methods list
908 * @iter: Pointer to incoming dbus message iter
909 * @error: Location to store error on failure
910 * @user_data: Function specific data
911 * Returns: TRUE on success, FALSE on failure
913 * Getter for "EapMethods" property. Handles requests
914 * by dbus clients to return list of strings with supported EAP methods
916 dbus_bool_t wpas_dbus_getter_eap_methods(
917 const struct wpa_dbus_property_desc *property_desc,
918 DBusMessageIter *iter, DBusError *error, void *user_data)
921 size_t num_items = 0;
924 eap_methods = eap_get_names_as_string_array(&num_items);
926 dbus_set_error_const(error, DBUS_ERROR_NO_MEMORY, "no memory");
930 success = wpas_dbus_simple_array_property_getter(iter,
936 os_free(eap_methods[--num_items]);
937 os_free(eap_methods);
943 * wpas_dbus_getter_global_capabilities - Request supported global capabilities
944 * @iter: Pointer to incoming dbus message iter
945 * @error: Location to store error on failure
946 * @user_data: Function specific data
947 * Returns: TRUE on success, FALSE on failure
949 * Getter for "Capabilities" property. Handles requests by dbus clients to
950 * return a list of strings with supported capabilities like AP, RSN IBSS,
951 * and P2P that are determined at compile time.
953 dbus_bool_t wpas_dbus_getter_global_capabilities(
954 const struct wpa_dbus_property_desc *property_desc,
955 DBusMessageIter *iter, DBusError *error, void *user_data)
957 const char *capabilities[5] = { NULL, NULL, NULL, NULL, NULL };
958 size_t num_items = 0;
961 capabilities[num_items++] = "ap";
962 #endif /* CONFIG_AP */
963 #ifdef CONFIG_IBSS_RSN
964 capabilities[num_items++] = "ibss-rsn";
965 #endif /* CONFIG_IBSS_RSN */
967 capabilities[num_items++] = "p2p";
968 #endif /* CONFIG_P2P */
969 #ifdef CONFIG_INTERWORKING
970 capabilities[num_items++] = "interworking";
971 #endif /* CONFIG_INTERWORKING */
973 return wpas_dbus_simple_array_property_getter(iter,
980 static int wpas_dbus_get_scan_type(DBusMessage *message, DBusMessageIter *var,
981 char **type, DBusMessage **reply)
983 if (dbus_message_iter_get_arg_type(var) != DBUS_TYPE_STRING) {
984 wpa_printf(MSG_DEBUG, "%s[dbus]: Type must be a string",
986 *reply = wpas_dbus_error_invalid_args(
987 message, "Wrong Type value type. String required");
990 dbus_message_iter_get_basic(var, type);
995 static int wpas_dbus_get_scan_ssids(DBusMessage *message, DBusMessageIter *var,
996 struct wpa_driver_scan_params *params,
999 struct wpa_driver_scan_ssid *ssids = params->ssids;
1000 size_t ssids_num = 0;
1002 DBusMessageIter array_iter, sub_array_iter;
1006 if (dbus_message_iter_get_arg_type(var) != DBUS_TYPE_ARRAY) {
1007 wpa_printf(MSG_DEBUG,
1008 "%s[dbus]: ssids must be an array of arrays of bytes",
1010 *reply = wpas_dbus_error_invalid_args(
1012 "Wrong SSIDs value type. Array of arrays of bytes required");
1016 dbus_message_iter_recurse(var, &array_iter);
1018 if (dbus_message_iter_get_arg_type(&array_iter) != DBUS_TYPE_ARRAY ||
1019 dbus_message_iter_get_element_type(&array_iter) != DBUS_TYPE_BYTE) {
1020 wpa_printf(MSG_DEBUG,
1021 "%s[dbus]: ssids must be an array of arrays of bytes",
1023 *reply = wpas_dbus_error_invalid_args(
1025 "Wrong SSIDs value type. Array of arrays of bytes required");
1029 while (dbus_message_iter_get_arg_type(&array_iter) == DBUS_TYPE_ARRAY) {
1030 if (ssids_num >= WPAS_MAX_SCAN_SSIDS) {
1031 wpa_printf(MSG_DEBUG,
1032 "%s[dbus]: Too many ssids specified on scan dbus call",
1034 *reply = wpas_dbus_error_invalid_args(
1036 "Too many ssids specified. Specify at most four");
1040 dbus_message_iter_recurse(&array_iter, &sub_array_iter);
1042 dbus_message_iter_get_fixed_array(&sub_array_iter, &val, &len);
1044 if (len > SSID_MAX_LEN) {
1045 wpa_printf(MSG_DEBUG,
1046 "%s[dbus]: SSID too long (len=%d max_len=%d)",
1047 __func__, len, SSID_MAX_LEN);
1048 *reply = wpas_dbus_error_invalid_args(
1049 message, "Invalid SSID: too long");
1054 ssid = os_malloc(len);
1056 *reply = wpas_dbus_error_no_memory(message);
1059 os_memcpy(ssid, val, len);
1061 /* Allow zero-length SSIDs */
1065 ssids[ssids_num].ssid = ssid;
1066 ssids[ssids_num].ssid_len = len;
1068 dbus_message_iter_next(&array_iter);
1072 params->num_ssids = ssids_num;
1077 static int wpas_dbus_get_scan_ies(DBusMessage *message, DBusMessageIter *var,
1078 struct wpa_driver_scan_params *params,
1079 DBusMessage **reply)
1081 u8 *ies = NULL, *nies;
1083 DBusMessageIter array_iter, sub_array_iter;
1087 if (dbus_message_iter_get_arg_type(var) != DBUS_TYPE_ARRAY) {
1088 wpa_printf(MSG_DEBUG,
1089 "%s[dbus]: ies must be an array of arrays of bytes",
1091 *reply = wpas_dbus_error_invalid_args(
1093 "Wrong IEs value type. Array of arrays of bytes required");
1097 dbus_message_iter_recurse(var, &array_iter);
1099 if (dbus_message_iter_get_arg_type(&array_iter) != DBUS_TYPE_ARRAY ||
1100 dbus_message_iter_get_element_type(&array_iter) != DBUS_TYPE_BYTE) {
1101 wpa_printf(MSG_DEBUG,
1102 "%s[dbus]: ies must be an array of arrays of bytes",
1104 *reply = wpas_dbus_error_invalid_args(
1105 message, "Wrong IEs value type. Array required");
1109 while (dbus_message_iter_get_arg_type(&array_iter) == DBUS_TYPE_ARRAY) {
1110 dbus_message_iter_recurse(&array_iter, &sub_array_iter);
1112 dbus_message_iter_get_fixed_array(&sub_array_iter, &val, &len);
1114 dbus_message_iter_next(&array_iter);
1118 nies = os_realloc(ies, ies_len + len);
1121 *reply = wpas_dbus_error_no_memory(message);
1125 os_memcpy(ies + ies_len, val, len);
1128 dbus_message_iter_next(&array_iter);
1131 params->extra_ies = ies;
1132 params->extra_ies_len = ies_len;
1137 static int wpas_dbus_get_scan_channels(DBusMessage *message,
1138 DBusMessageIter *var,
1139 struct wpa_driver_scan_params *params,
1140 DBusMessage **reply)
1142 DBusMessageIter array_iter, sub_array_iter;
1143 int *freqs = NULL, *nfreqs;
1146 if (dbus_message_iter_get_arg_type(var) != DBUS_TYPE_ARRAY) {
1147 wpa_printf(MSG_DEBUG,
1148 "%s[dbus]: Channels must be an array of structs",
1150 *reply = wpas_dbus_error_invalid_args(
1152 "Wrong Channels value type. Array of structs required");
1156 dbus_message_iter_recurse(var, &array_iter);
1158 if (dbus_message_iter_get_arg_type(&array_iter) != DBUS_TYPE_STRUCT) {
1159 wpa_printf(MSG_DEBUG,
1160 "%s[dbus]: Channels must be an array of structs",
1162 *reply = wpas_dbus_error_invalid_args(
1164 "Wrong Channels value type. Array of structs required");
1168 while (dbus_message_iter_get_arg_type(&array_iter) == DBUS_TYPE_STRUCT)
1172 dbus_message_iter_recurse(&array_iter, &sub_array_iter);
1174 if (dbus_message_iter_get_arg_type(&sub_array_iter) !=
1176 wpa_printf(MSG_DEBUG,
1177 "%s[dbus]: Channel must by specified by struct of two UINT32s %c",
1179 dbus_message_iter_get_arg_type(
1181 *reply = wpas_dbus_error_invalid_args(
1183 "Wrong Channel struct. Two UINT32s required");
1187 dbus_message_iter_get_basic(&sub_array_iter, &freq);
1189 if (!dbus_message_iter_next(&sub_array_iter) ||
1190 dbus_message_iter_get_arg_type(&sub_array_iter) !=
1192 wpa_printf(MSG_DEBUG,
1193 "%s[dbus]: Channel must by specified by struct of two UINT32s",
1195 *reply = wpas_dbus_error_invalid_args(
1197 "Wrong Channel struct. Two UINT32s required");
1202 dbus_message_iter_get_basic(&sub_array_iter, &width);
1204 #define FREQS_ALLOC_CHUNK 32
1205 if (freqs_num % FREQS_ALLOC_CHUNK == 0) {
1206 nfreqs = os_realloc_array(
1207 freqs, freqs_num + FREQS_ALLOC_CHUNK,
1213 if (freqs == NULL) {
1214 *reply = wpas_dbus_error_no_memory(message);
1218 freqs[freqs_num] = freq;
1221 dbus_message_iter_next(&array_iter);
1224 nfreqs = os_realloc_array(freqs, freqs_num + 1, sizeof(int));
1228 if (freqs == NULL) {
1229 *reply = wpas_dbus_error_no_memory(message);
1232 freqs[freqs_num] = 0;
1234 params->freqs = freqs;
1239 static int wpas_dbus_get_scan_allow_roam(DBusMessage *message,
1240 DBusMessageIter *var,
1242 DBusMessage **reply)
1244 if (dbus_message_iter_get_arg_type(var) != DBUS_TYPE_BOOLEAN) {
1245 wpa_printf(MSG_DEBUG, "%s[dbus]: Type must be a boolean",
1247 *reply = wpas_dbus_error_invalid_args(
1248 message, "Wrong Type value type. Boolean required");
1251 dbus_message_iter_get_basic(var, allow);
1257 * wpas_dbus_handler_scan - Request a wireless scan on an interface
1258 * @message: Pointer to incoming dbus message
1259 * @wpa_s: wpa_supplicant structure for a network interface
1260 * Returns: NULL indicating success or DBus error message on failure
1262 * Handler function for "Scan" method call of a network device. Requests
1263 * that wpa_supplicant perform a wireless scan as soon as possible
1264 * on a particular wireless interface.
1266 DBusMessage * wpas_dbus_handler_scan(DBusMessage *message,
1267 struct wpa_supplicant *wpa_s)
1269 DBusMessage *reply = NULL;
1270 DBusMessageIter iter, dict_iter, entry_iter, variant_iter;
1271 char *key = NULL, *type = NULL;
1272 struct wpa_driver_scan_params params;
1274 dbus_bool_t allow_roam = 1;
1276 os_memset(¶ms, 0, sizeof(params));
1278 dbus_message_iter_init(message, &iter);
1280 dbus_message_iter_recurse(&iter, &dict_iter);
1282 while (dbus_message_iter_get_arg_type(&dict_iter) ==
1283 DBUS_TYPE_DICT_ENTRY) {
1284 dbus_message_iter_recurse(&dict_iter, &entry_iter);
1285 dbus_message_iter_get_basic(&entry_iter, &key);
1286 dbus_message_iter_next(&entry_iter);
1287 dbus_message_iter_recurse(&entry_iter, &variant_iter);
1289 if (os_strcmp(key, "Type") == 0) {
1290 if (wpas_dbus_get_scan_type(message, &variant_iter,
1293 } else if (os_strcmp(key, "SSIDs") == 0) {
1294 if (wpas_dbus_get_scan_ssids(message, &variant_iter,
1295 ¶ms, &reply) < 0)
1297 } else if (os_strcmp(key, "IEs") == 0) {
1298 if (wpas_dbus_get_scan_ies(message, &variant_iter,
1299 ¶ms, &reply) < 0)
1301 } else if (os_strcmp(key, "Channels") == 0) {
1302 if (wpas_dbus_get_scan_channels(message, &variant_iter,
1303 ¶ms, &reply) < 0)
1305 } else if (os_strcmp(key, "AllowRoam") == 0) {
1306 if (wpas_dbus_get_scan_allow_roam(message,
1312 wpa_printf(MSG_DEBUG, "%s[dbus]: Unknown argument %s",
1314 reply = wpas_dbus_error_invalid_args(message, key);
1318 dbus_message_iter_next(&dict_iter);
1322 wpa_printf(MSG_DEBUG, "%s[dbus]: Scan type not specified",
1324 reply = wpas_dbus_error_invalid_args(message, key);
1328 if (os_strcmp(type, "passive") == 0) {
1329 if (params.num_ssids || params.extra_ies_len) {
1330 wpa_printf(MSG_DEBUG,
1331 "%s[dbus]: SSIDs or IEs specified for passive scan.",
1333 reply = wpas_dbus_error_invalid_args(
1335 "You can specify only Channels in passive scan");
1338 if (wpa_s->sched_scanning) {
1339 wpa_printf(MSG_DEBUG,
1340 "%s[dbus]: Stop ongoing sched_scan to allow requested scan to proceed",
1342 wpa_supplicant_cancel_sched_scan(wpa_s);
1345 if (params.freqs && params.freqs[0]) {
1346 wpa_s->last_scan_req = MANUAL_SCAN_REQ;
1347 if (wpa_supplicant_trigger_scan(wpa_s,
1349 reply = wpas_dbus_error_scan_error(
1351 "Scan request rejected");
1354 wpa_s->scan_req = MANUAL_SCAN_REQ;
1355 wpa_supplicant_req_scan(wpa_s, 0, 0);
1358 } else if (os_strcmp(type, "active") == 0) {
1359 if (!params.num_ssids) {
1360 /* Add wildcard ssid */
1363 #ifdef CONFIG_AUTOSCAN
1364 autoscan_deinit(wpa_s);
1365 #endif /* CONFIG_AUTOSCAN */
1366 if (wpa_s->sched_scanning) {
1367 wpa_printf(MSG_DEBUG,
1368 "%s[dbus]: Stop ongoing sched_scan to allow requested scan to proceed",
1370 wpa_supplicant_cancel_sched_scan(wpa_s);
1373 wpa_s->last_scan_req = MANUAL_SCAN_REQ;
1374 if (wpa_supplicant_trigger_scan(wpa_s, ¶ms)) {
1375 reply = wpas_dbus_error_scan_error(
1376 message, "Scan request rejected");
1379 wpa_printf(MSG_DEBUG, "%s[dbus]: Unknown scan type: %s",
1381 reply = wpas_dbus_error_invalid_args(message,
1387 wpa_s->scan_res_handler = scan_only_handler;
1390 for (i = 0; i < WPAS_MAX_SCAN_SSIDS; i++)
1391 os_free((u8 *) params.ssids[i].ssid);
1392 os_free((u8 *) params.extra_ies);
1393 os_free(params.freqs);
1399 * wpas_dbus_handler_signal_poll - Request immediate signal properties
1400 * @message: Pointer to incoming dbus message
1401 * @wpa_s: wpa_supplicant structure for a network interface
1402 * Returns: NULL indicating success or DBus error message on failure
1404 * Handler function for "SignalPoll" method call of a network device. Requests
1405 * that wpa_supplicant read signal properties like RSSI, noise, and link
1406 * speed and return them.
1408 DBusMessage * wpas_dbus_handler_signal_poll(DBusMessage *message,
1409 struct wpa_supplicant *wpa_s)
1411 struct wpa_signal_info si;
1412 DBusMessage *reply = NULL;
1413 DBusMessageIter iter, iter_dict, variant_iter;
1416 ret = wpa_drv_signal_poll(wpa_s, &si);
1418 return dbus_message_new_error(message, DBUS_ERROR_FAILED,
1419 "Failed to read signal");
1422 reply = dbus_message_new_method_return(message);
1426 dbus_message_iter_init_append(reply, &iter);
1428 if (!dbus_message_iter_open_container(&iter, DBUS_TYPE_VARIANT,
1429 "a{sv}", &variant_iter) ||
1430 !wpa_dbus_dict_open_write(&variant_iter, &iter_dict) ||
1431 !wpa_dbus_dict_append_int32(&iter_dict, "rssi",
1432 si.current_signal) ||
1433 !wpa_dbus_dict_append_int32(&iter_dict, "linkspeed",
1434 si.current_txrate / 1000) ||
1435 !wpa_dbus_dict_append_int32(&iter_dict, "noise",
1436 si.current_noise) ||
1437 !wpa_dbus_dict_append_uint32(&iter_dict, "frequency",
1439 (si.chanwidth != CHAN_WIDTH_UNKNOWN &&
1440 !wpa_dbus_dict_append_string(
1441 &iter_dict, "width",
1442 channel_width_to_string(si.chanwidth))) ||
1443 (si.center_frq1 > 0 && si.center_frq2 > 0 &&
1444 (!wpa_dbus_dict_append_int32(&iter_dict, "center-frq1",
1446 !wpa_dbus_dict_append_int32(&iter_dict, "center-frq2",
1447 si.center_frq2))) ||
1449 !wpa_dbus_dict_append_int32(&iter_dict, "avg-rssi",
1451 !wpa_dbus_dict_close_write(&variant_iter, &iter_dict) ||
1452 !dbus_message_iter_close_container(&iter, &variant_iter))
1459 dbus_message_unref(reply);
1460 return wpas_dbus_error_no_memory(message);
1465 * wpas_dbus_handler_disconnect - Terminate the current connection
1466 * @message: Pointer to incoming dbus message
1467 * @wpa_s: wpa_supplicant structure for a network interface
1468 * Returns: NotConnected DBus error message if already not connected
1469 * or NULL otherwise.
1471 * Handler function for "Disconnect" method call of network interface.
1473 DBusMessage * wpas_dbus_handler_disconnect(DBusMessage *message,
1474 struct wpa_supplicant *wpa_s)
1476 if (wpa_s->current_ssid != NULL) {
1477 wpa_s->disconnected = 1;
1478 wpa_supplicant_deauthenticate(wpa_s,
1479 WLAN_REASON_DEAUTH_LEAVING);
1484 return dbus_message_new_error(message, WPAS_DBUS_ERROR_NOT_CONNECTED,
1485 "This interface is not connected");
1490 * wpas_dbus_new_iface_add_network - Add a new configured network
1491 * @message: Pointer to incoming dbus message
1492 * @wpa_s: wpa_supplicant structure for a network interface
1493 * Returns: A dbus message containing the object path of the new network
1495 * Handler function for "AddNetwork" method call of a network interface.
1497 DBusMessage * wpas_dbus_handler_add_network(DBusMessage *message,
1498 struct wpa_supplicant *wpa_s)
1500 DBusMessage *reply = NULL;
1501 DBusMessageIter iter;
1502 struct wpa_ssid *ssid = NULL;
1503 char path_buf[WPAS_DBUS_OBJECT_PATH_MAX], *path = path_buf;
1506 dbus_message_iter_init(message, &iter);
1508 if (wpa_s->dbus_new_path)
1509 ssid = wpa_config_add_network(wpa_s->conf);
1511 wpa_printf(MSG_ERROR, "%s[dbus]: can't add new interface.",
1513 reply = wpas_dbus_error_unknown_error(
1515 "wpa_supplicant could not add a network on this interface.");
1518 wpas_notify_network_added(wpa_s, ssid);
1520 wpa_config_set_network_defaults(ssid);
1522 dbus_error_init(&error);
1523 if (!set_network_properties(wpa_s, ssid, &iter, &error)) {
1524 wpa_printf(MSG_DEBUG,
1525 "%s[dbus]: control interface couldn't set network properties",
1527 reply = wpas_dbus_reply_new_from_error(message, &error,
1528 DBUS_ERROR_INVALID_ARGS,
1529 "Failed to add network");
1530 dbus_error_free(&error);
1534 /* Construct the object path for this network. */
1535 os_snprintf(path, WPAS_DBUS_OBJECT_PATH_MAX,
1536 "%s/" WPAS_DBUS_NEW_NETWORKS_PART "/%d",
1537 wpa_s->dbus_new_path, ssid->id);
1539 reply = dbus_message_new_method_return(message);
1540 if (reply == NULL) {
1541 reply = wpas_dbus_error_no_memory(message);
1544 if (!dbus_message_append_args(reply, DBUS_TYPE_OBJECT_PATH, &path,
1545 DBUS_TYPE_INVALID)) {
1546 dbus_message_unref(reply);
1547 reply = wpas_dbus_error_no_memory(message);
1555 wpas_notify_network_removed(wpa_s, ssid);
1556 wpa_config_remove_network(wpa_s->conf, ssid->id);
1563 * wpas_dbus_handler_reassociate - Reassociate
1564 * @message: Pointer to incoming dbus message
1565 * @wpa_s: wpa_supplicant structure for a network interface
1566 * Returns: InterfaceDisabled DBus error message if disabled
1567 * or NULL otherwise.
1569 * Handler function for "Reassociate" method call of network interface.
1571 DBusMessage * wpas_dbus_handler_reassociate(DBusMessage *message,
1572 struct wpa_supplicant *wpa_s)
1574 if (wpa_s->wpa_state != WPA_INTERFACE_DISABLED) {
1575 wpas_request_connection(wpa_s);
1579 return dbus_message_new_error(message, WPAS_DBUS_ERROR_IFACE_DISABLED,
1580 "This interface is disabled");
1585 * wpas_dbus_handler_expect_disconnect - ExpectDisconnect
1586 * @message: Pointer to incoming dbus message
1587 * @global: %wpa_supplicant global data structure
1590 * Handler function for notifying system there will be a expected disconnect.
1591 * This will prevent wpa_supplicant from adding blacklists upon next disconnect..
1593 DBusMessage * wpas_dbus_handler_expect_disconnect(DBusMessage *message,
1594 struct wpa_global *global)
1596 struct wpa_supplicant *wpa_s = global->ifaces;
1598 for (; wpa_s; wpa_s = wpa_s->next)
1599 if (wpa_s->wpa_state >= WPA_ASSOCIATED)
1600 wpa_s->own_disconnect_req = 1;
1606 * wpas_dbus_handler_reattach - Reattach to current AP
1607 * @message: Pointer to incoming dbus message
1608 * @wpa_s: wpa_supplicant structure for a network interface
1609 * Returns: NotConnected DBus error message if not connected
1610 * or NULL otherwise.
1612 * Handler function for "Reattach" method call of network interface.
1614 DBusMessage * wpas_dbus_handler_reattach(DBusMessage *message,
1615 struct wpa_supplicant *wpa_s)
1617 if (wpa_s->current_ssid != NULL) {
1618 wpa_s->reattach = 1;
1619 wpas_request_connection(wpa_s);
1623 return dbus_message_new_error(message, WPAS_DBUS_ERROR_NOT_CONNECTED,
1624 "This interface is not connected");
1629 * wpas_dbus_handler_reconnect - Reconnect if disconnected
1630 * @message: Pointer to incoming dbus message
1631 * @wpa_s: wpa_supplicant structure for a network interface
1632 * Returns: InterfaceDisabled DBus error message if disabled
1633 * or NULL otherwise.
1635 * Handler function for "Reconnect" method call of network interface.
1637 DBusMessage * wpas_dbus_handler_reconnect(DBusMessage *message,
1638 struct wpa_supplicant *wpa_s)
1640 if (wpa_s->wpa_state == WPA_INTERFACE_DISABLED) {
1641 return dbus_message_new_error(message,
1642 WPAS_DBUS_ERROR_IFACE_DISABLED,
1643 "This interface is disabled");
1646 if (wpa_s->disconnected)
1647 wpas_request_connection(wpa_s);
1653 * wpas_dbus_handler_remove_network - Remove a configured network
1654 * @message: Pointer to incoming dbus message
1655 * @wpa_s: wpa_supplicant structure for a network interface
1656 * Returns: NULL on success or dbus error on failure
1658 * Handler function for "RemoveNetwork" method call of a network interface.
1660 DBusMessage * wpas_dbus_handler_remove_network(DBusMessage *message,
1661 struct wpa_supplicant *wpa_s)
1663 DBusMessage *reply = NULL;
1665 char *iface, *net_id;
1667 struct wpa_ssid *ssid;
1670 dbus_message_get_args(message, NULL, DBUS_TYPE_OBJECT_PATH, &op,
1673 /* Extract the network ID and ensure the network */
1674 /* is actually a child of this interface */
1675 iface = wpas_dbus_new_decompose_object_path(op,
1676 WPAS_DBUS_NEW_NETWORKS_PART,
1678 if (iface == NULL || net_id == NULL || !wpa_s->dbus_new_path ||
1679 os_strcmp(iface, wpa_s->dbus_new_path) != 0) {
1680 reply = wpas_dbus_error_invalid_args(message, op);
1685 id = strtoul(net_id, NULL, 10);
1687 reply = wpas_dbus_error_invalid_args(message, op);
1691 ssid = wpa_config_get_network(wpa_s->conf, id);
1693 reply = wpas_dbus_error_network_unknown(message);
1697 was_disabled = ssid->disabled;
1699 wpas_notify_network_removed(wpa_s, ssid);
1701 if (ssid == wpa_s->current_ssid)
1702 wpa_supplicant_deauthenticate(wpa_s,
1703 WLAN_REASON_DEAUTH_LEAVING);
1704 else if (!was_disabled && wpa_s->sched_scanning) {
1705 wpa_printf(MSG_DEBUG,
1706 "Stop ongoing sched_scan to remove network from filters");
1707 wpa_supplicant_cancel_sched_scan(wpa_s);
1708 wpa_supplicant_req_scan(wpa_s, 0, 0);
1711 if (wpa_config_remove_network(wpa_s->conf, id) < 0) {
1712 wpa_printf(MSG_ERROR,
1713 "%s[dbus]: error occurred when removing network %d",
1715 reply = wpas_dbus_error_unknown_error(
1717 "error removing the specified network on is interface.");
1727 static void remove_network(void *arg, struct wpa_ssid *ssid)
1729 struct wpa_supplicant *wpa_s = arg;
1731 wpas_notify_network_removed(wpa_s, ssid);
1733 if (wpa_config_remove_network(wpa_s->conf, ssid->id) < 0) {
1734 wpa_printf(MSG_ERROR,
1735 "%s[dbus]: error occurred when removing network %d",
1736 __func__, ssid->id);
1740 if (ssid == wpa_s->current_ssid)
1741 wpa_supplicant_deauthenticate(wpa_s,
1742 WLAN_REASON_DEAUTH_LEAVING);
1747 * wpas_dbus_handler_remove_all_networks - Remove all configured networks
1748 * @message: Pointer to incoming dbus message
1749 * @wpa_s: wpa_supplicant structure for a network interface
1750 * Returns: NULL on success or dbus error on failure
1752 * Handler function for "RemoveAllNetworks" method call of a network interface.
1754 DBusMessage * wpas_dbus_handler_remove_all_networks(
1755 DBusMessage *message, struct wpa_supplicant *wpa_s)
1757 if (wpa_s->sched_scanning)
1758 wpa_supplicant_cancel_sched_scan(wpa_s);
1760 /* NB: could check for failure and return an error */
1761 wpa_config_foreach_network(wpa_s->conf, remove_network, wpa_s);
1767 * wpas_dbus_handler_select_network - Attempt association with a network
1768 * @message: Pointer to incoming dbus message
1769 * @wpa_s: wpa_supplicant structure for a network interface
1770 * Returns: NULL on success or dbus error on failure
1772 * Handler function for "SelectNetwork" method call of network interface.
1774 DBusMessage * wpas_dbus_handler_select_network(DBusMessage *message,
1775 struct wpa_supplicant *wpa_s)
1777 DBusMessage *reply = NULL;
1779 char *iface, *net_id;
1781 struct wpa_ssid *ssid;
1783 dbus_message_get_args(message, NULL, DBUS_TYPE_OBJECT_PATH, &op,
1786 /* Extract the network ID and ensure the network */
1787 /* is actually a child of this interface */
1788 iface = wpas_dbus_new_decompose_object_path(op,
1789 WPAS_DBUS_NEW_NETWORKS_PART,
1791 if (iface == NULL || net_id == NULL || !wpa_s->dbus_new_path ||
1792 os_strcmp(iface, wpa_s->dbus_new_path) != 0) {
1793 reply = wpas_dbus_error_invalid_args(message, op);
1798 id = strtoul(net_id, NULL, 10);
1800 reply = wpas_dbus_error_invalid_args(message, op);
1804 ssid = wpa_config_get_network(wpa_s->conf, id);
1806 reply = wpas_dbus_error_network_unknown(message);
1810 /* Finally, associate with the network */
1811 wpa_supplicant_select_network(wpa_s, ssid);
1820 * wpas_dbus_handler_network_reply - Reply to a NetworkRequest signal
1821 * @message: Pointer to incoming dbus message
1822 * @wpa_s: wpa_supplicant structure for a network interface
1823 * Returns: NULL on success or dbus error on failure
1825 * Handler function for "NetworkReply" method call of network interface.
1827 DBusMessage * wpas_dbus_handler_network_reply(DBusMessage *message,
1828 struct wpa_supplicant *wpa_s)
1830 #ifdef IEEE8021X_EAPOL
1831 DBusMessage *reply = NULL;
1832 const char *op, *field, *value;
1833 char *iface, *net_id;
1835 struct wpa_ssid *ssid;
1837 if (!dbus_message_get_args(message, NULL,
1838 DBUS_TYPE_OBJECT_PATH, &op,
1839 DBUS_TYPE_STRING, &field,
1840 DBUS_TYPE_STRING, &value,
1842 return wpas_dbus_error_invalid_args(message, NULL);
1844 /* Extract the network ID and ensure the network */
1845 /* is actually a child of this interface */
1846 iface = wpas_dbus_new_decompose_object_path(op,
1847 WPAS_DBUS_NEW_NETWORKS_PART,
1849 if (iface == NULL || net_id == NULL || !wpa_s->dbus_new_path ||
1850 os_strcmp(iface, wpa_s->dbus_new_path) != 0) {
1851 reply = wpas_dbus_error_invalid_args(message, op);
1856 id = strtoul(net_id, NULL, 10);
1858 reply = wpas_dbus_error_invalid_args(message, net_id);
1862 ssid = wpa_config_get_network(wpa_s->conf, id);
1864 reply = wpas_dbus_error_network_unknown(message);
1868 if (wpa_supplicant_ctrl_iface_ctrl_rsp_handle(wpa_s, ssid,
1870 reply = wpas_dbus_error_invalid_args(message, field);
1872 /* Tell EAP to retry immediately */
1873 eapol_sm_notify_ctrl_response(wpa_s->eapol);
1879 #else /* IEEE8021X_EAPOL */
1880 wpa_printf(MSG_DEBUG, "CTRL_IFACE: 802.1X not included");
1881 return wpas_dbus_error_unknown_error(message, "802.1X not included");
1882 #endif /* IEEE8021X_EAPOL */
1886 #ifndef CONFIG_NO_CONFIG_BLOBS
1889 * wpas_dbus_handler_add_blob - Store named binary blob (ie, for certificates)
1890 * @message: Pointer to incoming dbus message
1891 * @wpa_s: %wpa_supplicant data structure
1892 * Returns: A dbus message containing an error on failure or NULL on success
1894 * Asks wpa_supplicant to internally store a binary blobs.
1896 DBusMessage * wpas_dbus_handler_add_blob(DBusMessage *message,
1897 struct wpa_supplicant *wpa_s)
1899 DBusMessage *reply = NULL;
1900 DBusMessageIter iter, array_iter;
1905 struct wpa_config_blob *blob = NULL;
1907 dbus_message_iter_init(message, &iter);
1908 dbus_message_iter_get_basic(&iter, &blob_name);
1910 if (wpa_config_get_blob(wpa_s->conf, blob_name)) {
1911 return dbus_message_new_error(message,
1912 WPAS_DBUS_ERROR_BLOB_EXISTS,
1916 dbus_message_iter_next(&iter);
1917 dbus_message_iter_recurse(&iter, &array_iter);
1919 dbus_message_iter_get_fixed_array(&array_iter, &blob_data, &blob_len);
1921 blob = os_zalloc(sizeof(*blob));
1923 reply = wpas_dbus_error_no_memory(message);
1927 blob->data = os_malloc(blob_len);
1928 blob->name = os_strdup(blob_name);
1929 if (!blob->data || !blob->name) {
1930 reply = wpas_dbus_error_no_memory(message);
1933 os_memcpy(blob->data, blob_data, blob_len);
1934 blob->len = blob_len;
1936 wpa_config_set_blob(wpa_s->conf, blob);
1937 wpas_notify_blob_added(wpa_s, blob->name);
1943 os_free(blob->name);
1944 os_free(blob->data);
1952 * wpas_dbus_handler_get_blob - Get named binary blob (ie, for certificates)
1953 * @message: Pointer to incoming dbus message
1954 * @wpa_s: %wpa_supplicant data structure
1955 * Returns: A dbus message containing array of bytes (blob)
1957 * Gets one wpa_supplicant's binary blobs.
1959 DBusMessage * wpas_dbus_handler_get_blob(DBusMessage *message,
1960 struct wpa_supplicant *wpa_s)
1962 DBusMessage *reply = NULL;
1963 DBusMessageIter iter, array_iter;
1966 const struct wpa_config_blob *blob;
1968 dbus_message_get_args(message, NULL, DBUS_TYPE_STRING, &blob_name,
1971 blob = wpa_config_get_blob(wpa_s->conf, blob_name);
1973 return dbus_message_new_error(message,
1974 WPAS_DBUS_ERROR_BLOB_UNKNOWN,
1978 reply = dbus_message_new_method_return(message);
1980 return wpas_dbus_error_no_memory(message);
1982 dbus_message_iter_init_append(reply, &iter);
1984 if (!dbus_message_iter_open_container(&iter, DBUS_TYPE_ARRAY,
1985 DBUS_TYPE_BYTE_AS_STRING,
1987 !dbus_message_iter_append_fixed_array(&array_iter, DBUS_TYPE_BYTE,
1988 &(blob->data), blob->len) ||
1989 !dbus_message_iter_close_container(&iter, &array_iter)) {
1990 dbus_message_unref(reply);
1991 reply = wpas_dbus_error_no_memory(message);
1999 * wpas_remove_handler_remove_blob - Remove named binary blob
2000 * @message: Pointer to incoming dbus message
2001 * @wpa_s: %wpa_supplicant data structure
2002 * Returns: NULL on success or dbus error
2004 * Asks wpa_supplicant to internally remove a binary blobs.
2006 DBusMessage * wpas_dbus_handler_remove_blob(DBusMessage *message,
2007 struct wpa_supplicant *wpa_s)
2009 DBusMessage *reply = NULL;
2012 dbus_message_get_args(message, NULL, DBUS_TYPE_STRING, &blob_name,
2015 if (wpa_config_remove_blob(wpa_s->conf, blob_name)) {
2016 return dbus_message_new_error(message,
2017 WPAS_DBUS_ERROR_BLOB_UNKNOWN,
2020 wpas_notify_blob_removed(wpa_s, blob_name);
2026 #endif /* CONFIG_NO_CONFIG_BLOBS */
2030 * wpas_dbus_handler_flush_bss - Flush the BSS cache
2031 * @message: Pointer to incoming dbus message
2032 * @wpa_s: wpa_supplicant structure for a network interface
2035 * Handler function for "FlushBSS" method call of network interface.
2037 DBusMessage * wpas_dbus_handler_flush_bss(DBusMessage *message,
2038 struct wpa_supplicant *wpa_s)
2042 dbus_message_get_args(message, NULL, DBUS_TYPE_UINT32, &age,
2046 wpa_bss_flush(wpa_s);
2048 wpa_bss_flush_by_age(wpa_s, age);
2054 #ifdef CONFIG_AUTOSCAN
2056 * wpas_dbus_handler_autoscan - Set autoscan parameters for the interface
2057 * @message: Pointer to incoming dbus message
2058 * @wpa_s: wpa_supplicant structure for a network interface
2061 * Handler function for "AutoScan" method call of network interface.
2063 DBusMessage * wpas_dbus_handler_autoscan(DBusMessage *message,
2064 struct wpa_supplicant *wpa_s)
2066 DBusMessage *reply = NULL;
2067 enum wpa_states state = wpa_s->wpa_state;
2070 dbus_message_get_args(message, NULL, DBUS_TYPE_STRING, &arg,
2073 if (arg != NULL && os_strlen(arg) > 0) {
2076 tmp = os_strdup(arg);
2078 reply = wpas_dbus_error_no_memory(message);
2080 os_free(wpa_s->conf->autoscan);
2081 wpa_s->conf->autoscan = tmp;
2082 if (state == WPA_DISCONNECTED || state == WPA_INACTIVE)
2083 autoscan_init(wpa_s, 1);
2084 else if (state == WPA_SCANNING)
2085 wpa_supplicant_reinit_autoscan(wpa_s);
2087 } else if (arg != NULL && os_strlen(arg) == 0) {
2088 os_free(wpa_s->conf->autoscan);
2089 wpa_s->conf->autoscan = NULL;
2090 autoscan_deinit(wpa_s);
2092 reply = dbus_message_new_error(message,
2093 DBUS_ERROR_INVALID_ARGS,
2098 #endif /* CONFIG_AUTOSCAN */
2102 * wpas_dbus_handler_eap_logoff - IEEE 802.1X EAPOL state machine logoff
2103 * @message: Pointer to incoming dbus message
2104 * @wpa_s: wpa_supplicant structure for a network interface
2107 * Handler function for "EAPLogoff" method call of network interface.
2109 DBusMessage * wpas_dbus_handler_eap_logoff(DBusMessage *message,
2110 struct wpa_supplicant *wpa_s)
2112 eapol_sm_notify_logoff(wpa_s->eapol, TRUE);
2118 * wpas_dbus_handler_eap_logon - IEEE 802.1X EAPOL state machine logon
2119 * @message: Pointer to incoming dbus message
2120 * @wpa_s: wpa_supplicant structure for a network interface
2123 * Handler function for "EAPLogin" method call of network interface.
2125 DBusMessage * wpas_dbus_handler_eap_logon(DBusMessage *message,
2126 struct wpa_supplicant *wpa_s)
2128 eapol_sm_notify_logoff(wpa_s->eapol, FALSE);
2135 static int get_peer_hwaddr_helper(DBusMessage *message, const char *func_name,
2136 u8 *peer_address, DBusMessage **error)
2138 const char *peer_string;
2142 if (!dbus_message_get_args(message, NULL,
2143 DBUS_TYPE_STRING, &peer_string,
2144 DBUS_TYPE_INVALID)) {
2145 *error = wpas_dbus_error_invalid_args(message, NULL);
2149 if (hwaddr_aton(peer_string, peer_address)) {
2150 wpa_printf(MSG_DEBUG, "%s: invalid address '%s'",
2151 func_name, peer_string);
2152 *error = wpas_dbus_error_invalid_args(
2153 message, "Invalid hardware address format");
2162 * wpas_dbus_handler_tdls_discover - Discover TDLS peer
2163 * @message: Pointer to incoming dbus message
2164 * @wpa_s: wpa_supplicant structure for a network interface
2165 * Returns: NULL indicating success or DBus error message on failure
2167 * Handler function for "TDLSDiscover" method call of network interface.
2169 DBusMessage * wpas_dbus_handler_tdls_discover(DBusMessage *message,
2170 struct wpa_supplicant *wpa_s)
2173 DBusMessage *error_reply;
2176 if (get_peer_hwaddr_helper(message, __func__, peer, &error_reply) < 0)
2179 wpa_printf(MSG_DEBUG, "DBUS TDLS_DISCOVER " MACSTR, MAC2STR(peer));
2181 if (wpa_tdls_is_external_setup(wpa_s->wpa))
2182 ret = wpa_tdls_send_discovery_request(wpa_s->wpa, peer);
2184 ret = wpa_drv_tdls_oper(wpa_s, TDLS_DISCOVERY_REQ, peer);
2187 return wpas_dbus_error_unknown_error(
2188 message, "error performing TDLS discovery");
2196 * wpas_dbus_handler_tdls_setup - Setup TDLS session
2197 * @message: Pointer to incoming dbus message
2198 * @wpa_s: wpa_supplicant structure for a network interface
2199 * Returns: NULL indicating success or DBus error message on failure
2201 * Handler function for "TDLSSetup" method call of network interface.
2203 DBusMessage * wpas_dbus_handler_tdls_setup(DBusMessage *message,
2204 struct wpa_supplicant *wpa_s)
2207 DBusMessage *error_reply;
2210 if (get_peer_hwaddr_helper(message, __func__, peer, &error_reply) < 0)
2213 wpa_printf(MSG_DEBUG, "DBUS TDLS_SETUP " MACSTR, MAC2STR(peer));
2215 wpa_tdls_remove(wpa_s->wpa, peer);
2216 if (wpa_tdls_is_external_setup(wpa_s->wpa))
2217 ret = wpa_tdls_start(wpa_s->wpa, peer);
2219 ret = wpa_drv_tdls_oper(wpa_s, TDLS_SETUP, peer);
2222 return wpas_dbus_error_unknown_error(
2223 message, "error performing TDLS setup");
2231 * wpas_dbus_handler_tdls_status - Return TDLS session status
2232 * @message: Pointer to incoming dbus message
2233 * @wpa_s: wpa_supplicant structure for a network interface
2234 * Returns: A string representing the state of the link to this TDLS peer
2236 * Handler function for "TDLSStatus" method call of network interface.
2238 DBusMessage * wpas_dbus_handler_tdls_status(DBusMessage *message,
2239 struct wpa_supplicant *wpa_s)
2243 const char *tdls_status;
2245 if (get_peer_hwaddr_helper(message, __func__, peer, &reply) < 0)
2248 wpa_printf(MSG_DEBUG, "DBUS TDLS_STATUS " MACSTR, MAC2STR(peer));
2250 tdls_status = wpa_tdls_get_link_status(wpa_s->wpa, peer);
2252 reply = dbus_message_new_method_return(message);
2253 dbus_message_append_args(reply, DBUS_TYPE_STRING,
2254 &tdls_status, DBUS_TYPE_INVALID);
2260 * wpas_dbus_handler_tdls_teardown - Teardown TDLS session
2261 * @message: Pointer to incoming dbus message
2262 * @wpa_s: wpa_supplicant structure for a network interface
2263 * Returns: NULL indicating success or DBus error message on failure
2265 * Handler function for "TDLSTeardown" method call of network interface.
2267 DBusMessage * wpas_dbus_handler_tdls_teardown(DBusMessage *message,
2268 struct wpa_supplicant *wpa_s)
2271 DBusMessage *error_reply;
2274 if (get_peer_hwaddr_helper(message, __func__, peer, &error_reply) < 0)
2277 wpa_printf(MSG_DEBUG, "DBUS TDLS_TEARDOWN " MACSTR, MAC2STR(peer));
2279 if (wpa_tdls_is_external_setup(wpa_s->wpa))
2280 ret = wpa_tdls_teardown_link(
2282 WLAN_REASON_TDLS_TEARDOWN_UNSPECIFIED);
2284 ret = wpa_drv_tdls_oper(wpa_s, TDLS_TEARDOWN, peer);
2287 return wpas_dbus_error_unknown_error(
2288 message, "error performing TDLS teardown");
2294 #endif /* CONFIG_TDLS */
2298 * wpas_dbus_handler_set_pkcs11_engine_and_module_path - Set PKCS #11 engine and module path
2299 * @message: Pointer to incoming dbus message
2300 * @wpa_s: %wpa_supplicant data structure
2301 * Returns: A dbus message containing an error on failure or NULL on success
2303 * Sets the PKCS #11 engine and module path.
2305 DBusMessage * wpas_dbus_handler_set_pkcs11_engine_and_module_path(
2306 DBusMessage *message, struct wpa_supplicant *wpa_s)
2308 DBusMessageIter iter;
2310 char *pkcs11_engine_path = NULL;
2311 char *pkcs11_module_path = NULL;
2313 dbus_message_iter_init(message, &iter);
2314 dbus_message_iter_get_basic(&iter, &value);
2315 if (value == NULL) {
2316 return dbus_message_new_error(
2317 message, DBUS_ERROR_INVALID_ARGS,
2318 "Invalid pkcs11_engine_path argument");
2320 /* Empty path defaults to NULL */
2321 if (os_strlen(value))
2322 pkcs11_engine_path = value;
2324 dbus_message_iter_next(&iter);
2325 dbus_message_iter_get_basic(&iter, &value);
2326 if (value == NULL) {
2327 os_free(pkcs11_engine_path);
2328 return dbus_message_new_error(
2329 message, DBUS_ERROR_INVALID_ARGS,
2330 "Invalid pkcs11_module_path argument");
2332 /* Empty path defaults to NULL */
2333 if (os_strlen(value))
2334 pkcs11_module_path = value;
2336 if (wpas_set_pkcs11_engine_and_module_path(wpa_s, pkcs11_engine_path,
2337 pkcs11_module_path))
2338 return dbus_message_new_error(
2339 message, DBUS_ERROR_FAILED,
2340 "Reinit of the EAPOL state machine with the new PKCS #11 engine and module path failed.");
2342 if (wpa_s->dbus_new_path) {
2343 wpa_dbus_mark_property_changed(
2344 wpa_s->global->dbus, wpa_s->dbus_new_path,
2345 WPAS_DBUS_NEW_IFACE_INTERFACE, "PKCS11EnginePath");
2346 wpa_dbus_mark_property_changed(
2347 wpa_s->global->dbus, wpa_s->dbus_new_path,
2348 WPAS_DBUS_NEW_IFACE_INTERFACE, "PKCS11ModulePath");
2356 * wpas_dbus_getter_capabilities - Return interface capabilities
2357 * @iter: Pointer to incoming dbus message iter
2358 * @error: Location to store error on failure
2359 * @user_data: Function specific data
2360 * Returns: TRUE on success, FALSE on failure
2362 * Getter for "Capabilities" property of an interface.
2364 dbus_bool_t wpas_dbus_getter_capabilities(
2365 const struct wpa_dbus_property_desc *property_desc,
2366 DBusMessageIter *iter, DBusError *error, void *user_data)
2368 struct wpa_supplicant *wpa_s = user_data;
2369 struct wpa_driver_capa capa;
2371 DBusMessageIter iter_dict, iter_dict_entry, iter_dict_val, iter_array,
2373 const char *scans[] = { "active", "passive", "ssid" };
2375 if (!dbus_message_iter_open_container(iter, DBUS_TYPE_VARIANT,
2376 "a{sv}", &variant_iter) ||
2377 !wpa_dbus_dict_open_write(&variant_iter, &iter_dict))
2380 res = wpa_drv_get_capa(wpa_s, &capa);
2382 /***** pairwise cipher */
2384 const char *args[] = {"ccmp", "tkip", "none"};
2386 if (!wpa_dbus_dict_append_string_array(
2387 &iter_dict, "Pairwise", args,
2391 if (!wpa_dbus_dict_begin_string_array(&iter_dict, "Pairwise",
2395 ((capa.enc & WPA_DRIVER_CAPA_ENC_CCMP_256) &&
2396 !wpa_dbus_dict_string_array_add_element(
2397 &iter_array, "ccmp-256")) ||
2398 ((capa.enc & WPA_DRIVER_CAPA_ENC_GCMP_256) &&
2399 !wpa_dbus_dict_string_array_add_element(
2400 &iter_array, "gcmp-256")) ||
2401 ((capa.enc & WPA_DRIVER_CAPA_ENC_CCMP) &&
2402 !wpa_dbus_dict_string_array_add_element(
2403 &iter_array, "ccmp")) ||
2404 ((capa.enc & WPA_DRIVER_CAPA_ENC_GCMP) &&
2405 !wpa_dbus_dict_string_array_add_element(
2406 &iter_array, "gcmp")) ||
2407 ((capa.enc & WPA_DRIVER_CAPA_ENC_TKIP) &&
2408 !wpa_dbus_dict_string_array_add_element(
2409 &iter_array, "tkip")) ||
2410 ((capa.key_mgmt & WPA_DRIVER_CAPA_KEY_MGMT_WPA_NONE) &&
2411 !wpa_dbus_dict_string_array_add_element(
2412 &iter_array, "none")) ||
2413 !wpa_dbus_dict_end_string_array(&iter_dict,
2420 /***** group cipher */
2422 const char *args[] = {
2423 "ccmp", "tkip", "wep104", "wep40"
2426 if (!wpa_dbus_dict_append_string_array(
2427 &iter_dict, "Group", args,
2431 if (!wpa_dbus_dict_begin_string_array(&iter_dict, "Group",
2435 ((capa.enc & WPA_DRIVER_CAPA_ENC_CCMP_256) &&
2436 !wpa_dbus_dict_string_array_add_element(
2437 &iter_array, "ccmp-256")) ||
2438 ((capa.enc & WPA_DRIVER_CAPA_ENC_GCMP_256) &&
2439 !wpa_dbus_dict_string_array_add_element(
2440 &iter_array, "gcmp-256")) ||
2441 ((capa.enc & WPA_DRIVER_CAPA_ENC_CCMP) &&
2442 !wpa_dbus_dict_string_array_add_element(
2443 &iter_array, "ccmp")) ||
2444 ((capa.enc & WPA_DRIVER_CAPA_ENC_GCMP) &&
2445 !wpa_dbus_dict_string_array_add_element(
2446 &iter_array, "gcmp")) ||
2447 ((capa.enc & WPA_DRIVER_CAPA_ENC_TKIP) &&
2448 !wpa_dbus_dict_string_array_add_element(
2449 &iter_array, "tkip")) ||
2450 ((capa.enc & WPA_DRIVER_CAPA_ENC_WEP104) &&
2451 !wpa_dbus_dict_string_array_add_element(
2452 &iter_array, "wep104")) ||
2453 ((capa.enc & WPA_DRIVER_CAPA_ENC_WEP40) &&
2454 !wpa_dbus_dict_string_array_add_element(
2455 &iter_array, "wep40")) ||
2456 !wpa_dbus_dict_end_string_array(&iter_dict,
2463 /***** key management */
2465 const char *args[] = {
2466 "wpa-psk", "wpa-eap", "ieee8021x", "wpa-none",
2469 #endif /* CONFIG_WPS */
2472 if (!wpa_dbus_dict_append_string_array(
2473 &iter_dict, "KeyMgmt", args,
2477 if (!wpa_dbus_dict_begin_string_array(&iter_dict, "KeyMgmt",
2481 !wpa_dbus_dict_string_array_add_element(&iter_array,
2483 !wpa_dbus_dict_string_array_add_element(&iter_array,
2487 if (capa.key_mgmt & (WPA_DRIVER_CAPA_KEY_MGMT_WPA |
2488 WPA_DRIVER_CAPA_KEY_MGMT_WPA2)) {
2489 if (!wpa_dbus_dict_string_array_add_element(
2490 &iter_array, "wpa-eap") ||
2491 ((capa.key_mgmt & WPA_DRIVER_CAPA_KEY_MGMT_FT) &&
2492 !wpa_dbus_dict_string_array_add_element(
2493 &iter_array, "wpa-ft-eap")))
2496 /* TODO: Ensure that driver actually supports sha256 encryption. */
2497 #ifdef CONFIG_IEEE80211W
2498 if (!wpa_dbus_dict_string_array_add_element(
2499 &iter_array, "wpa-eap-sha256"))
2501 #endif /* CONFIG_IEEE80211W */
2504 if (capa.key_mgmt & (WPA_DRIVER_CAPA_KEY_MGMT_WPA_PSK |
2505 WPA_DRIVER_CAPA_KEY_MGMT_WPA2_PSK)) {
2506 if (!wpa_dbus_dict_string_array_add_element(
2507 &iter_array, "wpa-psk") ||
2509 WPA_DRIVER_CAPA_KEY_MGMT_FT_PSK) &&
2510 !wpa_dbus_dict_string_array_add_element(
2511 &iter_array, "wpa-ft-psk")))
2514 /* TODO: Ensure that driver actually supports sha256 encryption. */
2515 #ifdef CONFIG_IEEE80211W
2516 if (!wpa_dbus_dict_string_array_add_element(
2517 &iter_array, "wpa-psk-sha256"))
2519 #endif /* CONFIG_IEEE80211W */
2522 if ((capa.key_mgmt & WPA_DRIVER_CAPA_KEY_MGMT_WPA_NONE) &&
2523 !wpa_dbus_dict_string_array_add_element(&iter_array,
2529 if (!wpa_dbus_dict_string_array_add_element(&iter_array,
2532 #endif /* CONFIG_WPS */
2534 if (!wpa_dbus_dict_end_string_array(&iter_dict,
2541 /***** WPA protocol */
2543 const char *args[] = { "rsn", "wpa" };
2545 if (!wpa_dbus_dict_append_string_array(
2546 &iter_dict, "Protocol", args,
2550 if (!wpa_dbus_dict_begin_string_array(&iter_dict, "Protocol",
2554 ((capa.key_mgmt & (WPA_DRIVER_CAPA_KEY_MGMT_WPA2 |
2555 WPA_DRIVER_CAPA_KEY_MGMT_WPA2_PSK)) &&
2556 !wpa_dbus_dict_string_array_add_element(
2557 &iter_array, "rsn")) ||
2558 ((capa.key_mgmt & (WPA_DRIVER_CAPA_KEY_MGMT_WPA |
2559 WPA_DRIVER_CAPA_KEY_MGMT_WPA_PSK)) &&
2560 !wpa_dbus_dict_string_array_add_element(
2561 &iter_array, "wpa")) ||
2562 !wpa_dbus_dict_end_string_array(&iter_dict,
2571 const char *args[] = { "open", "shared", "leap" };
2573 if (!wpa_dbus_dict_append_string_array(
2574 &iter_dict, "AuthAlg", args,
2578 if (!wpa_dbus_dict_begin_string_array(&iter_dict, "AuthAlg",
2584 if (((capa.auth & WPA_DRIVER_AUTH_OPEN) &&
2585 !wpa_dbus_dict_string_array_add_element(
2586 &iter_array, "open")) ||
2587 ((capa.auth & WPA_DRIVER_AUTH_SHARED) &&
2588 !wpa_dbus_dict_string_array_add_element(
2589 &iter_array, "shared")) ||
2590 ((capa.auth & WPA_DRIVER_AUTH_LEAP) &&
2591 !wpa_dbus_dict_string_array_add_element(
2592 &iter_array, "leap")) ||
2593 !wpa_dbus_dict_end_string_array(&iter_dict,
2601 if (!wpa_dbus_dict_append_string_array(&iter_dict, "Scan", scans,
2606 if (!wpa_dbus_dict_begin_string_array(&iter_dict, "Modes",
2610 !wpa_dbus_dict_string_array_add_element(
2611 &iter_array, "infrastructure") ||
2612 !wpa_dbus_dict_string_array_add_element(
2613 &iter_array, "ad-hoc") ||
2614 (res >= 0 && (capa.flags & WPA_DRIVER_FLAGS_AP) &&
2615 !wpa_dbus_dict_string_array_add_element(
2616 &iter_array, "ap")) ||
2617 (res >= 0 && (capa.flags & WPA_DRIVER_FLAGS_P2P_CAPABLE) &&
2618 !wpa_dbus_dict_string_array_add_element(
2619 &iter_array, "p2p")) ||
2620 !wpa_dbus_dict_end_string_array(&iter_dict,
2628 dbus_int32_t max_scan_ssid = capa.max_scan_ssids;
2630 if (!wpa_dbus_dict_append_int32(&iter_dict, "MaxScanSSID",
2635 if (!wpa_dbus_dict_close_write(&variant_iter, &iter_dict) ||
2636 !dbus_message_iter_close_container(iter, &variant_iter))
2642 dbus_set_error_const(error, DBUS_ERROR_NO_MEMORY, "no memory");
2648 * wpas_dbus_getter_state - Get interface state
2649 * @iter: Pointer to incoming dbus message iter
2650 * @error: Location to store error on failure
2651 * @user_data: Function specific data
2652 * Returns: TRUE on success, FALSE on failure
2654 * Getter for "State" property.
2656 dbus_bool_t wpas_dbus_getter_state(
2657 const struct wpa_dbus_property_desc *property_desc,
2658 DBusMessageIter *iter, DBusError *error, void *user_data)
2660 struct wpa_supplicant *wpa_s = user_data;
2661 const char *str_state;
2662 char *state_ls, *tmp;
2663 dbus_bool_t success = FALSE;
2665 str_state = wpa_supplicant_state_txt(wpa_s->wpa_state);
2667 /* make state string lowercase to fit new DBus API convention
2669 state_ls = tmp = os_strdup(str_state);
2671 dbus_set_error_const(error, DBUS_ERROR_NO_MEMORY, "no memory");
2675 *tmp = tolower(*tmp);
2679 success = wpas_dbus_simple_property_getter(iter, DBUS_TYPE_STRING,
2689 * wpas_dbus_new_iface_get_scanning - Get interface scanning state
2690 * @iter: Pointer to incoming dbus message iter
2691 * @error: Location to store error on failure
2692 * @user_data: Function specific data
2693 * Returns: TRUE on success, FALSE on failure
2695 * Getter for "scanning" property.
2697 dbus_bool_t wpas_dbus_getter_scanning(
2698 const struct wpa_dbus_property_desc *property_desc,
2699 DBusMessageIter *iter, DBusError *error, void *user_data)
2701 struct wpa_supplicant *wpa_s = user_data;
2702 dbus_bool_t scanning = wpa_s->scanning ? TRUE : FALSE;
2704 return wpas_dbus_simple_property_getter(iter, DBUS_TYPE_BOOLEAN,
2710 * wpas_dbus_getter_ap_scan - Control roaming mode
2711 * @iter: Pointer to incoming dbus message iter
2712 * @error: Location to store error on failure
2713 * @user_data: Function specific data
2714 * Returns: TRUE on success, FALSE on failure
2716 * Getter function for "ApScan" property.
2718 dbus_bool_t wpas_dbus_getter_ap_scan(
2719 const struct wpa_dbus_property_desc *property_desc,
2720 DBusMessageIter *iter, DBusError *error, void *user_data)
2722 struct wpa_supplicant *wpa_s = user_data;
2723 dbus_uint32_t ap_scan = wpa_s->conf->ap_scan;
2725 return wpas_dbus_simple_property_getter(iter, DBUS_TYPE_UINT32,
2731 * wpas_dbus_setter_ap_scan - Control roaming mode
2732 * @iter: Pointer to incoming dbus message iter
2733 * @error: Location to store error on failure
2734 * @user_data: Function specific data
2735 * Returns: TRUE on success, FALSE on failure
2737 * Setter function for "ApScan" property.
2739 dbus_bool_t wpas_dbus_setter_ap_scan(
2740 const struct wpa_dbus_property_desc *property_desc,
2741 DBusMessageIter *iter, DBusError *error, void *user_data)
2743 struct wpa_supplicant *wpa_s = user_data;
2744 dbus_uint32_t ap_scan;
2746 if (!wpas_dbus_simple_property_setter(iter, error, DBUS_TYPE_UINT32,
2750 if (wpa_supplicant_set_ap_scan(wpa_s, ap_scan)) {
2751 dbus_set_error_const(error, DBUS_ERROR_FAILED,
2752 "ap_scan must be 0, 1, or 2");
2760 * wpas_dbus_getter_fast_reauth - Control fast
2761 * reauthentication (TLS session resumption)
2762 * @iter: Pointer to incoming dbus message iter
2763 * @error: Location to store error on failure
2764 * @user_data: Function specific data
2765 * Returns: TRUE on success, FALSE on failure
2767 * Getter function for "FastReauth" property.
2769 dbus_bool_t wpas_dbus_getter_fast_reauth(
2770 const struct wpa_dbus_property_desc *property_desc,
2771 DBusMessageIter *iter, DBusError *error, void *user_data)
2773 struct wpa_supplicant *wpa_s = user_data;
2774 dbus_bool_t fast_reauth = wpa_s->conf->fast_reauth ? TRUE : FALSE;
2776 return wpas_dbus_simple_property_getter(iter, DBUS_TYPE_BOOLEAN,
2777 &fast_reauth, error);
2782 * wpas_dbus_setter_fast_reauth - Control fast
2783 * reauthentication (TLS session resumption)
2784 * @iter: Pointer to incoming dbus message iter
2785 * @error: Location to store error on failure
2786 * @user_data: Function specific data
2787 * Returns: TRUE on success, FALSE on failure
2789 * Setter function for "FastReauth" property.
2791 dbus_bool_t wpas_dbus_setter_fast_reauth(
2792 const struct wpa_dbus_property_desc *property_desc,
2793 DBusMessageIter *iter, DBusError *error, void *user_data)
2795 struct wpa_supplicant *wpa_s = user_data;
2796 dbus_bool_t fast_reauth;
2798 if (!wpas_dbus_simple_property_setter(iter, error, DBUS_TYPE_BOOLEAN,
2802 wpa_s->conf->fast_reauth = fast_reauth;
2808 * wpas_dbus_getter_disconnect_reason - Get most recent reason for disconnect
2809 * @iter: Pointer to incoming dbus message iter
2810 * @error: Location to store error on failure
2811 * @user_data: Function specific data
2812 * Returns: TRUE on success, FALSE on failure
2814 * Getter for "DisconnectReason" property. The reason is negative if it is
2815 * locally generated.
2817 dbus_bool_t wpas_dbus_getter_disconnect_reason(
2818 const struct wpa_dbus_property_desc *property_desc,
2819 DBusMessageIter *iter, DBusError *error, void *user_data)
2821 struct wpa_supplicant *wpa_s = user_data;
2822 dbus_int32_t reason = wpa_s->disconnect_reason;
2824 return wpas_dbus_simple_property_getter(iter, DBUS_TYPE_INT32,
2830 * wpas_dbus_getter_bss_expire_age - Get BSS entry expiration age
2831 * @iter: Pointer to incoming dbus message iter
2832 * @error: Location to store error on failure
2833 * @user_data: Function specific data
2834 * Returns: TRUE on success, FALSE on failure
2836 * Getter function for "BSSExpireAge" property.
2838 dbus_bool_t wpas_dbus_getter_bss_expire_age(
2839 const struct wpa_dbus_property_desc *property_desc,
2840 DBusMessageIter *iter, DBusError *error, void *user_data)
2842 struct wpa_supplicant *wpa_s = user_data;
2843 dbus_uint32_t expire_age = wpa_s->conf->bss_expiration_age;
2845 return wpas_dbus_simple_property_getter(iter, DBUS_TYPE_UINT32,
2846 &expire_age, error);
2851 * wpas_dbus_setter_bss_expire_age - Control BSS entry expiration age
2852 * @iter: Pointer to incoming dbus message iter
2853 * @error: Location to store error on failure
2854 * @user_data: Function specific data
2855 * Returns: TRUE on success, FALSE on failure
2857 * Setter function for "BSSExpireAge" property.
2859 dbus_bool_t wpas_dbus_setter_bss_expire_age(
2860 const struct wpa_dbus_property_desc *property_desc,
2861 DBusMessageIter *iter, DBusError *error, void *user_data)
2863 struct wpa_supplicant *wpa_s = user_data;
2864 dbus_uint32_t expire_age;
2866 if (!wpas_dbus_simple_property_setter(iter, error, DBUS_TYPE_UINT32,
2870 if (wpa_supplicant_set_bss_expiration_age(wpa_s, expire_age)) {
2871 dbus_set_error_const(error, DBUS_ERROR_FAILED,
2872 "BSSExpireAge must be >= 10");
2880 * wpas_dbus_getter_bss_expire_count - Get BSS entry expiration scan count
2881 * @iter: Pointer to incoming dbus message iter
2882 * @error: Location to store error on failure
2883 * @user_data: Function specific data
2884 * Returns: TRUE on success, FALSE on failure
2886 * Getter function for "BSSExpireCount" property.
2888 dbus_bool_t wpas_dbus_getter_bss_expire_count(
2889 const struct wpa_dbus_property_desc *property_desc,
2890 DBusMessageIter *iter, DBusError *error, void *user_data)
2892 struct wpa_supplicant *wpa_s = user_data;
2893 dbus_uint32_t expire_count = wpa_s->conf->bss_expiration_scan_count;
2895 return wpas_dbus_simple_property_getter(iter, DBUS_TYPE_UINT32,
2896 &expire_count, error);
2901 * wpas_dbus_setter_bss_expire_count - Control BSS entry expiration scan count
2902 * @iter: Pointer to incoming dbus message iter
2903 * @error: Location to store error on failure
2904 * @user_data: Function specific data
2905 * Returns: TRUE on success, FALSE on failure
2907 * Setter function for "BSSExpireCount" property.
2909 dbus_bool_t wpas_dbus_setter_bss_expire_count(
2910 const struct wpa_dbus_property_desc *property_desc,
2911 DBusMessageIter *iter, DBusError *error, void *user_data)
2913 struct wpa_supplicant *wpa_s = user_data;
2914 dbus_uint32_t expire_count;
2916 if (!wpas_dbus_simple_property_setter(iter, error, DBUS_TYPE_UINT32,
2920 if (wpa_supplicant_set_bss_expiration_count(wpa_s, expire_count)) {
2921 dbus_set_error_const(error, DBUS_ERROR_FAILED,
2922 "BSSExpireCount must be > 0");
2930 * wpas_dbus_getter_country - Control country code
2931 * @iter: Pointer to incoming dbus message iter
2932 * @error: Location to store error on failure
2933 * @user_data: Function specific data
2934 * Returns: TRUE on success, FALSE on failure
2936 * Getter function for "Country" property.
2938 dbus_bool_t wpas_dbus_getter_country(
2939 const struct wpa_dbus_property_desc *property_desc,
2940 DBusMessageIter *iter, DBusError *error, void *user_data)
2942 struct wpa_supplicant *wpa_s = user_data;
2944 char *str = country;
2946 country[0] = wpa_s->conf->country[0];
2947 country[1] = wpa_s->conf->country[1];
2950 return wpas_dbus_simple_property_getter(iter, DBUS_TYPE_STRING,
2956 * wpas_dbus_setter_country - Control country code
2957 * @iter: Pointer to incoming dbus message iter
2958 * @error: Location to store error on failure
2959 * @user_data: Function specific data
2960 * Returns: TRUE on success, FALSE on failure
2962 * Setter function for "Country" property.
2964 dbus_bool_t wpas_dbus_setter_country(
2965 const struct wpa_dbus_property_desc *property_desc,
2966 DBusMessageIter *iter, DBusError *error, void *user_data)
2968 struct wpa_supplicant *wpa_s = user_data;
2969 const char *country;
2971 if (!wpas_dbus_simple_property_setter(iter, error, DBUS_TYPE_STRING,
2975 if (!country[0] || !country[1]) {
2976 dbus_set_error_const(error, DBUS_ERROR_FAILED,
2977 "invalid country code");
2981 if (wpa_s->drv_priv != NULL && wpa_drv_set_country(wpa_s, country)) {
2982 wpa_printf(MSG_DEBUG, "Failed to set country");
2983 dbus_set_error_const(error, DBUS_ERROR_FAILED,
2984 "failed to set country code");
2988 wpa_s->conf->country[0] = country[0];
2989 wpa_s->conf->country[1] = country[1];
2995 * wpas_dbus_getter_scan_interval - Get scan interval
2996 * @iter: Pointer to incoming dbus message iter
2997 * @error: Location to store error on failure
2998 * @user_data: Function specific data
2999 * Returns: TRUE on success, FALSE on failure
3001 * Getter function for "ScanInterval" property.
3003 dbus_bool_t wpas_dbus_getter_scan_interval(
3004 const struct wpa_dbus_property_desc *property_desc,
3005 DBusMessageIter *iter, DBusError *error, void *user_data)
3007 struct wpa_supplicant *wpa_s = user_data;
3008 dbus_int32_t scan_interval = wpa_s->scan_interval;
3010 return wpas_dbus_simple_property_getter(iter, DBUS_TYPE_INT32,
3011 &scan_interval, error);
3016 * wpas_dbus_setter_scan_interval - Control scan interval
3017 * @iter: Pointer to incoming dbus message iter
3018 * @error: Location to store error on failure
3019 * @user_data: Function specific data
3020 * Returns: TRUE on success, FALSE on failure
3022 * Setter function for "ScanInterval" property.
3024 dbus_bool_t wpas_dbus_setter_scan_interval(
3025 const struct wpa_dbus_property_desc *property_desc,
3026 DBusMessageIter *iter, DBusError *error, void *user_data)
3028 struct wpa_supplicant *wpa_s = user_data;
3029 dbus_int32_t scan_interval;
3031 if (!wpas_dbus_simple_property_setter(iter, error, DBUS_TYPE_INT32,
3035 if (wpa_supplicant_set_scan_interval(wpa_s, scan_interval)) {
3036 dbus_set_error_const(error, DBUS_ERROR_FAILED,
3037 "scan_interval must be >= 0");
3045 * wpas_dbus_getter_ifname - Get interface name
3046 * @iter: Pointer to incoming dbus message iter
3047 * @error: Location to store error on failure
3048 * @user_data: Function specific data
3049 * Returns: TRUE on success, FALSE on failure
3051 * Getter for "Ifname" property.
3053 dbus_bool_t wpas_dbus_getter_ifname(
3054 const struct wpa_dbus_property_desc *property_desc,
3055 DBusMessageIter *iter, DBusError *error, void *user_data)
3057 struct wpa_supplicant *wpa_s = user_data;
3058 const char *ifname = wpa_s->ifname;
3060 return wpas_dbus_simple_property_getter(iter, DBUS_TYPE_STRING,
3066 * wpas_dbus_getter_driver - Get interface name
3067 * @iter: Pointer to incoming dbus message iter
3068 * @error: Location to store error on failure
3069 * @user_data: Function specific data
3070 * Returns: TRUE on success, FALSE on failure
3072 * Getter for "Driver" property.
3074 dbus_bool_t wpas_dbus_getter_driver(
3075 const struct wpa_dbus_property_desc *property_desc,
3076 DBusMessageIter *iter, DBusError *error, void *user_data)
3078 struct wpa_supplicant *wpa_s = user_data;
3081 if (wpa_s->driver == NULL || wpa_s->driver->name == NULL) {
3082 wpa_printf(MSG_DEBUG, "%s[dbus]: wpa_s has no driver set",
3084 dbus_set_error(error, DBUS_ERROR_FAILED, "%s: no driver set",
3089 driver = wpa_s->driver->name;
3090 return wpas_dbus_simple_property_getter(iter, DBUS_TYPE_STRING,
3096 * wpas_dbus_getter_current_bss - Get current bss object path
3097 * @iter: Pointer to incoming dbus message iter
3098 * @error: Location to store error on failure
3099 * @user_data: Function specific data
3100 * Returns: TRUE on success, FALSE on failure
3102 * Getter for "CurrentBSS" property.
3104 dbus_bool_t wpas_dbus_getter_current_bss(
3105 const struct wpa_dbus_property_desc *property_desc,
3106 DBusMessageIter *iter, DBusError *error, void *user_data)
3108 struct wpa_supplicant *wpa_s = user_data;
3109 char path_buf[WPAS_DBUS_OBJECT_PATH_MAX], *bss_obj_path = path_buf;
3111 if (wpa_s->current_bss && wpa_s->dbus_new_path)
3112 os_snprintf(bss_obj_path, WPAS_DBUS_OBJECT_PATH_MAX,
3113 "%s/" WPAS_DBUS_NEW_BSSIDS_PART "/%u",
3114 wpa_s->dbus_new_path, wpa_s->current_bss->id);
3116 os_snprintf(bss_obj_path, WPAS_DBUS_OBJECT_PATH_MAX, "/");
3118 return wpas_dbus_simple_property_getter(iter, DBUS_TYPE_OBJECT_PATH,
3119 &bss_obj_path, error);
3124 * wpas_dbus_getter_current_network - Get current network object path
3125 * @iter: Pointer to incoming dbus message iter
3126 * @error: Location to store error on failure
3127 * @user_data: Function specific data
3128 * Returns: TRUE on success, FALSE on failure
3130 * Getter for "CurrentNetwork" property.
3132 dbus_bool_t wpas_dbus_getter_current_network(
3133 const struct wpa_dbus_property_desc *property_desc,
3134 DBusMessageIter *iter, DBusError *error, void *user_data)
3136 struct wpa_supplicant *wpa_s = user_data;
3137 char path_buf[WPAS_DBUS_OBJECT_PATH_MAX], *net_obj_path = path_buf;
3139 if (wpa_s->current_ssid && wpa_s->dbus_new_path)
3140 os_snprintf(net_obj_path, WPAS_DBUS_OBJECT_PATH_MAX,
3141 "%s/" WPAS_DBUS_NEW_NETWORKS_PART "/%u",
3142 wpa_s->dbus_new_path, wpa_s->current_ssid->id);
3144 os_snprintf(net_obj_path, WPAS_DBUS_OBJECT_PATH_MAX, "/");
3146 return wpas_dbus_simple_property_getter(iter, DBUS_TYPE_OBJECT_PATH,
3147 &net_obj_path, error);
3152 * wpas_dbus_getter_current_auth_mode - Get current authentication type
3153 * @iter: Pointer to incoming dbus message iter
3154 * @error: Location to store error on failure
3155 * @user_data: Function specific data
3156 * Returns: TRUE on success, FALSE on failure
3158 * Getter for "CurrentAuthMode" property.
3160 dbus_bool_t wpas_dbus_getter_current_auth_mode(
3161 const struct wpa_dbus_property_desc *property_desc,
3162 DBusMessageIter *iter, DBusError *error, void *user_data)
3164 struct wpa_supplicant *wpa_s = user_data;
3165 const char *eap_mode;
3166 const char *auth_mode;
3167 char eap_mode_buf[WPAS_DBUS_AUTH_MODE_MAX];
3169 if (wpa_s->wpa_state != WPA_COMPLETED) {
3170 auth_mode = "INACTIVE";
3171 } else if (wpa_s->key_mgmt == WPA_KEY_MGMT_IEEE8021X ||
3172 wpa_s->key_mgmt == WPA_KEY_MGMT_IEEE8021X_NO_WPA) {
3173 eap_mode = wpa_supplicant_get_eap_mode(wpa_s);
3174 os_snprintf(eap_mode_buf, WPAS_DBUS_AUTH_MODE_MAX,
3175 "EAP-%s", eap_mode);
3176 auth_mode = eap_mode_buf;
3179 auth_mode = wpa_key_mgmt_txt(wpa_s->key_mgmt,
3180 wpa_s->current_ssid->proto);
3183 return wpas_dbus_simple_property_getter(iter, DBUS_TYPE_STRING,
3189 * wpas_dbus_getter_bridge_ifname - Get interface name
3190 * @iter: Pointer to incoming dbus message iter
3191 * @error: Location to store error on failure
3192 * @user_data: Function specific data
3193 * Returns: TRUE on success, FALSE on failure
3195 * Getter for "BridgeIfname" property.
3197 dbus_bool_t wpas_dbus_getter_bridge_ifname(
3198 const struct wpa_dbus_property_desc *property_desc,
3199 DBusMessageIter *iter, DBusError *error, void *user_data)
3201 struct wpa_supplicant *wpa_s = user_data;
3202 const char *bridge_ifname = wpa_s->bridge_ifname;
3204 return wpas_dbus_simple_property_getter(iter, DBUS_TYPE_STRING,
3205 &bridge_ifname, error);
3210 * wpas_dbus_getter_bsss - Get array of BSSs objects
3211 * @iter: Pointer to incoming dbus message iter
3212 * @error: Location to store error on failure
3213 * @user_data: Function specific data
3214 * Returns: TRUE on success, FALSE on failure
3216 * Getter for "BSSs" property.
3218 dbus_bool_t wpas_dbus_getter_bsss(
3219 const struct wpa_dbus_property_desc *property_desc,
3220 DBusMessageIter *iter, DBusError *error, void *user_data)
3222 struct wpa_supplicant *wpa_s = user_data;
3223 struct wpa_bss *bss;
3226 dbus_bool_t success = FALSE;
3228 if (!wpa_s->dbus_new_path) {
3229 dbus_set_error(error, DBUS_ERROR_FAILED,
3230 "%s: no D-Bus interface", __func__);
3234 paths = os_calloc(wpa_s->num_bss, sizeof(char *));
3236 dbus_set_error_const(error, DBUS_ERROR_NO_MEMORY, "no memory");
3240 /* Loop through scan results and append each result's object path */
3241 dl_list_for_each(bss, &wpa_s->bss_id, struct wpa_bss, list_id) {
3242 paths[i] = os_zalloc(WPAS_DBUS_OBJECT_PATH_MAX);
3243 if (paths[i] == NULL) {
3244 dbus_set_error_const(error, DBUS_ERROR_NO_MEMORY,
3248 /* Construct the object path for this BSS. */
3249 os_snprintf(paths[i++], WPAS_DBUS_OBJECT_PATH_MAX,
3250 "%s/" WPAS_DBUS_NEW_BSSIDS_PART "/%u",
3251 wpa_s->dbus_new_path, bss->id);
3254 success = wpas_dbus_simple_array_property_getter(iter,
3255 DBUS_TYPE_OBJECT_PATH,
3256 paths, wpa_s->num_bss,
3261 os_free(paths[--i]);
3268 * wpas_dbus_getter_networks - Get array of networks objects
3269 * @iter: Pointer to incoming dbus message iter
3270 * @error: Location to store error on failure
3271 * @user_data: Function specific data
3272 * Returns: TRUE on success, FALSE on failure
3274 * Getter for "Networks" property.
3276 dbus_bool_t wpas_dbus_getter_networks(
3277 const struct wpa_dbus_property_desc *property_desc,
3278 DBusMessageIter *iter, DBusError *error, void *user_data)
3280 struct wpa_supplicant *wpa_s = user_data;
3281 struct wpa_ssid *ssid;
3283 unsigned int i = 0, num = 0;
3284 dbus_bool_t success = FALSE;
3286 if (!wpa_s->dbus_new_path) {
3287 dbus_set_error(error, DBUS_ERROR_FAILED,
3288 "%s: no D-Bus interface", __func__);
3292 for (ssid = wpa_s->conf->ssid; ssid; ssid = ssid->next)
3293 if (!network_is_persistent_group(ssid))
3296 paths = os_calloc(num, sizeof(char *));
3298 dbus_set_error(error, DBUS_ERROR_NO_MEMORY, "no memory");
3302 /* Loop through configured networks and append object path of each */
3303 for (ssid = wpa_s->conf->ssid; ssid; ssid = ssid->next) {
3304 if (network_is_persistent_group(ssid))
3306 paths[i] = os_zalloc(WPAS_DBUS_OBJECT_PATH_MAX);
3307 if (paths[i] == NULL) {
3308 dbus_set_error(error, DBUS_ERROR_NO_MEMORY,
3313 /* Construct the object path for this network. */
3314 os_snprintf(paths[i++], WPAS_DBUS_OBJECT_PATH_MAX,
3315 "%s/" WPAS_DBUS_NEW_NETWORKS_PART "/%d",
3316 wpa_s->dbus_new_path, ssid->id);
3319 success = wpas_dbus_simple_array_property_getter(iter,
3320 DBUS_TYPE_OBJECT_PATH,
3325 os_free(paths[--i]);
3332 * wpas_dbus_getter_pkcs11_engine_path - Get PKCS #11 engine path
3333 * @iter: Pointer to incoming dbus message iter
3334 * @error: Location to store error on failure
3335 * @user_data: Function specific data
3336 * Returns: A dbus message containing the PKCS #11 engine path
3338 * Getter for "PKCS11EnginePath" property.
3340 dbus_bool_t wpas_dbus_getter_pkcs11_engine_path(
3341 const struct wpa_dbus_property_desc *property_desc,
3342 DBusMessageIter *iter, DBusError *error, void *user_data)
3344 struct wpa_supplicant *wpa_s = user_data;
3345 const char *pkcs11_engine_path;
3347 if (wpa_s->conf->pkcs11_engine_path == NULL)
3348 pkcs11_engine_path = "";
3350 pkcs11_engine_path = wpa_s->conf->pkcs11_engine_path;
3351 return wpas_dbus_simple_property_getter(iter, DBUS_TYPE_STRING,
3352 &pkcs11_engine_path, error);
3357 * wpas_dbus_getter_pkcs11_module_path - Get PKCS #11 module path
3358 * @iter: Pointer to incoming dbus message iter
3359 * @error: Location to store error on failure
3360 * @user_data: Function specific data
3361 * Returns: A dbus message containing the PKCS #11 module path
3363 * Getter for "PKCS11ModulePath" property.
3365 dbus_bool_t wpas_dbus_getter_pkcs11_module_path(
3366 const struct wpa_dbus_property_desc *property_desc,
3367 DBusMessageIter *iter, DBusError *error, void *user_data)
3369 struct wpa_supplicant *wpa_s = user_data;
3370 const char *pkcs11_module_path;
3372 if (wpa_s->conf->pkcs11_module_path == NULL)
3373 pkcs11_module_path = "";
3375 pkcs11_module_path = wpa_s->conf->pkcs11_module_path;
3376 return wpas_dbus_simple_property_getter(iter, DBUS_TYPE_STRING,
3377 &pkcs11_module_path, error);
3382 * wpas_dbus_getter_blobs - Get all blobs defined for this interface
3383 * @iter: Pointer to incoming dbus message iter
3384 * @error: Location to store error on failure
3385 * @user_data: Function specific data
3386 * Returns: TRUE on success, FALSE on failure
3388 * Getter for "Blobs" property.
3390 dbus_bool_t wpas_dbus_getter_blobs(
3391 const struct wpa_dbus_property_desc *property_desc,
3392 DBusMessageIter *iter, DBusError *error, void *user_data)
3394 struct wpa_supplicant *wpa_s = user_data;
3395 DBusMessageIter variant_iter, dict_iter, entry_iter, array_iter;
3396 struct wpa_config_blob *blob;
3398 if (!dbus_message_iter_open_container(iter, DBUS_TYPE_VARIANT,
3399 "a{say}", &variant_iter) ||
3400 !dbus_message_iter_open_container(&variant_iter, DBUS_TYPE_ARRAY,
3401 "{say}", &dict_iter)) {
3402 dbus_set_error_const(error, DBUS_ERROR_NO_MEMORY, "no memory");
3406 blob = wpa_s->conf->blobs;
3408 if (!dbus_message_iter_open_container(&dict_iter,
3409 DBUS_TYPE_DICT_ENTRY,
3410 NULL, &entry_iter) ||
3411 !dbus_message_iter_append_basic(&entry_iter,
3414 !dbus_message_iter_open_container(&entry_iter,
3416 DBUS_TYPE_BYTE_AS_STRING,
3418 !dbus_message_iter_append_fixed_array(&array_iter,
3422 !dbus_message_iter_close_container(&entry_iter,
3424 !dbus_message_iter_close_container(&dict_iter,
3426 dbus_set_error_const(error, DBUS_ERROR_NO_MEMORY,
3434 if (!dbus_message_iter_close_container(&variant_iter, &dict_iter) ||
3435 !dbus_message_iter_close_container(iter, &variant_iter)) {
3436 dbus_set_error_const(error, DBUS_ERROR_NO_MEMORY, "no memory");
3444 static struct wpa_bss * get_bss_helper(struct bss_handler_args *args,
3445 DBusError *error, const char *func_name)
3447 struct wpa_bss *res = wpa_bss_get_id(args->wpa_s, args->id);
3450 wpa_printf(MSG_ERROR, "%s[dbus]: no bss with id %d found",
3451 func_name, args->id);
3452 dbus_set_error(error, DBUS_ERROR_FAILED,
3453 "%s: BSS %d not found",
3454 func_name, args->id);
3462 * wpas_dbus_getter_bss_bssid - Return the BSSID of a BSS
3463 * @iter: Pointer to incoming dbus message iter
3464 * @error: Location to store error on failure
3465 * @user_data: Function specific data
3466 * Returns: TRUE on success, FALSE on failure
3468 * Getter for "BSSID" property.
3470 dbus_bool_t wpas_dbus_getter_bss_bssid(
3471 const struct wpa_dbus_property_desc *property_desc,
3472 DBusMessageIter *iter, DBusError *error, void *user_data)
3474 struct bss_handler_args *args = user_data;
3475 struct wpa_bss *res;
3477 res = get_bss_helper(args, error, __func__);
3481 return wpas_dbus_simple_array_property_getter(iter, DBUS_TYPE_BYTE,
3482 res->bssid, ETH_ALEN,
3488 * wpas_dbus_getter_bss_ssid - Return the SSID of a BSS
3489 * @iter: Pointer to incoming dbus message iter
3490 * @error: Location to store error on failure
3491 * @user_data: Function specific data
3492 * Returns: TRUE on success, FALSE on failure
3494 * Getter for "SSID" property.
3496 dbus_bool_t wpas_dbus_getter_bss_ssid(
3497 const struct wpa_dbus_property_desc *property_desc,
3498 DBusMessageIter *iter, DBusError *error, void *user_data)
3500 struct bss_handler_args *args = user_data;
3501 struct wpa_bss *res;
3503 res = get_bss_helper(args, error, __func__);
3507 return wpas_dbus_simple_array_property_getter(iter, DBUS_TYPE_BYTE,
3508 res->ssid, res->ssid_len,
3514 * wpas_dbus_getter_bss_privacy - Return the privacy flag of a BSS
3515 * @iter: Pointer to incoming dbus message iter
3516 * @error: Location to store error on failure
3517 * @user_data: Function specific data
3518 * Returns: TRUE on success, FALSE on failure
3520 * Getter for "Privacy" property.
3522 dbus_bool_t wpas_dbus_getter_bss_privacy(
3523 const struct wpa_dbus_property_desc *property_desc,
3524 DBusMessageIter *iter, DBusError *error, void *user_data)
3526 struct bss_handler_args *args = user_data;
3527 struct wpa_bss *res;
3528 dbus_bool_t privacy;
3530 res = get_bss_helper(args, error, __func__);
3534 privacy = (res->caps & IEEE80211_CAP_PRIVACY) ? TRUE : FALSE;
3535 return wpas_dbus_simple_property_getter(iter, DBUS_TYPE_BOOLEAN,
3541 * wpas_dbus_getter_bss_mode - Return the mode of a BSS
3542 * @iter: Pointer to incoming dbus message iter
3543 * @error: Location to store error on failure
3544 * @user_data: Function specific data
3545 * Returns: TRUE on success, FALSE on failure
3547 * Getter for "Mode" property.
3549 dbus_bool_t wpas_dbus_getter_bss_mode(
3550 const struct wpa_dbus_property_desc *property_desc,
3551 DBusMessageIter *iter, DBusError *error, void *user_data)
3553 struct bss_handler_args *args = user_data;
3554 struct wpa_bss *res;
3557 res = get_bss_helper(args, error, __func__);
3560 if (bss_is_dmg(res)) {
3561 switch (res->caps & IEEE80211_CAP_DMG_MASK) {
3562 case IEEE80211_CAP_DMG_PBSS:
3563 case IEEE80211_CAP_DMG_IBSS:
3566 case IEEE80211_CAP_DMG_AP:
3567 mode = "infrastructure";
3571 if (res->caps & IEEE80211_CAP_IBSS)
3574 mode = "infrastructure";
3577 return wpas_dbus_simple_property_getter(iter, DBUS_TYPE_STRING,
3583 * wpas_dbus_getter_bss_level - Return the signal strength of a BSS
3584 * @iter: Pointer to incoming dbus message iter
3585 * @error: Location to store error on failure
3586 * @user_data: Function specific data
3587 * Returns: TRUE on success, FALSE on failure
3589 * Getter for "Level" property.
3591 dbus_bool_t wpas_dbus_getter_bss_signal(
3592 const struct wpa_dbus_property_desc *property_desc,
3593 DBusMessageIter *iter, DBusError *error, void *user_data)
3595 struct bss_handler_args *args = user_data;
3596 struct wpa_bss *res;
3599 res = get_bss_helper(args, error, __func__);
3603 level = (s16) res->level;
3604 return wpas_dbus_simple_property_getter(iter, DBUS_TYPE_INT16,
3610 * wpas_dbus_getter_bss_frequency - Return the frequency of a BSS
3611 * @iter: Pointer to incoming dbus message iter
3612 * @error: Location to store error on failure
3613 * @user_data: Function specific data
3614 * Returns: TRUE on success, FALSE on failure
3616 * Getter for "Frequency" property.
3618 dbus_bool_t wpas_dbus_getter_bss_frequency(
3619 const struct wpa_dbus_property_desc *property_desc,
3620 DBusMessageIter *iter, DBusError *error, void *user_data)
3622 struct bss_handler_args *args = user_data;
3623 struct wpa_bss *res;
3626 res = get_bss_helper(args, error, __func__);
3630 freq = (u16) res->freq;
3631 return wpas_dbus_simple_property_getter(iter, DBUS_TYPE_UINT16,
3636 static int cmp_u8s_desc(const void *a, const void *b)
3638 return (*(u8 *) b - *(u8 *) a);
3643 * wpas_dbus_getter_bss_rates - Return available bit rates of a BSS
3644 * @iter: Pointer to incoming dbus message iter
3645 * @error: Location to store error on failure
3646 * @user_data: Function specific data
3647 * Returns: TRUE on success, FALSE on failure
3649 * Getter for "Rates" property.
3651 dbus_bool_t wpas_dbus_getter_bss_rates(
3652 const struct wpa_dbus_property_desc *property_desc,
3653 DBusMessageIter *iter, DBusError *error, void *user_data)
3655 struct bss_handler_args *args = user_data;
3656 struct wpa_bss *res;
3657 u8 *ie_rates = NULL;
3660 dbus_bool_t success = FALSE;
3662 res = get_bss_helper(args, error, __func__);
3666 rates_num = wpa_bss_get_bit_rates(res, &ie_rates);
3670 qsort(ie_rates, rates_num, 1, cmp_u8s_desc);
3672 real_rates = os_malloc(sizeof(u32) * rates_num);
3675 dbus_set_error_const(error, DBUS_ERROR_NO_MEMORY, "no memory");
3679 for (i = 0; i < rates_num; i++)
3680 real_rates[i] = ie_rates[i] * 500000;
3682 success = wpas_dbus_simple_array_property_getter(iter, DBUS_TYPE_UINT32,
3683 real_rates, rates_num,
3687 os_free(real_rates);
3692 static dbus_bool_t wpas_dbus_get_bss_security_prop(
3693 const struct wpa_dbus_property_desc *property_desc,
3694 DBusMessageIter *iter, struct wpa_ie_data *ie_data, DBusError *error)
3696 DBusMessageIter iter_dict, variant_iter;
3698 const char *pairwise[5]; /* max 5 pairwise ciphers is supported */
3699 const char *key_mgmt[9]; /* max 9 key managements may be supported */
3702 if (!dbus_message_iter_open_container(iter, DBUS_TYPE_VARIANT,
3703 "a{sv}", &variant_iter))
3706 if (!wpa_dbus_dict_open_write(&variant_iter, &iter_dict))
3711 if (ie_data->key_mgmt & WPA_KEY_MGMT_PSK)
3712 key_mgmt[n++] = "wpa-psk";
3713 if (ie_data->key_mgmt & WPA_KEY_MGMT_FT_PSK)
3714 key_mgmt[n++] = "wpa-ft-psk";
3715 if (ie_data->key_mgmt & WPA_KEY_MGMT_PSK_SHA256)
3716 key_mgmt[n++] = "wpa-psk-sha256";
3717 if (ie_data->key_mgmt & WPA_KEY_MGMT_IEEE8021X)
3718 key_mgmt[n++] = "wpa-eap";
3719 if (ie_data->key_mgmt & WPA_KEY_MGMT_FT_IEEE8021X)
3720 key_mgmt[n++] = "wpa-ft-eap";
3721 if (ie_data->key_mgmt & WPA_KEY_MGMT_IEEE8021X_SHA256)
3722 key_mgmt[n++] = "wpa-eap-sha256";
3723 #ifdef CONFIG_SUITEB
3724 if (ie_data->key_mgmt & WPA_KEY_MGMT_IEEE8021X_SUITE_B)
3725 key_mgmt[n++] = "wpa-eap-suite-b";
3726 #endif /* CONFIG_SUITEB */
3727 #ifdef CONFIG_SUITEB192
3728 if (ie_data->key_mgmt & WPA_KEY_MGMT_IEEE8021X_SUITE_B_192)
3729 key_mgmt[n++] = "wpa-eap-suite-b-192";
3730 #endif /* CONFIG_SUITEB192 */
3731 if (ie_data->key_mgmt & WPA_KEY_MGMT_NONE)
3732 key_mgmt[n++] = "wpa-none";
3734 if (!wpa_dbus_dict_append_string_array(&iter_dict, "KeyMgmt",
3739 switch (ie_data->group_cipher) {
3740 case WPA_CIPHER_WEP40:
3743 case WPA_CIPHER_TKIP:
3746 case WPA_CIPHER_CCMP:
3749 case WPA_CIPHER_GCMP:
3752 case WPA_CIPHER_WEP104:
3755 case WPA_CIPHER_CCMP_256:
3758 case WPA_CIPHER_GCMP_256:
3766 if (!wpa_dbus_dict_append_string(&iter_dict, "Group", group))
3771 if (ie_data->pairwise_cipher & WPA_CIPHER_TKIP)
3772 pairwise[n++] = "tkip";
3773 if (ie_data->pairwise_cipher & WPA_CIPHER_CCMP)
3774 pairwise[n++] = "ccmp";
3775 if (ie_data->pairwise_cipher & WPA_CIPHER_GCMP)
3776 pairwise[n++] = "gcmp";
3777 if (ie_data->pairwise_cipher & WPA_CIPHER_CCMP_256)
3778 pairwise[n++] = "ccmp-256";
3779 if (ie_data->pairwise_cipher & WPA_CIPHER_GCMP_256)
3780 pairwise[n++] = "gcmp-256";
3782 if (!wpa_dbus_dict_append_string_array(&iter_dict, "Pairwise",
3786 /* Management group (RSN only) */
3787 if (ie_data->proto == WPA_PROTO_RSN) {
3788 switch (ie_data->mgmt_group_cipher) {
3789 #ifdef CONFIG_IEEE80211W
3790 case WPA_CIPHER_AES_128_CMAC:
3791 group = "aes128cmac";
3793 #endif /* CONFIG_IEEE80211W */
3799 if (!wpa_dbus_dict_append_string(&iter_dict, "MgmtGroup",
3804 if (!wpa_dbus_dict_close_write(&variant_iter, &iter_dict) ||
3805 !dbus_message_iter_close_container(iter, &variant_iter))
3811 dbus_set_error_const(error, DBUS_ERROR_NO_MEMORY, "no memory");
3817 * wpas_dbus_getter_bss_wpa - Return the WPA options of a BSS
3818 * @iter: Pointer to incoming dbus message iter
3819 * @error: Location to store error on failure
3820 * @user_data: Function specific data
3821 * Returns: TRUE on success, FALSE on failure
3823 * Getter for "WPA" property.
3825 dbus_bool_t wpas_dbus_getter_bss_wpa(
3826 const struct wpa_dbus_property_desc *property_desc,
3827 DBusMessageIter *iter, DBusError *error, void *user_data)
3829 struct bss_handler_args *args = user_data;
3830 struct wpa_bss *res;
3831 struct wpa_ie_data wpa_data;
3834 res = get_bss_helper(args, error, __func__);
3838 os_memset(&wpa_data, 0, sizeof(wpa_data));
3839 ie = wpa_bss_get_vendor_ie(res, WPA_IE_VENDOR_TYPE);
3840 if (ie && wpa_parse_wpa_ie(ie, 2 + ie[1], &wpa_data) < 0) {
3841 dbus_set_error_const(error, DBUS_ERROR_FAILED,
3842 "failed to parse WPA IE");
3846 return wpas_dbus_get_bss_security_prop(property_desc, iter, &wpa_data, error);
3851 * wpas_dbus_getter_bss_rsn - Return the RSN options of a BSS
3852 * @iter: Pointer to incoming dbus message iter
3853 * @error: Location to store error on failure
3854 * @user_data: Function specific data
3855 * Returns: TRUE on success, FALSE on failure
3857 * Getter for "RSN" property.
3859 dbus_bool_t wpas_dbus_getter_bss_rsn(
3860 const struct wpa_dbus_property_desc *property_desc,
3861 DBusMessageIter *iter, DBusError *error, void *user_data)
3863 struct bss_handler_args *args = user_data;
3864 struct wpa_bss *res;
3865 struct wpa_ie_data wpa_data;
3868 res = get_bss_helper(args, error, __func__);
3872 os_memset(&wpa_data, 0, sizeof(wpa_data));
3873 ie = wpa_bss_get_ie(res, WLAN_EID_RSN);
3874 if (ie && wpa_parse_wpa_ie(ie, 2 + ie[1], &wpa_data) < 0) {
3875 dbus_set_error_const(error, DBUS_ERROR_FAILED,
3876 "failed to parse RSN IE");
3880 return wpas_dbus_get_bss_security_prop(property_desc, iter, &wpa_data, error);
3885 * wpas_dbus_getter_bss_wps - Return the WPS options of a BSS
3886 * @iter: Pointer to incoming dbus message iter
3887 * @error: Location to store error on failure
3888 * @user_data: Function specific data
3889 * Returns: TRUE on success, FALSE on failure
3891 * Getter for "WPS" property.
3893 dbus_bool_t wpas_dbus_getter_bss_wps(
3894 const struct wpa_dbus_property_desc *property_desc,
3895 DBusMessageIter *iter, DBusError *error, void *user_data)
3897 struct bss_handler_args *args = user_data;
3898 struct wpa_bss *res;
3900 struct wpabuf *wps_ie;
3901 #endif /* CONFIG_WPS */
3902 DBusMessageIter iter_dict, variant_iter;
3903 int wps_support = 0;
3904 const char *type = "";
3906 res = get_bss_helper(args, error, __func__);
3910 if (!dbus_message_iter_open_container(iter, DBUS_TYPE_VARIANT,
3911 "a{sv}", &variant_iter) ||
3912 !wpa_dbus_dict_open_write(&variant_iter, &iter_dict))
3916 wps_ie = wpa_bss_get_vendor_ie_multi(res, WPS_IE_VENDOR_TYPE);
3919 if (wps_is_selected_pbc_registrar(wps_ie))
3921 else if (wps_is_selected_pin_registrar(wps_ie))
3924 wpabuf_free(wps_ie);
3926 #endif /* CONFIG_WPS */
3928 if ((wps_support && !wpa_dbus_dict_append_string(&iter_dict, "Type", type)) ||
3929 !wpa_dbus_dict_close_write(&variant_iter, &iter_dict) ||
3930 !dbus_message_iter_close_container(iter, &variant_iter))
3936 dbus_set_error_const(error, DBUS_ERROR_NO_MEMORY, "no memory");
3942 * wpas_dbus_getter_bss_ies - Return all IEs of a BSS
3943 * @iter: Pointer to incoming dbus message iter
3944 * @error: Location to store error on failure
3945 * @user_data: Function specific data
3946 * Returns: TRUE on success, FALSE on failure
3948 * Getter for "IEs" property.
3950 dbus_bool_t wpas_dbus_getter_bss_ies(
3951 const struct wpa_dbus_property_desc *property_desc,
3952 DBusMessageIter *iter, DBusError *error, void *user_data)
3954 struct bss_handler_args *args = user_data;
3955 struct wpa_bss *res;
3957 res = get_bss_helper(args, error, __func__);
3961 return wpas_dbus_simple_array_property_getter(iter, DBUS_TYPE_BYTE,
3962 res + 1, res->ie_len,
3968 * wpas_dbus_getter_bss_age - Return time in seconds since BSS was last seen
3969 * @iter: Pointer to incoming dbus message iter
3970 * @error: Location to store error on failure
3971 * @user_data: Function specific data
3972 * Returns: TRUE on success, FALSE on failure
3974 * Getter for BSS age
3976 dbus_bool_t wpas_dbus_getter_bss_age(
3977 const struct wpa_dbus_property_desc *property_desc,
3978 DBusMessageIter *iter, DBusError *error, void *user_data)
3980 struct bss_handler_args *args = user_data;
3981 struct wpa_bss *res;
3982 struct os_reltime now, diff = { 0, 0 };
3985 res = get_bss_helper(args, error, __func__);
3989 os_get_reltime(&now);
3990 os_reltime_sub(&now, &res->last_update, &diff);
3991 age = diff.sec > 0 ? diff.sec : 0;
3992 return wpas_dbus_simple_property_getter(iter, DBUS_TYPE_UINT32, &age,
3998 * wpas_dbus_getter_enabled - Check whether network is enabled or disabled
3999 * @iter: Pointer to incoming dbus message iter
4000 * @error: Location to store error on failure
4001 * @user_data: Function specific data
4002 * Returns: TRUE on success, FALSE on failure
4004 * Getter for "enabled" property of a configured network.
4006 dbus_bool_t wpas_dbus_getter_enabled(
4007 const struct wpa_dbus_property_desc *property_desc,
4008 DBusMessageIter *iter, DBusError *error, void *user_data)
4010 struct network_handler_args *net = user_data;
4011 dbus_bool_t enabled = net->ssid->disabled ? FALSE : TRUE;
4013 return wpas_dbus_simple_property_getter(iter, DBUS_TYPE_BOOLEAN,
4019 * wpas_dbus_setter_enabled - Mark a configured network as enabled or disabled
4020 * @iter: Pointer to incoming dbus message iter
4021 * @error: Location to store error on failure
4022 * @user_data: Function specific data
4023 * Returns: TRUE on success, FALSE on failure
4025 * Setter for "Enabled" property of a configured network.
4027 dbus_bool_t wpas_dbus_setter_enabled(
4028 const struct wpa_dbus_property_desc *property_desc,
4029 DBusMessageIter *iter, DBusError *error, void *user_data)
4031 struct network_handler_args *net = user_data;
4032 struct wpa_supplicant *wpa_s;
4033 struct wpa_ssid *ssid;
4036 if (!wpas_dbus_simple_property_setter(iter, error, DBUS_TYPE_BOOLEAN,
4044 wpa_supplicant_enable_network(wpa_s, ssid);
4046 wpa_supplicant_disable_network(wpa_s, ssid);
4053 * wpas_dbus_getter_network_properties - Get options for a configured network
4054 * @iter: Pointer to incoming dbus message iter
4055 * @error: Location to store error on failure
4056 * @user_data: Function specific data
4057 * Returns: TRUE on success, FALSE on failure
4059 * Getter for "Properties" property of a configured network.
4061 dbus_bool_t wpas_dbus_getter_network_properties(
4062 const struct wpa_dbus_property_desc *property_desc,
4063 DBusMessageIter *iter, DBusError *error, void *user_data)
4065 struct network_handler_args *net = user_data;
4066 DBusMessageIter variant_iter, dict_iter;
4068 char **props = wpa_config_get_all(net->ssid, 1);
4069 dbus_bool_t success = FALSE;
4072 dbus_set_error_const(error, DBUS_ERROR_NO_MEMORY, "no memory");
4076 if (!dbus_message_iter_open_container(iter, DBUS_TYPE_VARIANT, "a{sv}",
4078 !wpa_dbus_dict_open_write(&variant_iter, &dict_iter)) {
4079 dbus_set_error_const(error, DBUS_ERROR_NO_MEMORY, "no memory");
4085 if (!wpa_dbus_dict_append_string(&dict_iter, *iterator,
4087 dbus_set_error_const(error, DBUS_ERROR_NO_MEMORY,
4095 if (!wpa_dbus_dict_close_write(&variant_iter, &dict_iter) ||
4096 !dbus_message_iter_close_container(iter, &variant_iter)) {
4097 dbus_set_error_const(error, DBUS_ERROR_NO_MEMORY, "no memory");
4115 * wpas_dbus_setter_network_properties - Set options for a configured network
4116 * @iter: Pointer to incoming dbus message iter
4117 * @error: Location to store error on failure
4118 * @user_data: Function specific data
4119 * Returns: TRUE on success, FALSE on failure
4121 * Setter for "Properties" property of a configured network.
4123 dbus_bool_t wpas_dbus_setter_network_properties(
4124 const struct wpa_dbus_property_desc *property_desc,
4125 DBusMessageIter *iter, DBusError *error, void *user_data)
4127 struct network_handler_args *net = user_data;
4128 struct wpa_ssid *ssid = net->ssid;
4129 DBusMessageIter variant_iter;
4131 dbus_message_iter_recurse(iter, &variant_iter);
4132 return set_network_properties(net->wpa_s, ssid, &variant_iter, error);
4138 DBusMessage * wpas_dbus_handler_subscribe_preq(
4139 DBusMessage *message, struct wpa_supplicant *wpa_s)
4141 struct wpas_dbus_priv *priv = wpa_s->global->dbus;
4144 if (wpa_s->preq_notify_peer != NULL) {
4145 if (os_strcmp(dbus_message_get_sender(message),
4146 wpa_s->preq_notify_peer) == 0)
4149 return dbus_message_new_error(message,
4150 WPAS_DBUS_ERROR_SUBSCRIPTION_IN_USE,
4151 "Another application is already subscribed");
4154 name = os_strdup(dbus_message_get_sender(message));
4156 return wpas_dbus_error_no_memory(message);
4158 wpa_s->preq_notify_peer = name;
4160 /* Subscribe to clean up if application closes socket */
4161 wpas_dbus_subscribe_noc(priv);
4164 * Double-check it's still alive to make sure that we didn't
4165 * miss the NameOwnerChanged signal, e.g. while strdup'ing.
4167 if (!dbus_bus_name_has_owner(priv->con, name, NULL)) {
4169 * Application no longer exists, clean up.
4170 * The return value is irrelevant now.
4172 * Need to check if the NameOwnerChanged handling
4173 * already cleaned up because we have processed
4174 * DBus messages while checking if the name still
4177 if (!wpa_s->preq_notify_peer)
4179 os_free(wpa_s->preq_notify_peer);
4180 wpa_s->preq_notify_peer = NULL;
4181 wpas_dbus_unsubscribe_noc(priv);
4188 DBusMessage * wpas_dbus_handler_unsubscribe_preq(
4189 DBusMessage *message, struct wpa_supplicant *wpa_s)
4191 struct wpas_dbus_priv *priv = wpa_s->global->dbus;
4193 if (!wpa_s->preq_notify_peer)
4194 return dbus_message_new_error(message,
4195 WPAS_DBUS_ERROR_NO_SUBSCRIPTION,
4198 if (os_strcmp(wpa_s->preq_notify_peer,
4199 dbus_message_get_sender(message)))
4200 return dbus_message_new_error(message,
4201 WPAS_DBUS_ERROR_SUBSCRIPTION_EPERM,
4202 "Can't unsubscribe others");
4204 os_free(wpa_s->preq_notify_peer);
4205 wpa_s->preq_notify_peer = NULL;
4206 wpas_dbus_unsubscribe_noc(priv);
4211 void wpas_dbus_signal_preq(struct wpa_supplicant *wpa_s,
4212 const u8 *addr, const u8 *dst, const u8 *bssid,
4213 const u8 *ie, size_t ie_len, u32 ssi_signal)
4216 DBusMessageIter iter, dict_iter;
4217 struct wpas_dbus_priv *priv = wpa_s->global->dbus;
4219 /* Do nothing if the control interface is not turned on */
4220 if (priv == NULL || !wpa_s->dbus_new_path)
4223 if (wpa_s->preq_notify_peer == NULL)
4226 msg = dbus_message_new_signal(wpa_s->dbus_new_path,
4227 WPAS_DBUS_NEW_IFACE_INTERFACE,
4232 dbus_message_set_destination(msg, wpa_s->preq_notify_peer);
4234 dbus_message_iter_init_append(msg, &iter);
4236 if (!wpa_dbus_dict_open_write(&iter, &dict_iter) ||
4237 (addr && !wpa_dbus_dict_append_byte_array(&dict_iter, "addr",
4238 (const char *) addr,
4240 (dst && !wpa_dbus_dict_append_byte_array(&dict_iter, "dst",
4243 (bssid && !wpa_dbus_dict_append_byte_array(&dict_iter, "bssid",
4244 (const char *) bssid,
4246 (ie && ie_len && !wpa_dbus_dict_append_byte_array(&dict_iter, "ies",
4249 (ssi_signal && !wpa_dbus_dict_append_int32(&dict_iter, "signal",
4251 !wpa_dbus_dict_close_write(&iter, &dict_iter))
4254 dbus_connection_send(priv->con, msg, NULL);
4257 wpa_printf(MSG_ERROR, "dbus: Failed to construct signal");
4259 dbus_message_unref(msg);
4262 #endif /* CONFIG_AP */