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 "ap/hostapd.h"
19 #include "ap/sta_info.h"
20 #include "ap/ap_drv_ops.h"
21 #include "../config.h"
22 #include "../wpa_supplicant_i.h"
23 #include "../driver_i.h"
24 #include "../notify.h"
27 #include "../autoscan.h"
29 #include "dbus_new_helpers.h"
31 #include "dbus_new_handlers.h"
32 #include "dbus_dict_helpers.h"
33 #include "dbus_common_i.h"
34 #include "drivers/driver.h"
36 #include "ap/hostapd.h"
37 #include "ap/sta_info.h"
38 #endif /* CONFIG_MESH */
40 static const char * const debug_strings
[] = {
41 "excessive", "msgdump", "debug", "info", "warning", "error", NULL
46 * wpas_dbus_error_unknown_error - Return a new UnknownError error message
47 * @message: Pointer to incoming dbus message this error refers to
48 * @arg: Optional string appended to error message
49 * Returns: a dbus error message
51 * Convenience function to create and return an UnknownError
53 DBusMessage
* wpas_dbus_error_unknown_error(DBusMessage
*message
,
56 return dbus_message_new_error(message
, WPAS_DBUS_ERROR_UNKNOWN_ERROR
,
62 * wpas_dbus_error_iface_unknown - Return a new invalid interface error message
63 * @message: Pointer to incoming dbus message this error refers to
64 * Returns: A dbus error message
66 * Convenience function to create and return an invalid interface error
68 static DBusMessage
* wpas_dbus_error_iface_unknown(DBusMessage
*message
)
70 return dbus_message_new_error(
71 message
, WPAS_DBUS_ERROR_IFACE_UNKNOWN
,
72 "wpa_supplicant knows nothing about this interface.");
77 * wpas_dbus_error_network_unknown - Return a new NetworkUnknown error message
78 * @message: Pointer to incoming dbus message this error refers to
79 * Returns: a dbus error message
81 * Convenience function to create and return an invalid network error
83 static DBusMessage
* wpas_dbus_error_network_unknown(DBusMessage
*message
)
85 return dbus_message_new_error(
86 message
, WPAS_DBUS_ERROR_NETWORK_UNKNOWN
,
87 "There is no such a network in this interface.");
92 * wpas_dbus_error_invalid_args - Return a new InvalidArgs error message
93 * @message: Pointer to incoming dbus message this error refers to
94 * Returns: a dbus error message
96 * Convenience function to create and return an invalid options error
98 DBusMessage
* wpas_dbus_error_invalid_args(DBusMessage
*message
,
103 reply
= dbus_message_new_error(
104 message
, WPAS_DBUS_ERROR_INVALID_ARGS
,
105 "Did not receive correct message arguments.");
107 dbus_message_append_args(reply
, DBUS_TYPE_STRING
, &arg
,
115 * wpas_dbus_error_scan_error - Return a new ScanError error message
116 * @message: Pointer to incoming dbus message this error refers to
117 * @error: Optional string to be used as the error message
118 * Returns: a dbus error message
120 * Convenience function to create and return a scan error
122 static DBusMessage
* wpas_dbus_error_scan_error(DBusMessage
*message
,
125 return dbus_message_new_error(message
,
126 WPAS_DBUS_ERROR_IFACE_SCAN_ERROR
,
131 DBusMessage
* wpas_dbus_error_no_memory(DBusMessage
*message
)
133 wpa_printf(MSG_DEBUG
, "dbus: Failed to allocate memory");
134 return dbus_message_new_error(message
, DBUS_ERROR_NO_MEMORY
, NULL
);
138 static const char * const dont_quote
[] = {
139 "key_mgmt", "proto", "pairwise", "auth_alg", "group", "eap",
140 "opensc_engine_path", "pkcs11_engine_path", "pkcs11_module_path",
141 "bssid", "scan_freq", "freq_list", NULL
144 static dbus_bool_t
should_quote_opt(const char *key
)
148 while (dont_quote
[i
] != NULL
) {
149 if (os_strcmp(key
, dont_quote
[i
]) == 0)
157 * get_iface_by_dbus_path - Get a new network interface
158 * @global: Pointer to global data from wpa_supplicant_init()
159 * @path: Pointer to a dbus object path representing an interface
160 * Returns: Pointer to the interface or %NULL if not found
162 static struct wpa_supplicant
* get_iface_by_dbus_path(
163 struct wpa_global
*global
, const char *path
)
165 struct wpa_supplicant
*wpa_s
;
167 for (wpa_s
= global
->ifaces
; wpa_s
; wpa_s
= wpa_s
->next
) {
168 if (wpa_s
->dbus_new_path
&&
169 os_strcmp(wpa_s
->dbus_new_path
, path
) == 0)
177 * set_network_properties - Set properties of a configured network
178 * @wpa_s: wpa_supplicant structure for a network interface
179 * @ssid: wpa_ssid structure for a configured network
180 * @iter: DBus message iterator containing dictionary of network
182 * @error: On failure, an error describing the failure
183 * Returns: TRUE if the request succeeds, FALSE if it failed
185 * Sets network configuration with parameters given id DBus dictionary
187 dbus_bool_t
set_network_properties(struct wpa_supplicant
*wpa_s
,
188 struct wpa_ssid
*ssid
,
189 DBusMessageIter
*iter
,
192 struct wpa_dbus_dict_entry entry
= { .type
= DBUS_TYPE_STRING
};
193 DBusMessageIter iter_dict
;
196 if (!wpa_dbus_dict_open_read(iter
, &iter_dict
, error
))
199 while (wpa_dbus_dict_has_dict_entry(&iter_dict
)) {
203 if (!wpa_dbus_dict_get_entry(&iter_dict
, &entry
))
207 if (entry
.type
== DBUS_TYPE_ARRAY
&&
208 entry
.array_type
== DBUS_TYPE_BYTE
) {
209 if (entry
.array_len
<= 0)
212 size
= entry
.array_len
* 2 + 1;
213 value
= os_zalloc(size
);
217 ret
= wpa_snprintf_hex(value
, size
,
218 (u8
*) entry
.bytearray_value
,
222 } else if (entry
.type
== DBUS_TYPE_STRING
) {
223 if (should_quote_opt(entry
.key
)) {
224 size
= os_strlen(entry
.str_value
);
229 value
= os_zalloc(size
);
233 ret
= os_snprintf(value
, size
, "\"%s\"",
235 if (os_snprintf_error(size
, ret
))
238 value
= os_strdup(entry
.str_value
);
242 } else if (entry
.type
== DBUS_TYPE_UINT32
) {
243 value
= os_zalloc(size
);
247 ret
= os_snprintf(value
, size
, "%u",
249 if (os_snprintf_error(size
, ret
))
251 } else if (entry
.type
== DBUS_TYPE_INT32
) {
252 value
= os_zalloc(size
);
256 ret
= os_snprintf(value
, size
, "%d",
258 if (os_snprintf_error(size
, ret
))
263 if (wpa_config_set(ssid
, entry
.key
, value
, 0) < 0)
266 if (os_strcmp(entry
.key
, "bssid") != 0 &&
267 os_strcmp(entry
.key
, "priority") != 0)
268 wpa_sm_pmksa_cache_flush(wpa_s
->wpa
, ssid
);
270 if (wpa_s
->current_ssid
== ssid
||
271 wpa_s
->current_ssid
== NULL
) {
273 * Invalidate the EAP session cache if anything in the
274 * current or previously used configuration changes.
276 eapol_sm_invalidate_cached_session(wpa_s
->eapol
);
279 if ((os_strcmp(entry
.key
, "psk") == 0 &&
280 value
[0] == '"' && ssid
->ssid_len
) ||
281 (os_strcmp(entry
.key
, "ssid") == 0 && ssid
->passphrase
))
282 wpa_config_update_psk(ssid
);
283 else if (os_strcmp(entry
.key
, "priority") == 0)
284 wpa_config_update_prio_list(wpa_s
->conf
);
288 wpa_dbus_dict_entry_clear(&entry
);
295 wpa_dbus_dict_entry_clear(&entry
);
296 dbus_set_error_const(error
, DBUS_ERROR_INVALID_ARGS
,
297 "invalid message format");
303 * wpas_dbus_simple_property_getter - Get basic type property
304 * @iter: Message iter to use when appending arguments
305 * @type: DBus type of property (must be basic type)
306 * @val: pointer to place holding property value
307 * @error: On failure an error describing the failure
308 * Returns: TRUE if the request was successful, FALSE if it failed
310 * Generic getter for basic type properties. Type is required to be basic.
312 dbus_bool_t
wpas_dbus_simple_property_getter(DBusMessageIter
*iter
,
317 DBusMessageIter variant_iter
;
319 if (!dbus_type_is_basic(type
)) {
320 dbus_set_error(error
, DBUS_ERROR_FAILED
,
321 "%s: given type is not basic", __func__
);
325 if (!dbus_message_iter_open_container(iter
, DBUS_TYPE_VARIANT
,
326 wpa_dbus_type_as_string(type
),
328 !dbus_message_iter_append_basic(&variant_iter
, type
, val
) ||
329 !dbus_message_iter_close_container(iter
, &variant_iter
)) {
330 dbus_set_error(error
, DBUS_ERROR_FAILED
,
331 "%s: error constructing reply", __func__
);
340 * wpas_dbus_simple_property_setter - Set basic type property
341 * @message: Pointer to incoming dbus message
342 * @type: DBus type of property (must be basic type)
343 * @val: pointer to place where value being set will be stored
344 * Returns: TRUE if the request was successful, FALSE if it failed
346 * Generic setter for basic type properties. Type is required to be basic.
348 dbus_bool_t
wpas_dbus_simple_property_setter(DBusMessageIter
*iter
,
350 const int type
, void *val
)
352 DBusMessageIter variant_iter
;
354 if (!dbus_type_is_basic(type
)) {
355 dbus_set_error(error
, DBUS_ERROR_FAILED
,
356 "%s: given type is not basic", __func__
);
360 /* Look at the new value */
361 dbus_message_iter_recurse(iter
, &variant_iter
);
362 if (dbus_message_iter_get_arg_type(&variant_iter
) != type
) {
363 dbus_set_error_const(error
, DBUS_ERROR_FAILED
,
364 "wrong property type");
367 dbus_message_iter_get_basic(&variant_iter
, val
);
374 * wpas_dbus_simple_array_property_getter - Get array type property
375 * @iter: Pointer to incoming dbus message iterator
376 * @type: DBus type of property array elements (must be basic type)
377 * @array: pointer to array of elements to put into response message
378 * @array_len: length of above array
379 * @error: a pointer to an error to fill on failure
380 * Returns: TRUE if the request succeeded, FALSE if it failed
382 * Generic getter for array type properties. Array elements type is
383 * required to be basic.
385 dbus_bool_t
wpas_dbus_simple_array_property_getter(DBusMessageIter
*iter
,
391 DBusMessageIter variant_iter
, array_iter
;
392 char type_str
[] = "a?"; /* ? will be replaced with subtype letter; */
393 const char *sub_type_str
;
394 size_t element_size
, i
;
396 if (!dbus_type_is_basic(type
)) {
397 dbus_set_error(error
, DBUS_ERROR_FAILED
,
398 "%s: given type is not basic", __func__
);
402 sub_type_str
= wpa_dbus_type_as_string(type
);
403 type_str
[1] = sub_type_str
[0];
405 if (!dbus_message_iter_open_container(iter
, DBUS_TYPE_VARIANT
,
406 type_str
, &variant_iter
) ||
407 !dbus_message_iter_open_container(&variant_iter
, DBUS_TYPE_ARRAY
,
408 sub_type_str
, &array_iter
)) {
409 dbus_set_error(error
, DBUS_ERROR_FAILED
,
410 "%s: failed to construct message", __func__
);
416 case DBUS_TYPE_BOOLEAN
:
419 case DBUS_TYPE_INT16
:
420 case DBUS_TYPE_UINT16
:
421 element_size
= sizeof(uint16_t);
423 case DBUS_TYPE_INT32
:
424 case DBUS_TYPE_UINT32
:
425 element_size
= sizeof(uint32_t);
427 case DBUS_TYPE_INT64
:
428 case DBUS_TYPE_UINT64
:
429 element_size
= sizeof(uint64_t);
431 case DBUS_TYPE_DOUBLE
:
432 element_size
= sizeof(double);
434 case DBUS_TYPE_STRING
:
435 case DBUS_TYPE_OBJECT_PATH
:
436 element_size
= sizeof(char *);
439 dbus_set_error(error
, DBUS_ERROR_FAILED
,
440 "%s: unknown element type %d", __func__
, type
);
444 for (i
= 0; i
< array_len
; i
++) {
445 if (!dbus_message_iter_append_basic(&array_iter
, type
,
446 (const char *) array
+
448 dbus_set_error(error
, DBUS_ERROR_FAILED
,
449 "%s: failed to construct message 2.5",
455 if (!dbus_message_iter_close_container(&variant_iter
, &array_iter
) ||
456 !dbus_message_iter_close_container(iter
, &variant_iter
)) {
457 dbus_set_error(error
, DBUS_ERROR_FAILED
,
458 "%s: failed to construct message 3", __func__
);
467 * wpas_dbus_simple_array_array_property_getter - Get array array type property
468 * @iter: Pointer to incoming dbus message iterator
469 * @type: DBus type of property array elements (must be basic type)
470 * @array: pointer to array of elements to put into response message
471 * @array_len: length of above array
472 * @error: a pointer to an error to fill on failure
473 * Returns: TRUE if the request succeeded, FALSE if it failed
475 * Generic getter for array type properties. Array elements type is
476 * required to be basic.
478 dbus_bool_t
wpas_dbus_simple_array_array_property_getter(DBusMessageIter
*iter
,
480 struct wpabuf
**array
,
484 DBusMessageIter variant_iter
, array_iter
;
485 char type_str
[] = "aa?";
486 char inner_type_str
[] = "a?";
487 const char *sub_type_str
;
490 if (!dbus_type_is_basic(type
)) {
491 dbus_set_error(error
, DBUS_ERROR_FAILED
,
492 "%s: given type is not basic", __func__
);
496 sub_type_str
= wpa_dbus_type_as_string(type
);
497 type_str
[2] = sub_type_str
[0];
498 inner_type_str
[1] = sub_type_str
[0];
500 if (!dbus_message_iter_open_container(iter
, DBUS_TYPE_VARIANT
,
501 type_str
, &variant_iter
) ||
502 !dbus_message_iter_open_container(&variant_iter
, DBUS_TYPE_ARRAY
,
503 inner_type_str
, &array_iter
)) {
504 dbus_set_error(error
, DBUS_ERROR_FAILED
,
505 "%s: failed to construct message", __func__
);
509 for (i
= 0; i
< array_len
&& array
[i
]; i
++) {
510 wpa_dbus_dict_bin_array_add_element(&array_iter
,
511 wpabuf_head(array
[i
]),
512 wpabuf_len(array
[i
]));
516 if (!dbus_message_iter_close_container(&variant_iter
, &array_iter
) ||
517 !dbus_message_iter_close_container(iter
, &variant_iter
)) {
518 dbus_set_error(error
, DBUS_ERROR_FAILED
,
519 "%s: failed to close message", __func__
);
528 * wpas_dbus_string_property_getter - Get string type property
529 * @iter: Message iter to use when appending arguments
530 * @val: Pointer to place holding property value, can be %NULL
531 * @error: On failure an error describing the failure
532 * Returns: TRUE if the request was successful, FALSE if it failed
534 * Generic getter for string type properties. %NULL is converted to an empty
537 dbus_bool_t
wpas_dbus_string_property_getter(DBusMessageIter
*iter
,
543 return wpas_dbus_simple_property_getter(iter
, DBUS_TYPE_STRING
,
549 * wpas_dbus_handler_create_interface - Request registration of a network iface
550 * @message: Pointer to incoming dbus message
551 * @global: %wpa_supplicant global data structure
552 * Returns: The object path of the new interface object,
553 * or a dbus error message with more information
555 * Handler function for "CreateInterface" method call. Handles requests
556 * by dbus clients to register a network interface that wpa_supplicant
559 DBusMessage
* wpas_dbus_handler_create_interface(DBusMessage
*message
,
560 struct wpa_global
*global
)
562 DBusMessageIter iter_dict
;
563 DBusMessage
*reply
= NULL
;
564 DBusMessageIter iter
;
565 struct wpa_dbus_dict_entry entry
;
568 char *confname
= NULL
;
569 char *bridge_ifname
= NULL
;
571 dbus_message_iter_init(message
, &iter
);
573 if (!wpa_dbus_dict_open_read(&iter
, &iter_dict
, NULL
))
575 while (wpa_dbus_dict_has_dict_entry(&iter_dict
)) {
576 if (!wpa_dbus_dict_get_entry(&iter_dict
, &entry
))
578 if (os_strcmp(entry
.key
, "Driver") == 0 &&
579 entry
.type
== DBUS_TYPE_STRING
) {
581 driver
= os_strdup(entry
.str_value
);
582 wpa_dbus_dict_entry_clear(&entry
);
585 } else if (os_strcmp(entry
.key
, "Ifname") == 0 &&
586 entry
.type
== DBUS_TYPE_STRING
) {
588 ifname
= os_strdup(entry
.str_value
);
589 wpa_dbus_dict_entry_clear(&entry
);
592 } else if (os_strcmp(entry
.key
, "ConfigFile") == 0 &&
593 entry
.type
== DBUS_TYPE_STRING
) {
595 confname
= os_strdup(entry
.str_value
);
596 wpa_dbus_dict_entry_clear(&entry
);
597 if (confname
== NULL
)
599 } else if (os_strcmp(entry
.key
, "BridgeIfname") == 0 &&
600 entry
.type
== DBUS_TYPE_STRING
) {
601 os_free(bridge_ifname
);
602 bridge_ifname
= os_strdup(entry
.str_value
);
603 wpa_dbus_dict_entry_clear(&entry
);
604 if (bridge_ifname
== NULL
)
607 wpa_dbus_dict_entry_clear(&entry
);
613 goto error
; /* Required Ifname argument missing */
616 * Try to get the wpa_supplicant record for this iface, return
617 * an error if we already control it.
619 if (wpa_supplicant_get_iface(global
, ifname
) != NULL
) {
620 reply
= dbus_message_new_error(
621 message
, WPAS_DBUS_ERROR_IFACE_EXISTS
,
622 "wpa_supplicant already controls this interface.");
624 struct wpa_supplicant
*wpa_s
;
625 struct wpa_interface iface
;
627 os_memset(&iface
, 0, sizeof(iface
));
628 iface
.driver
= driver
;
629 iface
.ifname
= ifname
;
630 iface
.confname
= confname
;
631 iface
.bridge_ifname
= bridge_ifname
;
632 /* Otherwise, have wpa_supplicant attach to it. */
633 wpa_s
= wpa_supplicant_add_iface(global
, &iface
, NULL
);
634 if (wpa_s
&& wpa_s
->dbus_new_path
) {
635 const char *path
= wpa_s
->dbus_new_path
;
637 reply
= dbus_message_new_method_return(message
);
638 dbus_message_append_args(reply
, DBUS_TYPE_OBJECT_PATH
,
639 &path
, DBUS_TYPE_INVALID
);
641 reply
= wpas_dbus_error_unknown_error(
643 "wpa_supplicant couldn't grab this interface.");
651 os_free(bridge_ifname
);
655 reply
= wpas_dbus_error_invalid_args(message
, NULL
);
658 reply
= wpas_dbus_error_no_memory(message
);
664 * wpas_dbus_handler_remove_interface - Request deregistration of an interface
665 * @message: Pointer to incoming dbus message
666 * @global: wpa_supplicant global data structure
667 * Returns: a dbus message containing a UINT32 indicating success (1) or
668 * failure (0), or returns a dbus error message with more information
670 * Handler function for "removeInterface" method call. Handles requests
671 * by dbus clients to deregister a network interface that wpa_supplicant
674 DBusMessage
* wpas_dbus_handler_remove_interface(DBusMessage
*message
,
675 struct wpa_global
*global
)
677 struct wpa_supplicant
*wpa_s
;
679 DBusMessage
*reply
= NULL
;
681 dbus_message_get_args(message
, NULL
, DBUS_TYPE_OBJECT_PATH
, &path
,
684 wpa_s
= get_iface_by_dbus_path(global
, path
);
686 reply
= wpas_dbus_error_iface_unknown(message
);
687 else if (wpa_supplicant_remove_iface(global
, wpa_s
, 0)) {
688 reply
= wpas_dbus_error_unknown_error(
690 "wpa_supplicant couldn't remove this interface.");
698 * wpas_dbus_handler_get_interface - Get the object path for an interface name
699 * @message: Pointer to incoming dbus message
700 * @global: %wpa_supplicant global data structure
701 * Returns: The object path of the interface object,
702 * or a dbus error message with more information
704 * Handler function for "getInterface" method call.
706 DBusMessage
* wpas_dbus_handler_get_interface(DBusMessage
*message
,
707 struct wpa_global
*global
)
709 DBusMessage
*reply
= NULL
;
712 struct wpa_supplicant
*wpa_s
;
714 dbus_message_get_args(message
, NULL
, DBUS_TYPE_STRING
, &ifname
,
717 wpa_s
= wpa_supplicant_get_iface(global
, ifname
);
718 if (wpa_s
== NULL
|| wpa_s
->dbus_new_path
== NULL
)
719 return wpas_dbus_error_iface_unknown(message
);
721 path
= wpa_s
->dbus_new_path
;
722 reply
= dbus_message_new_method_return(message
);
724 return wpas_dbus_error_no_memory(message
);
725 if (!dbus_message_append_args(reply
, DBUS_TYPE_OBJECT_PATH
, &path
,
726 DBUS_TYPE_INVALID
)) {
727 dbus_message_unref(reply
);
728 return wpas_dbus_error_no_memory(message
);
736 * wpas_dbus_getter_debug_level - Get debug level
737 * @iter: Pointer to incoming dbus message iter
738 * @error: Location to store error on failure
739 * @user_data: Function specific data
740 * Returns: TRUE on success, FALSE on failure
742 * Getter for "DebugLevel" property.
744 dbus_bool_t
wpas_dbus_getter_debug_level(
745 const struct wpa_dbus_property_desc
*property_desc
,
746 DBusMessageIter
*iter
, DBusError
*error
, void *user_data
)
749 int idx
= wpa_debug_level
;
755 str
= debug_strings
[idx
];
756 return wpas_dbus_simple_property_getter(iter
, DBUS_TYPE_STRING
,
762 * wpas_dbus_getter_debug_timestamp - Get debug timestamp
763 * @iter: Pointer to incoming dbus message iter
764 * @error: Location to store error on failure
765 * @user_data: Function specific data
766 * Returns: TRUE on success, FALSE on failure
768 * Getter for "DebugTimestamp" property.
770 dbus_bool_t
wpas_dbus_getter_debug_timestamp(
771 const struct wpa_dbus_property_desc
*property_desc
,
772 DBusMessageIter
*iter
, DBusError
*error
, void *user_data
)
774 return wpas_dbus_simple_property_getter(iter
, DBUS_TYPE_BOOLEAN
,
775 &wpa_debug_timestamp
, error
);
781 * wpas_dbus_getter_debug_show_keys - Get debug show keys
782 * @iter: Pointer to incoming dbus message iter
783 * @error: Location to store error on failure
784 * @user_data: Function specific data
785 * Returns: TRUE on success, FALSE on failure
787 * Getter for "DebugShowKeys" property.
789 dbus_bool_t
wpas_dbus_getter_debug_show_keys(
790 const struct wpa_dbus_property_desc
*property_desc
,
791 DBusMessageIter
*iter
, DBusError
*error
, void *user_data
)
793 return wpas_dbus_simple_property_getter(iter
, DBUS_TYPE_BOOLEAN
,
794 &wpa_debug_show_keys
, error
);
799 * wpas_dbus_setter_debug_level - Set debug level
800 * @iter: Pointer to incoming dbus message iter
801 * @error: Location to store error on failure
802 * @user_data: Function specific data
803 * Returns: TRUE on success, FALSE on failure
805 * Setter for "DebugLevel" property.
807 dbus_bool_t
wpas_dbus_setter_debug_level(
808 const struct wpa_dbus_property_desc
*property_desc
,
809 DBusMessageIter
*iter
, DBusError
*error
, void *user_data
)
811 struct wpa_global
*global
= user_data
;
812 const char *str
= NULL
;
815 if (!wpas_dbus_simple_property_setter(iter
, error
, DBUS_TYPE_STRING
,
819 for (i
= 0; debug_strings
[i
]; i
++)
820 if (os_strcmp(debug_strings
[i
], str
) == 0) {
826 wpa_supplicant_set_debug_params(global
, val
, wpa_debug_timestamp
,
827 wpa_debug_show_keys
)) {
828 dbus_set_error_const(error
, DBUS_ERROR_FAILED
,
829 "wrong debug level value");
838 * wpas_dbus_setter_debug_timestamp - Set debug timestamp
839 * @iter: Pointer to incoming dbus message iter
840 * @error: Location to store error on failure
841 * @user_data: Function specific data
842 * Returns: TRUE on success, FALSE on failure
844 * Setter for "DebugTimestamp" property.
846 dbus_bool_t
wpas_dbus_setter_debug_timestamp(
847 const struct wpa_dbus_property_desc
*property_desc
,
848 DBusMessageIter
*iter
, DBusError
*error
, void *user_data
)
850 struct wpa_global
*global
= user_data
;
853 if (!wpas_dbus_simple_property_setter(iter
, error
, DBUS_TYPE_BOOLEAN
,
857 wpa_supplicant_set_debug_params(global
, wpa_debug_level
, val
? 1 : 0,
858 wpa_debug_show_keys
);
864 * wpas_dbus_setter_debug_show_keys - Set debug show keys
865 * @iter: Pointer to incoming dbus message iter
866 * @error: Location to store error on failure
867 * @user_data: Function specific data
868 * Returns: TRUE on success, FALSE on failure
870 * Setter for "DebugShowKeys" property.
872 dbus_bool_t
wpas_dbus_setter_debug_show_keys(
873 const struct wpa_dbus_property_desc
*property_desc
,
874 DBusMessageIter
*iter
, DBusError
*error
, void *user_data
)
876 struct wpa_global
*global
= user_data
;
879 if (!wpas_dbus_simple_property_setter(iter
, error
, DBUS_TYPE_BOOLEAN
,
883 wpa_supplicant_set_debug_params(global
, wpa_debug_level
,
891 * wpas_dbus_getter_interfaces - Request registered interfaces list
892 * @iter: Pointer to incoming dbus message iter
893 * @error: Location to store error on failure
894 * @user_data: Function specific data
895 * Returns: TRUE on success, FALSE on failure
897 * Getter for "Interfaces" property. Handles requests
898 * by dbus clients to return list of registered interfaces objects
901 dbus_bool_t
wpas_dbus_getter_interfaces(
902 const struct wpa_dbus_property_desc
*property_desc
,
903 DBusMessageIter
*iter
, DBusError
*error
, void *user_data
)
905 struct wpa_global
*global
= user_data
;
906 struct wpa_supplicant
*wpa_s
;
908 unsigned int i
= 0, num
= 0;
911 for (wpa_s
= global
->ifaces
; wpa_s
; wpa_s
= wpa_s
->next
) {
912 if (wpa_s
->dbus_new_path
)
916 paths
= os_calloc(num
, sizeof(char *));
918 dbus_set_error_const(error
, DBUS_ERROR_NO_MEMORY
, "no memory");
922 for (wpa_s
= global
->ifaces
; wpa_s
; wpa_s
= wpa_s
->next
) {
923 if (wpa_s
->dbus_new_path
)
924 paths
[i
++] = wpa_s
->dbus_new_path
;
927 success
= wpas_dbus_simple_array_property_getter(iter
,
928 DBUS_TYPE_OBJECT_PATH
,
937 * wpas_dbus_getter_eap_methods - Request supported EAP methods list
938 * @iter: Pointer to incoming dbus message iter
939 * @error: Location to store error on failure
940 * @user_data: Function specific data
941 * Returns: TRUE on success, FALSE on failure
943 * Getter for "EapMethods" property. Handles requests
944 * by dbus clients to return list of strings with supported EAP methods
946 dbus_bool_t
wpas_dbus_getter_eap_methods(
947 const struct wpa_dbus_property_desc
*property_desc
,
948 DBusMessageIter
*iter
, DBusError
*error
, void *user_data
)
951 size_t num_items
= 0;
954 eap_methods
= eap_get_names_as_string_array(&num_items
);
956 dbus_set_error_const(error
, DBUS_ERROR_NO_MEMORY
, "no memory");
960 success
= wpas_dbus_simple_array_property_getter(iter
,
966 os_free(eap_methods
[--num_items
]);
967 os_free(eap_methods
);
973 * wpas_dbus_getter_global_capabilities - Request supported global capabilities
974 * @iter: Pointer to incoming dbus message iter
975 * @error: Location to store error on failure
976 * @user_data: Function specific data
977 * Returns: TRUE on success, FALSE on failure
979 * Getter for "Capabilities" property. Handles requests by dbus clients to
980 * return a list of strings with supported capabilities like AP, RSN IBSS,
981 * and P2P that are determined at compile time.
983 dbus_bool_t
wpas_dbus_getter_global_capabilities(
984 const struct wpa_dbus_property_desc
*property_desc
,
985 DBusMessageIter
*iter
, DBusError
*error
, void *user_data
)
987 const char *capabilities
[10] = { NULL
, NULL
, NULL
, NULL
, NULL
, NULL
,
988 NULL
, NULL
, NULL
, NULL
};
989 size_t num_items
= 0;
991 struct wpa_global
*global
= user_data
;
992 struct wpa_supplicant
*wpa_s
;
993 int fils_supported
= 0, fils_sk_pfs_supported
= 0;
995 for (wpa_s
= global
->ifaces
; wpa_s
; wpa_s
= wpa_s
->next
) {
996 if (wpa_is_fils_supported(wpa_s
))
998 if (wpa_is_fils_sk_pfs_supported(wpa_s
))
999 fils_sk_pfs_supported
= 1;
1001 #endif /* CONFIG_FILS */
1004 capabilities
[num_items
++] = "ap";
1005 #endif /* CONFIG_AP */
1006 #ifdef CONFIG_IBSS_RSN
1007 capabilities
[num_items
++] = "ibss-rsn";
1008 #endif /* CONFIG_IBSS_RSN */
1010 capabilities
[num_items
++] = "p2p";
1011 #endif /* CONFIG_P2P */
1012 #ifdef CONFIG_INTERWORKING
1013 capabilities
[num_items
++] = "interworking";
1014 #endif /* CONFIG_INTERWORKING */
1015 capabilities
[num_items
++] = "pmf";
1017 capabilities
[num_items
++] = "mesh";
1018 #endif /* CONFIG_MESH */
1021 capabilities
[num_items
++] = "fils";
1022 if (fils_sk_pfs_supported
)
1023 capabilities
[num_items
++] = "fils_sk_pfs";
1024 #endif /* CONFIG_FILS */
1025 #ifdef CONFIG_IEEE80211R
1026 capabilities
[num_items
++] = "ft";
1027 #endif /* CONFIG_IEEE80211R */
1028 #ifdef CONFIG_SHA384
1029 capabilities
[num_items
++] = "sha384";
1030 #endif /* CONFIG_SHA384 */
1032 return wpas_dbus_simple_array_property_getter(iter
,
1039 static int wpas_dbus_get_scan_type(DBusMessage
*message
, DBusMessageIter
*var
,
1040 char **type
, DBusMessage
**reply
)
1042 if (dbus_message_iter_get_arg_type(var
) != DBUS_TYPE_STRING
) {
1043 wpa_printf(MSG_DEBUG
, "%s[dbus]: Type must be a string",
1045 *reply
= wpas_dbus_error_invalid_args(
1046 message
, "Wrong Type value type. String required");
1049 dbus_message_iter_get_basic(var
, type
);
1054 static int wpas_dbus_get_scan_ssids(DBusMessage
*message
, DBusMessageIter
*var
,
1055 struct wpa_driver_scan_params
*params
,
1056 DBusMessage
**reply
)
1058 struct wpa_driver_scan_ssid
*ssids
= params
->ssids
;
1059 size_t ssids_num
= 0;
1061 DBusMessageIter array_iter
, sub_array_iter
;
1065 if (dbus_message_iter_get_arg_type(var
) != DBUS_TYPE_ARRAY
) {
1066 wpa_printf(MSG_DEBUG
,
1067 "%s[dbus]: ssids must be an array of arrays of bytes",
1069 *reply
= wpas_dbus_error_invalid_args(
1071 "Wrong SSIDs value type. Array of arrays of bytes required");
1075 dbus_message_iter_recurse(var
, &array_iter
);
1077 if (dbus_message_iter_get_arg_type(&array_iter
) != DBUS_TYPE_ARRAY
||
1078 dbus_message_iter_get_element_type(&array_iter
) != DBUS_TYPE_BYTE
) {
1079 wpa_printf(MSG_DEBUG
,
1080 "%s[dbus]: ssids must be an array of arrays of bytes",
1082 *reply
= wpas_dbus_error_invalid_args(
1084 "Wrong SSIDs value type. Array of arrays of bytes required");
1088 while (dbus_message_iter_get_arg_type(&array_iter
) == DBUS_TYPE_ARRAY
) {
1089 if (ssids_num
>= WPAS_MAX_SCAN_SSIDS
) {
1090 wpa_printf(MSG_DEBUG
,
1091 "%s[dbus]: Too many ssids specified on scan dbus call",
1093 *reply
= wpas_dbus_error_invalid_args(
1095 "Too many ssids specified. Specify at most four");
1099 dbus_message_iter_recurse(&array_iter
, &sub_array_iter
);
1101 dbus_message_iter_get_fixed_array(&sub_array_iter
, &val
, &len
);
1103 if (len
> SSID_MAX_LEN
) {
1104 wpa_printf(MSG_DEBUG
,
1105 "%s[dbus]: SSID too long (len=%d max_len=%d)",
1106 __func__
, len
, SSID_MAX_LEN
);
1107 *reply
= wpas_dbus_error_invalid_args(
1108 message
, "Invalid SSID: too long");
1113 ssid
= os_memdup(val
, len
);
1115 *reply
= wpas_dbus_error_no_memory(message
);
1119 /* Allow zero-length SSIDs */
1123 ssids
[ssids_num
].ssid
= ssid
;
1124 ssids
[ssids_num
].ssid_len
= len
;
1126 dbus_message_iter_next(&array_iter
);
1130 params
->num_ssids
= ssids_num
;
1135 static int wpas_dbus_get_scan_ies(DBusMessage
*message
, DBusMessageIter
*var
,
1136 struct wpa_driver_scan_params
*params
,
1137 DBusMessage
**reply
)
1139 u8
*ies
= NULL
, *nies
;
1141 DBusMessageIter array_iter
, sub_array_iter
;
1145 if (dbus_message_iter_get_arg_type(var
) != DBUS_TYPE_ARRAY
) {
1146 wpa_printf(MSG_DEBUG
,
1147 "%s[dbus]: ies must be an array of arrays of bytes",
1149 *reply
= wpas_dbus_error_invalid_args(
1151 "Wrong IEs value type. Array of arrays of bytes required");
1155 dbus_message_iter_recurse(var
, &array_iter
);
1157 if (dbus_message_iter_get_arg_type(&array_iter
) != DBUS_TYPE_ARRAY
||
1158 dbus_message_iter_get_element_type(&array_iter
) != DBUS_TYPE_BYTE
) {
1159 wpa_printf(MSG_DEBUG
,
1160 "%s[dbus]: ies must be an array of arrays of bytes",
1162 *reply
= wpas_dbus_error_invalid_args(
1163 message
, "Wrong IEs value type. Array required");
1167 while (dbus_message_iter_get_arg_type(&array_iter
) == DBUS_TYPE_ARRAY
) {
1168 dbus_message_iter_recurse(&array_iter
, &sub_array_iter
);
1170 dbus_message_iter_get_fixed_array(&sub_array_iter
, &val
, &len
);
1172 dbus_message_iter_next(&array_iter
);
1176 nies
= os_realloc(ies
, ies_len
+ len
);
1179 *reply
= wpas_dbus_error_no_memory(message
);
1183 os_memcpy(ies
+ ies_len
, val
, len
);
1186 dbus_message_iter_next(&array_iter
);
1189 params
->extra_ies
= ies
;
1190 params
->extra_ies_len
= ies_len
;
1195 static int wpas_dbus_get_scan_channels(DBusMessage
*message
,
1196 DBusMessageIter
*var
,
1197 struct wpa_driver_scan_params
*params
,
1198 DBusMessage
**reply
)
1200 DBusMessageIter array_iter
, sub_array_iter
;
1201 int *freqs
= NULL
, *nfreqs
;
1204 if (dbus_message_iter_get_arg_type(var
) != DBUS_TYPE_ARRAY
) {
1205 wpa_printf(MSG_DEBUG
,
1206 "%s[dbus]: Channels must be an array of structs",
1208 *reply
= wpas_dbus_error_invalid_args(
1210 "Wrong Channels value type. Array of structs required");
1214 dbus_message_iter_recurse(var
, &array_iter
);
1216 if (dbus_message_iter_get_arg_type(&array_iter
) != DBUS_TYPE_STRUCT
) {
1217 wpa_printf(MSG_DEBUG
,
1218 "%s[dbus]: Channels must be an array of structs",
1220 *reply
= wpas_dbus_error_invalid_args(
1222 "Wrong Channels value type. Array of structs required");
1226 while (dbus_message_iter_get_arg_type(&array_iter
) == DBUS_TYPE_STRUCT
)
1230 dbus_message_iter_recurse(&array_iter
, &sub_array_iter
);
1232 if (dbus_message_iter_get_arg_type(&sub_array_iter
) !=
1234 wpa_printf(MSG_DEBUG
,
1235 "%s[dbus]: Channel must by specified by struct of two UINT32s %c",
1237 dbus_message_iter_get_arg_type(
1239 *reply
= wpas_dbus_error_invalid_args(
1241 "Wrong Channel struct. Two UINT32s required");
1245 dbus_message_iter_get_basic(&sub_array_iter
, &freq
);
1247 if (!dbus_message_iter_next(&sub_array_iter
) ||
1248 dbus_message_iter_get_arg_type(&sub_array_iter
) !=
1250 wpa_printf(MSG_DEBUG
,
1251 "%s[dbus]: Channel must by specified by struct of two UINT32s",
1253 *reply
= wpas_dbus_error_invalid_args(
1255 "Wrong Channel struct. Two UINT32s required");
1260 dbus_message_iter_get_basic(&sub_array_iter
, &width
);
1262 #define FREQS_ALLOC_CHUNK 32
1263 if (freqs_num
% FREQS_ALLOC_CHUNK
== 0) {
1264 nfreqs
= os_realloc_array(
1265 freqs
, freqs_num
+ FREQS_ALLOC_CHUNK
,
1271 if (freqs
== NULL
) {
1272 *reply
= wpas_dbus_error_no_memory(message
);
1276 freqs
[freqs_num
] = freq
;
1279 dbus_message_iter_next(&array_iter
);
1282 nfreqs
= os_realloc_array(freqs
, freqs_num
+ 1, sizeof(int));
1286 if (freqs
== NULL
) {
1287 *reply
= wpas_dbus_error_no_memory(message
);
1290 freqs
[freqs_num
] = 0;
1292 params
->freqs
= freqs
;
1297 static int wpas_dbus_get_scan_allow_roam(DBusMessage
*message
,
1298 DBusMessageIter
*var
,
1300 DBusMessage
**reply
)
1302 if (dbus_message_iter_get_arg_type(var
) != DBUS_TYPE_BOOLEAN
) {
1303 wpa_printf(MSG_DEBUG
, "%s[dbus]: Type must be a boolean",
1305 *reply
= wpas_dbus_error_invalid_args(
1306 message
, "Wrong Type value type. Boolean required");
1309 dbus_message_iter_get_basic(var
, allow
);
1315 * wpas_dbus_handler_scan - Request a wireless scan on an interface
1316 * @message: Pointer to incoming dbus message
1317 * @wpa_s: wpa_supplicant structure for a network interface
1318 * Returns: NULL indicating success or DBus error message on failure
1320 * Handler function for "Scan" method call of a network device. Requests
1321 * that wpa_supplicant perform a wireless scan as soon as possible
1322 * on a particular wireless interface.
1324 DBusMessage
* wpas_dbus_handler_scan(DBusMessage
*message
,
1325 struct wpa_supplicant
*wpa_s
)
1327 DBusMessage
*reply
= NULL
;
1328 DBusMessageIter iter
, dict_iter
, entry_iter
, variant_iter
;
1329 char *key
= NULL
, *type
= NULL
;
1330 struct wpa_driver_scan_params params
;
1332 dbus_bool_t allow_roam
= 1;
1334 os_memset(¶ms
, 0, sizeof(params
));
1336 dbus_message_iter_init(message
, &iter
);
1338 dbus_message_iter_recurse(&iter
, &dict_iter
);
1340 while (dbus_message_iter_get_arg_type(&dict_iter
) ==
1341 DBUS_TYPE_DICT_ENTRY
) {
1342 dbus_message_iter_recurse(&dict_iter
, &entry_iter
);
1343 dbus_message_iter_get_basic(&entry_iter
, &key
);
1344 dbus_message_iter_next(&entry_iter
);
1345 dbus_message_iter_recurse(&entry_iter
, &variant_iter
);
1347 if (os_strcmp(key
, "Type") == 0) {
1348 if (wpas_dbus_get_scan_type(message
, &variant_iter
,
1351 } else if (os_strcmp(key
, "SSIDs") == 0) {
1352 if (wpas_dbus_get_scan_ssids(message
, &variant_iter
,
1353 ¶ms
, &reply
) < 0)
1355 } else if (os_strcmp(key
, "IEs") == 0) {
1356 if (wpas_dbus_get_scan_ies(message
, &variant_iter
,
1357 ¶ms
, &reply
) < 0)
1359 } else if (os_strcmp(key
, "Channels") == 0) {
1360 if (wpas_dbus_get_scan_channels(message
, &variant_iter
,
1361 ¶ms
, &reply
) < 0)
1363 } else if (os_strcmp(key
, "AllowRoam") == 0) {
1364 if (wpas_dbus_get_scan_allow_roam(message
,
1370 wpa_printf(MSG_DEBUG
, "%s[dbus]: Unknown argument %s",
1372 reply
= wpas_dbus_error_invalid_args(message
, key
);
1376 dbus_message_iter_next(&dict_iter
);
1380 wpa_printf(MSG_DEBUG
, "%s[dbus]: Scan type not specified",
1382 reply
= wpas_dbus_error_invalid_args(message
, key
);
1386 if (os_strcmp(type
, "passive") == 0) {
1387 if (params
.num_ssids
|| params
.extra_ies_len
) {
1388 wpa_printf(MSG_DEBUG
,
1389 "%s[dbus]: SSIDs or IEs specified for passive scan.",
1391 reply
= wpas_dbus_error_invalid_args(
1393 "You can specify only Channels in passive scan");
1396 if (wpa_s
->sched_scanning
) {
1397 wpa_printf(MSG_DEBUG
,
1398 "%s[dbus]: Stop ongoing sched_scan to allow requested scan to proceed",
1400 wpa_supplicant_cancel_sched_scan(wpa_s
);
1403 if (params
.freqs
&& params
.freqs
[0]) {
1404 wpa_s
->last_scan_req
= MANUAL_SCAN_REQ
;
1405 if (wpa_supplicant_trigger_scan(wpa_s
,
1407 reply
= wpas_dbus_error_scan_error(
1409 "Scan request rejected");
1412 wpa_s
->scan_req
= MANUAL_SCAN_REQ
;
1413 wpa_supplicant_req_scan(wpa_s
, 0, 0);
1416 } else if (os_strcmp(type
, "active") == 0) {
1417 if (!params
.num_ssids
) {
1418 /* Add wildcard ssid */
1421 #ifdef CONFIG_AUTOSCAN
1422 autoscan_deinit(wpa_s
);
1423 #endif /* CONFIG_AUTOSCAN */
1424 if (wpa_s
->sched_scanning
) {
1425 wpa_printf(MSG_DEBUG
,
1426 "%s[dbus]: Stop ongoing sched_scan to allow requested scan to proceed",
1428 wpa_supplicant_cancel_sched_scan(wpa_s
);
1431 wpa_s
->last_scan_req
= MANUAL_SCAN_REQ
;
1432 if (wpa_supplicant_trigger_scan(wpa_s
, ¶ms
)) {
1433 reply
= wpas_dbus_error_scan_error(
1434 message
, "Scan request rejected");
1437 wpa_printf(MSG_DEBUG
, "%s[dbus]: Unknown scan type: %s",
1439 reply
= wpas_dbus_error_invalid_args(message
,
1445 wpa_s
->scan_res_handler
= scan_only_handler
;
1448 for (i
= 0; i
< WPAS_MAX_SCAN_SSIDS
; i
++)
1449 os_free((u8
*) params
.ssids
[i
].ssid
);
1450 os_free((u8
*) params
.extra_ies
);
1451 os_free(params
.freqs
);
1457 * wpas_dbus_handler_abort_scan - Request an ongoing scan to be aborted
1458 * @message: Pointer to incoming dbus message
1459 * @wpa_s: wpa_supplicant structure for a network interface
1460 * Returns: Abort failed or no scan in progress DBus error message on failure
1461 * or NULL otherwise.
1463 * Handler function for "AbortScan" method call of network interface.
1465 DBusMessage
* wpas_dbus_handler_abort_scan(DBusMessage
*message
,
1466 struct wpa_supplicant
*wpa_s
)
1468 if (wpas_abort_ongoing_scan(wpa_s
) < 0)
1469 return dbus_message_new_error(
1470 message
, WPAS_DBUS_ERROR_IFACE_SCAN_ERROR
,
1471 "Abort failed or no scan in progress");
1478 * wpas_dbus_handler_signal_poll - Request immediate signal properties
1479 * @message: Pointer to incoming dbus message
1480 * @wpa_s: wpa_supplicant structure for a network interface
1481 * Returns: NULL indicating success or DBus error message on failure
1483 * Handler function for "SignalPoll" method call of a network device. Requests
1484 * that wpa_supplicant read signal properties like RSSI, noise, and link
1485 * speed and return them.
1487 DBusMessage
* wpas_dbus_handler_signal_poll(DBusMessage
*message
,
1488 struct wpa_supplicant
*wpa_s
)
1490 struct wpa_signal_info si
;
1491 DBusMessage
*reply
= NULL
;
1492 DBusMessageIter iter
, iter_dict
, variant_iter
;
1495 ret
= wpa_drv_signal_poll(wpa_s
, &si
);
1497 return dbus_message_new_error(message
, DBUS_ERROR_FAILED
,
1498 "Failed to read signal");
1501 reply
= dbus_message_new_method_return(message
);
1505 dbus_message_iter_init_append(reply
, &iter
);
1507 if (!dbus_message_iter_open_container(&iter
, DBUS_TYPE_VARIANT
,
1508 "a{sv}", &variant_iter
) ||
1509 !wpa_dbus_dict_open_write(&variant_iter
, &iter_dict
) ||
1510 !wpa_dbus_dict_append_int32(&iter_dict
, "rssi",
1511 si
.current_signal
) ||
1512 !wpa_dbus_dict_append_int32(&iter_dict
, "linkspeed",
1513 si
.current_txrate
/ 1000) ||
1514 !wpa_dbus_dict_append_int32(&iter_dict
, "noise",
1515 si
.current_noise
) ||
1516 !wpa_dbus_dict_append_uint32(&iter_dict
, "frequency",
1518 (si
.chanwidth
!= CHAN_WIDTH_UNKNOWN
&&
1519 !wpa_dbus_dict_append_string(
1520 &iter_dict
, "width",
1521 channel_width_to_string(si
.chanwidth
))) ||
1522 (si
.center_frq1
> 0 && si
.center_frq2
> 0 &&
1523 (!wpa_dbus_dict_append_int32(&iter_dict
, "center-frq1",
1525 !wpa_dbus_dict_append_int32(&iter_dict
, "center-frq2",
1526 si
.center_frq2
))) ||
1528 !wpa_dbus_dict_append_int32(&iter_dict
, "avg-rssi",
1530 !wpa_dbus_dict_close_write(&variant_iter
, &iter_dict
) ||
1531 !dbus_message_iter_close_container(&iter
, &variant_iter
))
1538 dbus_message_unref(reply
);
1539 return wpas_dbus_error_no_memory(message
);
1544 * wpas_dbus_handler_disconnect - Terminate the current connection
1545 * @message: Pointer to incoming dbus message
1546 * @wpa_s: wpa_supplicant structure for a network interface
1547 * Returns: NotConnected DBus error message if already not connected
1548 * or NULL otherwise.
1550 * Handler function for "Disconnect" method call of network interface.
1552 DBusMessage
* wpas_dbus_handler_disconnect(DBusMessage
*message
,
1553 struct wpa_supplicant
*wpa_s
)
1555 if (wpa_s
->current_ssid
!= NULL
) {
1556 wpas_request_disconnection(wpa_s
);
1560 return dbus_message_new_error(message
, WPAS_DBUS_ERROR_NOT_CONNECTED
,
1561 "This interface is not connected");
1566 * wpas_dbus_new_iface_add_network - Add a new configured network
1567 * @message: Pointer to incoming dbus message
1568 * @wpa_s: wpa_supplicant structure for a network interface
1569 * Returns: A dbus message containing the object path of the new network
1571 * Handler function for "AddNetwork" method call of a network interface.
1573 DBusMessage
* wpas_dbus_handler_add_network(DBusMessage
*message
,
1574 struct wpa_supplicant
*wpa_s
)
1576 DBusMessage
*reply
= NULL
;
1577 DBusMessageIter iter
;
1578 struct wpa_ssid
*ssid
= NULL
;
1579 char path_buf
[WPAS_DBUS_OBJECT_PATH_MAX
], *path
= path_buf
;
1582 dbus_message_iter_init(message
, &iter
);
1584 if (wpa_s
->dbus_new_path
)
1585 ssid
= wpa_supplicant_add_network(wpa_s
);
1587 wpa_printf(MSG_ERROR
, "%s[dbus]: can't add new interface.",
1589 reply
= wpas_dbus_error_unknown_error(
1591 "wpa_supplicant could not add a network on this interface.");
1595 dbus_error_init(&error
);
1596 if (!set_network_properties(wpa_s
, ssid
, &iter
, &error
)) {
1597 wpa_printf(MSG_DEBUG
,
1598 "%s[dbus]: control interface couldn't set network properties",
1600 reply
= wpas_dbus_reply_new_from_error(message
, &error
,
1601 DBUS_ERROR_INVALID_ARGS
,
1602 "Failed to add network");
1603 dbus_error_free(&error
);
1607 /* Construct the object path for this network. */
1608 os_snprintf(path
, WPAS_DBUS_OBJECT_PATH_MAX
,
1609 "%s/" WPAS_DBUS_NEW_NETWORKS_PART
"/%d",
1610 wpa_s
->dbus_new_path
, ssid
->id
);
1612 reply
= dbus_message_new_method_return(message
);
1613 if (reply
== NULL
) {
1614 reply
= wpas_dbus_error_no_memory(message
);
1617 if (!dbus_message_append_args(reply
, DBUS_TYPE_OBJECT_PATH
, &path
,
1618 DBUS_TYPE_INVALID
)) {
1619 dbus_message_unref(reply
);
1620 reply
= wpas_dbus_error_no_memory(message
);
1628 wpas_notify_network_removed(wpa_s
, ssid
);
1629 wpa_config_remove_network(wpa_s
->conf
, ssid
->id
);
1636 * wpas_dbus_handler_reassociate - Reassociate
1637 * @message: Pointer to incoming dbus message
1638 * @wpa_s: wpa_supplicant structure for a network interface
1639 * Returns: InterfaceDisabled DBus error message if disabled
1640 * or NULL otherwise.
1642 * Handler function for "Reassociate" method call of network interface.
1644 DBusMessage
* wpas_dbus_handler_reassociate(DBusMessage
*message
,
1645 struct wpa_supplicant
*wpa_s
)
1647 if (wpa_s
->wpa_state
!= WPA_INTERFACE_DISABLED
) {
1648 wpas_request_connection(wpa_s
);
1652 return dbus_message_new_error(message
, WPAS_DBUS_ERROR_IFACE_DISABLED
,
1653 "This interface is disabled");
1658 * wpas_dbus_handler_expect_disconnect - ExpectDisconnect
1659 * @message: Pointer to incoming dbus message
1660 * @global: %wpa_supplicant global data structure
1663 * Handler function for notifying system there will be a expected disconnect.
1664 * This will prevent wpa_supplicant from adding blacklists upon next disconnect..
1666 DBusMessage
* wpas_dbus_handler_expect_disconnect(DBusMessage
*message
,
1667 struct wpa_global
*global
)
1669 struct wpa_supplicant
*wpa_s
= global
->ifaces
;
1671 for (; wpa_s
; wpa_s
= wpa_s
->next
)
1672 if (wpa_s
->wpa_state
>= WPA_ASSOCIATED
)
1673 wpa_s
->own_disconnect_req
= 1;
1679 * wpas_dbus_handler_reattach - Reattach to current AP
1680 * @message: Pointer to incoming dbus message
1681 * @wpa_s: wpa_supplicant structure for a network interface
1682 * Returns: NotConnected DBus error message if not connected
1683 * or NULL otherwise.
1685 * Handler function for "Reattach" method call of network interface.
1687 DBusMessage
* wpas_dbus_handler_reattach(DBusMessage
*message
,
1688 struct wpa_supplicant
*wpa_s
)
1690 if (wpa_s
->current_ssid
!= NULL
) {
1691 wpa_s
->reattach
= 1;
1692 wpas_request_connection(wpa_s
);
1696 return dbus_message_new_error(message
, WPAS_DBUS_ERROR_NOT_CONNECTED
,
1697 "This interface is not connected");
1702 * wpas_dbus_handler_reconnect - Reconnect if disconnected
1703 * @message: Pointer to incoming dbus message
1704 * @wpa_s: wpa_supplicant structure for a network interface
1705 * Returns: InterfaceDisabled DBus error message if disabled
1706 * or NULL otherwise.
1708 * Handler function for "Reconnect" method call of network interface.
1710 DBusMessage
* wpas_dbus_handler_reconnect(DBusMessage
*message
,
1711 struct wpa_supplicant
*wpa_s
)
1713 if (wpa_s
->wpa_state
== WPA_INTERFACE_DISABLED
) {
1714 return dbus_message_new_error(message
,
1715 WPAS_DBUS_ERROR_IFACE_DISABLED
,
1716 "This interface is disabled");
1719 if (wpa_s
->disconnected
)
1720 wpas_request_connection(wpa_s
);
1726 * wpas_dbus_handler_remove_network - Remove a configured network
1727 * @message: Pointer to incoming dbus message
1728 * @wpa_s: wpa_supplicant structure for a network interface
1729 * Returns: NULL on success or dbus error on failure
1731 * Handler function for "RemoveNetwork" method call of a network interface.
1733 DBusMessage
* wpas_dbus_handler_remove_network(DBusMessage
*message
,
1734 struct wpa_supplicant
*wpa_s
)
1736 DBusMessage
*reply
= NULL
;
1738 char *iface
, *net_id
;
1742 dbus_message_get_args(message
, NULL
, DBUS_TYPE_OBJECT_PATH
, &op
,
1745 /* Extract the network ID and ensure the network */
1746 /* is actually a child of this interface */
1747 iface
= wpas_dbus_new_decompose_object_path(op
,
1748 WPAS_DBUS_NEW_NETWORKS_PART
,
1750 if (iface
== NULL
|| net_id
== NULL
|| !wpa_s
->dbus_new_path
||
1751 os_strcmp(iface
, wpa_s
->dbus_new_path
) != 0) {
1752 reply
= wpas_dbus_error_invalid_args(message
, op
);
1757 id
= strtoul(net_id
, NULL
, 10);
1759 reply
= wpas_dbus_error_invalid_args(message
, op
);
1763 result
= wpa_supplicant_remove_network(wpa_s
, id
);
1765 reply
= wpas_dbus_error_network_unknown(message
);
1769 wpa_printf(MSG_ERROR
,
1770 "%s[dbus]: error occurred when removing network %d",
1772 reply
= wpas_dbus_error_unknown_error(
1774 "error removing the specified network on is interface.");
1784 static void remove_network(void *arg
, struct wpa_ssid
*ssid
)
1786 struct wpa_supplicant
*wpa_s
= arg
;
1788 wpas_notify_network_removed(wpa_s
, ssid
);
1790 if (wpa_config_remove_network(wpa_s
->conf
, ssid
->id
) < 0) {
1791 wpa_printf(MSG_ERROR
,
1792 "%s[dbus]: error occurred when removing network %d",
1793 __func__
, ssid
->id
);
1797 if (ssid
== wpa_s
->current_ssid
)
1798 wpa_supplicant_deauthenticate(wpa_s
,
1799 WLAN_REASON_DEAUTH_LEAVING
);
1804 * wpas_dbus_handler_remove_all_networks - Remove all configured networks
1805 * @message: Pointer to incoming dbus message
1806 * @wpa_s: wpa_supplicant structure for a network interface
1807 * Returns: NULL on success or dbus error on failure
1809 * Handler function for "RemoveAllNetworks" method call of a network interface.
1811 DBusMessage
* wpas_dbus_handler_remove_all_networks(
1812 DBusMessage
*message
, struct wpa_supplicant
*wpa_s
)
1814 if (wpa_s
->sched_scanning
)
1815 wpa_supplicant_cancel_sched_scan(wpa_s
);
1817 /* NB: could check for failure and return an error */
1818 wpa_config_foreach_network(wpa_s
->conf
, remove_network
, wpa_s
);
1824 * wpas_dbus_handler_select_network - Attempt association with a network
1825 * @message: Pointer to incoming dbus message
1826 * @wpa_s: wpa_supplicant structure for a network interface
1827 * Returns: NULL on success or dbus error on failure
1829 * Handler function for "SelectNetwork" method call of network interface.
1831 DBusMessage
* wpas_dbus_handler_select_network(DBusMessage
*message
,
1832 struct wpa_supplicant
*wpa_s
)
1834 DBusMessage
*reply
= NULL
;
1836 char *iface
, *net_id
;
1838 struct wpa_ssid
*ssid
;
1840 dbus_message_get_args(message
, NULL
, DBUS_TYPE_OBJECT_PATH
, &op
,
1843 /* Extract the network ID and ensure the network */
1844 /* is actually a child of this interface */
1845 iface
= wpas_dbus_new_decompose_object_path(op
,
1846 WPAS_DBUS_NEW_NETWORKS_PART
,
1848 if (iface
== NULL
|| net_id
== NULL
|| !wpa_s
->dbus_new_path
||
1849 os_strcmp(iface
, wpa_s
->dbus_new_path
) != 0) {
1850 reply
= wpas_dbus_error_invalid_args(message
, op
);
1855 id
= strtoul(net_id
, NULL
, 10);
1857 reply
= wpas_dbus_error_invalid_args(message
, op
);
1861 ssid
= wpa_config_get_network(wpa_s
->conf
, id
);
1863 reply
= wpas_dbus_error_network_unknown(message
);
1867 /* Finally, associate with the network */
1868 wpa_supplicant_select_network(wpa_s
, ssid
);
1877 * wpas_dbus_handler_network_reply - Reply to a NetworkRequest signal
1878 * @message: Pointer to incoming dbus message
1879 * @wpa_s: wpa_supplicant structure for a network interface
1880 * Returns: NULL on success or dbus error on failure
1882 * Handler function for "NetworkReply" method call of network interface.
1884 DBusMessage
* wpas_dbus_handler_network_reply(DBusMessage
*message
,
1885 struct wpa_supplicant
*wpa_s
)
1887 #ifdef IEEE8021X_EAPOL
1888 DBusMessage
*reply
= NULL
;
1889 const char *op
, *field
, *value
;
1890 char *iface
, *net_id
;
1892 struct wpa_ssid
*ssid
;
1894 if (!dbus_message_get_args(message
, NULL
,
1895 DBUS_TYPE_OBJECT_PATH
, &op
,
1896 DBUS_TYPE_STRING
, &field
,
1897 DBUS_TYPE_STRING
, &value
,
1899 return wpas_dbus_error_invalid_args(message
, NULL
);
1901 /* Extract the network ID and ensure the network */
1902 /* is actually a child of this interface */
1903 iface
= wpas_dbus_new_decompose_object_path(op
,
1904 WPAS_DBUS_NEW_NETWORKS_PART
,
1906 if (iface
== NULL
|| net_id
== NULL
|| !wpa_s
->dbus_new_path
||
1907 os_strcmp(iface
, wpa_s
->dbus_new_path
) != 0) {
1908 reply
= wpas_dbus_error_invalid_args(message
, op
);
1913 id
= strtoul(net_id
, NULL
, 10);
1915 reply
= wpas_dbus_error_invalid_args(message
, net_id
);
1919 ssid
= wpa_config_get_network(wpa_s
->conf
, id
);
1921 reply
= wpas_dbus_error_network_unknown(message
);
1925 if (wpa_supplicant_ctrl_iface_ctrl_rsp_handle(wpa_s
, ssid
,
1927 reply
= wpas_dbus_error_invalid_args(message
, field
);
1929 /* Tell EAP to retry immediately */
1930 eapol_sm_notify_ctrl_response(wpa_s
->eapol
);
1936 #else /* IEEE8021X_EAPOL */
1937 wpa_printf(MSG_DEBUG
, "dbus: 802.1X not included");
1938 return wpas_dbus_error_unknown_error(message
, "802.1X not included");
1939 #endif /* IEEE8021X_EAPOL */
1943 #ifndef CONFIG_NO_CONFIG_BLOBS
1946 * wpas_dbus_handler_add_blob - Store named binary blob (ie, for certificates)
1947 * @message: Pointer to incoming dbus message
1948 * @wpa_s: %wpa_supplicant data structure
1949 * Returns: A dbus message containing an error on failure or NULL on success
1951 * Asks wpa_supplicant to internally store a binary blobs.
1953 DBusMessage
* wpas_dbus_handler_add_blob(DBusMessage
*message
,
1954 struct wpa_supplicant
*wpa_s
)
1956 DBusMessage
*reply
= NULL
;
1957 DBusMessageIter iter
, array_iter
;
1962 struct wpa_config_blob
*blob
= NULL
;
1964 dbus_message_iter_init(message
, &iter
);
1965 dbus_message_iter_get_basic(&iter
, &blob_name
);
1967 if (wpa_config_get_blob(wpa_s
->conf
, blob_name
)) {
1968 return dbus_message_new_error(message
,
1969 WPAS_DBUS_ERROR_BLOB_EXISTS
,
1973 dbus_message_iter_next(&iter
);
1974 dbus_message_iter_recurse(&iter
, &array_iter
);
1976 dbus_message_iter_get_fixed_array(&array_iter
, &blob_data
, &blob_len
);
1978 blob
= os_zalloc(sizeof(*blob
));
1980 reply
= wpas_dbus_error_no_memory(message
);
1984 blob
->data
= os_memdup(blob_data
, blob_len
);
1985 blob
->name
= os_strdup(blob_name
);
1986 if (!blob
->data
|| !blob
->name
) {
1987 reply
= wpas_dbus_error_no_memory(message
);
1990 blob
->len
= blob_len
;
1992 wpa_config_set_blob(wpa_s
->conf
, blob
);
1993 wpas_notify_blob_added(wpa_s
, blob
->name
);
1999 os_free(blob
->name
);
2000 os_free(blob
->data
);
2008 * wpas_dbus_handler_get_blob - Get named binary blob (ie, for certificates)
2009 * @message: Pointer to incoming dbus message
2010 * @wpa_s: %wpa_supplicant data structure
2011 * Returns: A dbus message containing array of bytes (blob)
2013 * Gets one wpa_supplicant's binary blobs.
2015 DBusMessage
* wpas_dbus_handler_get_blob(DBusMessage
*message
,
2016 struct wpa_supplicant
*wpa_s
)
2018 DBusMessage
*reply
= NULL
;
2019 DBusMessageIter iter
, array_iter
;
2022 const struct wpa_config_blob
*blob
;
2024 dbus_message_get_args(message
, NULL
, DBUS_TYPE_STRING
, &blob_name
,
2027 blob
= wpa_config_get_blob(wpa_s
->conf
, blob_name
);
2029 return dbus_message_new_error(message
,
2030 WPAS_DBUS_ERROR_BLOB_UNKNOWN
,
2034 reply
= dbus_message_new_method_return(message
);
2036 return wpas_dbus_error_no_memory(message
);
2038 dbus_message_iter_init_append(reply
, &iter
);
2040 if (!dbus_message_iter_open_container(&iter
, DBUS_TYPE_ARRAY
,
2041 DBUS_TYPE_BYTE_AS_STRING
,
2043 !dbus_message_iter_append_fixed_array(&array_iter
, DBUS_TYPE_BYTE
,
2044 &(blob
->data
), blob
->len
) ||
2045 !dbus_message_iter_close_container(&iter
, &array_iter
)) {
2046 dbus_message_unref(reply
);
2047 reply
= wpas_dbus_error_no_memory(message
);
2055 * wpas_remove_handler_remove_blob - Remove named binary blob
2056 * @message: Pointer to incoming dbus message
2057 * @wpa_s: %wpa_supplicant data structure
2058 * Returns: NULL on success or dbus error
2060 * Asks wpa_supplicant to internally remove a binary blobs.
2062 DBusMessage
* wpas_dbus_handler_remove_blob(DBusMessage
*message
,
2063 struct wpa_supplicant
*wpa_s
)
2065 DBusMessage
*reply
= NULL
;
2068 dbus_message_get_args(message
, NULL
, DBUS_TYPE_STRING
, &blob_name
,
2071 if (wpa_config_remove_blob(wpa_s
->conf
, blob_name
)) {
2072 return dbus_message_new_error(message
,
2073 WPAS_DBUS_ERROR_BLOB_UNKNOWN
,
2076 wpas_notify_blob_removed(wpa_s
, blob_name
);
2082 #endif /* CONFIG_NO_CONFIG_BLOBS */
2086 * wpas_dbus_handler_flush_bss - Flush the BSS cache
2087 * @message: Pointer to incoming dbus message
2088 * @wpa_s: wpa_supplicant structure for a network interface
2091 * Handler function for "FlushBSS" method call of network interface.
2093 DBusMessage
* wpas_dbus_handler_flush_bss(DBusMessage
*message
,
2094 struct wpa_supplicant
*wpa_s
)
2098 dbus_message_get_args(message
, NULL
, DBUS_TYPE_UINT32
, &age
,
2102 wpa_bss_flush(wpa_s
);
2104 wpa_bss_flush_by_age(wpa_s
, age
);
2110 #ifdef CONFIG_AUTOSCAN
2112 * wpas_dbus_handler_autoscan - Set autoscan parameters for the interface
2113 * @message: Pointer to incoming dbus message
2114 * @wpa_s: wpa_supplicant structure for a network interface
2117 * Handler function for "AutoScan" method call of network interface.
2119 DBusMessage
* wpas_dbus_handler_autoscan(DBusMessage
*message
,
2120 struct wpa_supplicant
*wpa_s
)
2122 DBusMessage
*reply
= NULL
;
2123 enum wpa_states state
= wpa_s
->wpa_state
;
2126 dbus_message_get_args(message
, NULL
, DBUS_TYPE_STRING
, &arg
,
2129 if (arg
!= NULL
&& os_strlen(arg
) > 0) {
2132 tmp
= os_strdup(arg
);
2134 reply
= wpas_dbus_error_no_memory(message
);
2136 os_free(wpa_s
->conf
->autoscan
);
2137 wpa_s
->conf
->autoscan
= tmp
;
2138 if (state
== WPA_DISCONNECTED
|| state
== WPA_INACTIVE
)
2139 autoscan_init(wpa_s
, 1);
2140 else if (state
== WPA_SCANNING
)
2141 wpa_supplicant_reinit_autoscan(wpa_s
);
2143 } else if (arg
!= NULL
&& os_strlen(arg
) == 0) {
2144 os_free(wpa_s
->conf
->autoscan
);
2145 wpa_s
->conf
->autoscan
= NULL
;
2146 autoscan_deinit(wpa_s
);
2148 reply
= dbus_message_new_error(message
,
2149 DBUS_ERROR_INVALID_ARGS
,
2154 #endif /* CONFIG_AUTOSCAN */
2158 * wpas_dbus_handler_eap_logoff - IEEE 802.1X EAPOL state machine logoff
2159 * @message: Pointer to incoming dbus message
2160 * @wpa_s: wpa_supplicant structure for a network interface
2163 * Handler function for "EAPLogoff" method call of network interface.
2165 DBusMessage
* wpas_dbus_handler_eap_logoff(DBusMessage
*message
,
2166 struct wpa_supplicant
*wpa_s
)
2168 eapol_sm_notify_logoff(wpa_s
->eapol
, TRUE
);
2174 * wpas_dbus_handler_eap_logon - IEEE 802.1X EAPOL state machine logon
2175 * @message: Pointer to incoming dbus message
2176 * @wpa_s: wpa_supplicant structure for a network interface
2179 * Handler function for "EAPLogin" method call of network interface.
2181 DBusMessage
* wpas_dbus_handler_eap_logon(DBusMessage
*message
,
2182 struct wpa_supplicant
*wpa_s
)
2184 eapol_sm_notify_logoff(wpa_s
->eapol
, FALSE
);
2191 static int get_peer_hwaddr_helper(DBusMessage
*message
, const char *func_name
,
2192 u8
*peer_address
, DBusMessage
**error
)
2194 const char *peer_string
;
2198 if (!dbus_message_get_args(message
, NULL
,
2199 DBUS_TYPE_STRING
, &peer_string
,
2200 DBUS_TYPE_INVALID
)) {
2201 *error
= wpas_dbus_error_invalid_args(message
, NULL
);
2205 if (hwaddr_aton(peer_string
, peer_address
)) {
2206 wpa_printf(MSG_DEBUG
, "%s: invalid address '%s'",
2207 func_name
, peer_string
);
2208 *error
= wpas_dbus_error_invalid_args(
2209 message
, "Invalid hardware address format");
2218 * wpas_dbus_handler_tdls_discover - Discover TDLS peer
2219 * @message: Pointer to incoming dbus message
2220 * @wpa_s: wpa_supplicant structure for a network interface
2221 * Returns: NULL indicating success or DBus error message on failure
2223 * Handler function for "TDLSDiscover" method call of network interface.
2225 DBusMessage
* wpas_dbus_handler_tdls_discover(DBusMessage
*message
,
2226 struct wpa_supplicant
*wpa_s
)
2229 DBusMessage
*error_reply
;
2232 if (get_peer_hwaddr_helper(message
, __func__
, peer
, &error_reply
) < 0)
2235 wpa_printf(MSG_DEBUG
, "DBUS TDLS_DISCOVER " MACSTR
, MAC2STR(peer
));
2237 if (wpa_tdls_is_external_setup(wpa_s
->wpa
))
2238 ret
= wpa_tdls_send_discovery_request(wpa_s
->wpa
, peer
);
2240 ret
= wpa_drv_tdls_oper(wpa_s
, TDLS_DISCOVERY_REQ
, peer
);
2243 return wpas_dbus_error_unknown_error(
2244 message
, "error performing TDLS discovery");
2252 * wpas_dbus_handler_tdls_setup - Setup TDLS session
2253 * @message: Pointer to incoming dbus message
2254 * @wpa_s: wpa_supplicant structure for a network interface
2255 * Returns: NULL indicating success or DBus error message on failure
2257 * Handler function for "TDLSSetup" method call of network interface.
2259 DBusMessage
* wpas_dbus_handler_tdls_setup(DBusMessage
*message
,
2260 struct wpa_supplicant
*wpa_s
)
2263 DBusMessage
*error_reply
;
2266 if (get_peer_hwaddr_helper(message
, __func__
, peer
, &error_reply
) < 0)
2269 wpa_printf(MSG_DEBUG
, "DBUS TDLS_SETUP " MACSTR
, MAC2STR(peer
));
2271 wpa_tdls_remove(wpa_s
->wpa
, peer
);
2272 if (wpa_tdls_is_external_setup(wpa_s
->wpa
))
2273 ret
= wpa_tdls_start(wpa_s
->wpa
, peer
);
2275 ret
= wpa_drv_tdls_oper(wpa_s
, TDLS_SETUP
, peer
);
2278 return wpas_dbus_error_unknown_error(
2279 message
, "error performing TDLS setup");
2287 * wpas_dbus_handler_tdls_status - Return TDLS session status
2288 * @message: Pointer to incoming dbus message
2289 * @wpa_s: wpa_supplicant structure for a network interface
2290 * Returns: A string representing the state of the link to this TDLS peer
2292 * Handler function for "TDLSStatus" method call of network interface.
2294 DBusMessage
* wpas_dbus_handler_tdls_status(DBusMessage
*message
,
2295 struct wpa_supplicant
*wpa_s
)
2299 const char *tdls_status
;
2301 if (get_peer_hwaddr_helper(message
, __func__
, peer
, &reply
) < 0)
2304 wpa_printf(MSG_DEBUG
, "DBUS TDLS_STATUS " MACSTR
, MAC2STR(peer
));
2306 tdls_status
= wpa_tdls_get_link_status(wpa_s
->wpa
, peer
);
2308 reply
= dbus_message_new_method_return(message
);
2309 dbus_message_append_args(reply
, DBUS_TYPE_STRING
,
2310 &tdls_status
, DBUS_TYPE_INVALID
);
2316 * wpas_dbus_handler_tdls_teardown - Teardown TDLS session
2317 * @message: Pointer to incoming dbus message
2318 * @wpa_s: wpa_supplicant structure for a network interface
2319 * Returns: NULL indicating success or DBus error message on failure
2321 * Handler function for "TDLSTeardown" method call of network interface.
2323 DBusMessage
* wpas_dbus_handler_tdls_teardown(DBusMessage
*message
,
2324 struct wpa_supplicant
*wpa_s
)
2327 DBusMessage
*error_reply
;
2330 if (get_peer_hwaddr_helper(message
, __func__
, peer
, &error_reply
) < 0)
2333 wpa_printf(MSG_DEBUG
, "DBUS TDLS_TEARDOWN " MACSTR
, MAC2STR(peer
));
2335 if (wpa_tdls_is_external_setup(wpa_s
->wpa
))
2336 ret
= wpa_tdls_teardown_link(
2338 WLAN_REASON_TDLS_TEARDOWN_UNSPECIFIED
);
2340 ret
= wpa_drv_tdls_oper(wpa_s
, TDLS_TEARDOWN
, peer
);
2343 return wpas_dbus_error_unknown_error(
2344 message
, "error performing TDLS teardown");
2351 * wpas_dbus_handler_tdls_channel_switch - Enable channel switching with TDLS peer
2352 * @message: Pointer to incoming dbus message
2353 * @wpa_s: wpa_supplicant structure for a network interface
2354 * Returns: NULL indicating success or DBus error message on failure
2356 * Handler function for "TDLSChannelSwitch" method call of network interface.
2359 wpas_dbus_handler_tdls_channel_switch(DBusMessage
*message
,
2360 struct wpa_supplicant
*wpa_s
)
2362 DBusMessageIter iter
, iter_dict
;
2363 struct wpa_dbus_dict_entry entry
;
2365 struct hostapd_freq_params freq_params
;
2368 int is_peer_present
= 0;
2370 if (!wpa_tdls_is_external_setup(wpa_s
->wpa
)) {
2371 wpa_printf(MSG_INFO
,
2372 "tdls_chanswitch: Only supported with external setup");
2373 return wpas_dbus_error_unknown_error(message
, "TDLS is not using external setup");
2376 os_memset(&freq_params
, 0, sizeof(freq_params
));
2378 dbus_message_iter_init(message
, &iter
);
2380 if (!wpa_dbus_dict_open_read(&iter
, &iter_dict
, NULL
))
2381 return wpas_dbus_error_invalid_args(message
, NULL
);
2383 while (wpa_dbus_dict_has_dict_entry(&iter_dict
)) {
2384 if (!wpa_dbus_dict_get_entry(&iter_dict
, &entry
))
2385 return wpas_dbus_error_invalid_args(message
, NULL
);
2387 if (os_strcmp(entry
.key
, "PeerAddress") == 0 &&
2388 entry
.type
== DBUS_TYPE_STRING
) {
2389 if (hwaddr_aton(entry
.str_value
, peer
)) {
2390 wpa_printf(MSG_DEBUG
,
2391 "tdls_chanswitch: Invalid address '%s'",
2393 wpa_dbus_dict_entry_clear(&entry
);
2394 return wpas_dbus_error_invalid_args(message
,
2398 is_peer_present
= 1;
2399 } else if (os_strcmp(entry
.key
, "OperClass") == 0 &&
2400 entry
.type
== DBUS_TYPE_BYTE
) {
2401 oper_class
= entry
.byte_value
;
2402 } else if (os_strcmp(entry
.key
, "Frequency") == 0 &&
2403 entry
.type
== DBUS_TYPE_UINT32
) {
2404 freq_params
.freq
= entry
.uint32_value
;
2405 } else if (os_strcmp(entry
.key
, "SecChannelOffset") == 0 &&
2406 entry
.type
== DBUS_TYPE_UINT32
) {
2407 freq_params
.sec_channel_offset
= entry
.uint32_value
;
2408 } else if (os_strcmp(entry
.key
, "CenterFrequency1") == 0 &&
2409 entry
.type
== DBUS_TYPE_UINT32
) {
2410 freq_params
.center_freq1
= entry
.uint32_value
;
2411 } else if (os_strcmp(entry
.key
, "CenterFrequency2") == 0 &&
2412 entry
.type
== DBUS_TYPE_UINT32
) {
2413 freq_params
.center_freq2
= entry
.uint32_value
;
2414 } else if (os_strcmp(entry
.key
, "Bandwidth") == 0 &&
2415 entry
.type
== DBUS_TYPE_UINT32
) {
2416 freq_params
.bandwidth
= entry
.uint32_value
;
2417 } else if (os_strcmp(entry
.key
, "HT") == 0 &&
2418 entry
.type
== DBUS_TYPE_BOOLEAN
) {
2419 freq_params
.ht_enabled
= entry
.bool_value
;
2420 } else if (os_strcmp(entry
.key
, "VHT") == 0 &&
2421 entry
.type
== DBUS_TYPE_BOOLEAN
) {
2422 freq_params
.vht_enabled
= entry
.bool_value
;
2424 wpa_dbus_dict_entry_clear(&entry
);
2425 return wpas_dbus_error_invalid_args(message
, NULL
);
2428 wpa_dbus_dict_entry_clear(&entry
);
2431 if (oper_class
== 0) {
2432 wpa_printf(MSG_INFO
,
2433 "tdls_chanswitch: Invalid op class provided");
2434 return wpas_dbus_error_invalid_args(
2435 message
, "Invalid op class provided");
2438 if (freq_params
.freq
== 0) {
2439 wpa_printf(MSG_INFO
,
2440 "tdls_chanswitch: Invalid freq provided");
2441 return wpas_dbus_error_invalid_args(message
,
2442 "Invalid freq provided");
2445 if (is_peer_present
== 0) {
2446 wpa_printf(MSG_DEBUG
,
2447 "tdls_chanswitch: peer address not provided");
2448 return wpas_dbus_error_invalid_args(
2449 message
, "peer address not provided");
2452 wpa_printf(MSG_DEBUG
, "dbus: TDLS_CHAN_SWITCH " MACSTR
2453 " OP CLASS %d FREQ %d CENTER1 %d CENTER2 %d BW %d SEC_OFFSET %d%s%s",
2454 MAC2STR(peer
), oper_class
, freq_params
.freq
,
2455 freq_params
.center_freq1
, freq_params
.center_freq2
,
2456 freq_params
.bandwidth
, freq_params
.sec_channel_offset
,
2457 freq_params
.ht_enabled
? " HT" : "",
2458 freq_params
.vht_enabled
? " VHT" : "");
2460 ret
= wpa_tdls_enable_chan_switch(wpa_s
->wpa
, peer
, oper_class
,
2463 return wpas_dbus_error_unknown_error(
2464 message
, "error processing TDLS channel switch");
2470 * wpas_dbus_handler_tdls_cancel_channel_switch - Disable channel switching with TDLS peer
2471 * @message: Pointer to incoming dbus message
2472 * @wpa_s: wpa_supplicant structure for a network interface
2473 * Returns: NULL indicating success or DBus error message on failure
2475 * Handler function for "TDLSCancelChannelSwitch" method call of network
2479 wpas_dbus_handler_tdls_cancel_channel_switch(DBusMessage
*message
,
2480 struct wpa_supplicant
*wpa_s
)
2483 DBusMessage
*error_reply
;
2486 if (get_peer_hwaddr_helper(message
, __func__
, peer
, &error_reply
) < 0)
2489 wpa_printf(MSG_DEBUG
, "dbus: TDLS_CANCEL_CHAN_SWITCH " MACSTR
,
2492 ret
= wpa_tdls_disable_chan_switch(wpa_s
->wpa
, peer
);
2494 return wpas_dbus_error_unknown_error(
2495 message
, "error canceling TDLS channel switch");
2500 #endif /* CONFIG_TDLS */
2503 #ifndef CONFIG_NO_CONFIG_WRITE
2505 * wpas_dbus_handler_save_config - Save configuration to configuration file
2506 * @message: Pointer to incoming dbus message
2507 * @wpa_s: wpa_supplicant structure for a network interface
2508 * Returns: NULL on Success, Otherwise errror message
2510 * Handler function for "SaveConfig" method call of network interface.
2512 DBusMessage
* wpas_dbus_handler_save_config(DBusMessage
*message
,
2513 struct wpa_supplicant
*wpa_s
)
2517 if (!wpa_s
->conf
->update_config
) {
2518 return wpas_dbus_error_unknown_error(
2520 "Not allowed to update configuration (update_config=0)");
2523 ret
= wpa_config_write(wpa_s
->confname
, wpa_s
->conf
);
2525 return wpas_dbus_error_unknown_error(
2526 message
, "Failed to update configuration");
2529 #endif /* CONFIG_NO_CONFIG_WRITE */
2533 * wpas_dbus_handler_set_pkcs11_engine_and_module_path - Set PKCS #11 engine and module path
2534 * @message: Pointer to incoming dbus message
2535 * @wpa_s: %wpa_supplicant data structure
2536 * Returns: A dbus message containing an error on failure or NULL on success
2538 * Sets the PKCS #11 engine and module path.
2540 DBusMessage
* wpas_dbus_handler_set_pkcs11_engine_and_module_path(
2541 DBusMessage
*message
, struct wpa_supplicant
*wpa_s
)
2543 DBusMessageIter iter
;
2545 char *pkcs11_engine_path
= NULL
;
2546 char *pkcs11_module_path
= NULL
;
2548 dbus_message_iter_init(message
, &iter
);
2549 dbus_message_iter_get_basic(&iter
, &value
);
2550 if (value
== NULL
) {
2551 return dbus_message_new_error(
2552 message
, DBUS_ERROR_INVALID_ARGS
,
2553 "Invalid pkcs11_engine_path argument");
2555 /* Empty path defaults to NULL */
2556 if (os_strlen(value
))
2557 pkcs11_engine_path
= value
;
2559 dbus_message_iter_next(&iter
);
2560 dbus_message_iter_get_basic(&iter
, &value
);
2561 if (value
== NULL
) {
2562 os_free(pkcs11_engine_path
);
2563 return dbus_message_new_error(
2564 message
, DBUS_ERROR_INVALID_ARGS
,
2565 "Invalid pkcs11_module_path argument");
2567 /* Empty path defaults to NULL */
2568 if (os_strlen(value
))
2569 pkcs11_module_path
= value
;
2571 if (wpas_set_pkcs11_engine_and_module_path(wpa_s
, pkcs11_engine_path
,
2572 pkcs11_module_path
))
2573 return dbus_message_new_error(
2574 message
, DBUS_ERROR_FAILED
,
2575 "Reinit of the EAPOL state machine with the new PKCS #11 engine and module path failed.");
2577 if (wpa_s
->dbus_new_path
) {
2578 wpa_dbus_mark_property_changed(
2579 wpa_s
->global
->dbus
, wpa_s
->dbus_new_path
,
2580 WPAS_DBUS_NEW_IFACE_INTERFACE
, "PKCS11EnginePath");
2581 wpa_dbus_mark_property_changed(
2582 wpa_s
->global
->dbus
, wpa_s
->dbus_new_path
,
2583 WPAS_DBUS_NEW_IFACE_INTERFACE
, "PKCS11ModulePath");
2591 * wpas_dbus_getter_capabilities - Return interface capabilities
2592 * @iter: Pointer to incoming dbus message iter
2593 * @error: Location to store error on failure
2594 * @user_data: Function specific data
2595 * Returns: TRUE on success, FALSE on failure
2597 * Getter for "Capabilities" property of an interface.
2599 dbus_bool_t
wpas_dbus_getter_capabilities(
2600 const struct wpa_dbus_property_desc
*property_desc
,
2601 DBusMessageIter
*iter
, DBusError
*error
, void *user_data
)
2603 struct wpa_supplicant
*wpa_s
= user_data
;
2604 struct wpa_driver_capa capa
;
2606 DBusMessageIter iter_dict
, iter_dict_entry
, iter_dict_val
, iter_array
,
2608 const char *scans
[] = { "active", "passive", "ssid" };
2610 if (!dbus_message_iter_open_container(iter
, DBUS_TYPE_VARIANT
,
2611 "a{sv}", &variant_iter
) ||
2612 !wpa_dbus_dict_open_write(&variant_iter
, &iter_dict
))
2615 res
= wpa_drv_get_capa(wpa_s
, &capa
);
2617 /***** pairwise cipher */
2619 const char *args
[] = {"ccmp", "tkip", "none"};
2621 if (!wpa_dbus_dict_append_string_array(
2622 &iter_dict
, "Pairwise", args
,
2626 if (!wpa_dbus_dict_begin_string_array(&iter_dict
, "Pairwise",
2630 ((capa
.enc
& WPA_DRIVER_CAPA_ENC_CCMP_256
) &&
2631 !wpa_dbus_dict_string_array_add_element(
2632 &iter_array
, "ccmp-256")) ||
2633 ((capa
.enc
& WPA_DRIVER_CAPA_ENC_GCMP_256
) &&
2634 !wpa_dbus_dict_string_array_add_element(
2635 &iter_array
, "gcmp-256")) ||
2636 ((capa
.enc
& WPA_DRIVER_CAPA_ENC_CCMP
) &&
2637 !wpa_dbus_dict_string_array_add_element(
2638 &iter_array
, "ccmp")) ||
2639 ((capa
.enc
& WPA_DRIVER_CAPA_ENC_GCMP
) &&
2640 !wpa_dbus_dict_string_array_add_element(
2641 &iter_array
, "gcmp")) ||
2642 ((capa
.enc
& WPA_DRIVER_CAPA_ENC_TKIP
) &&
2643 !wpa_dbus_dict_string_array_add_element(
2644 &iter_array
, "tkip")) ||
2645 ((capa
.key_mgmt
& WPA_DRIVER_CAPA_KEY_MGMT_WPA_NONE
) &&
2646 !wpa_dbus_dict_string_array_add_element(
2647 &iter_array
, "none")) ||
2648 !wpa_dbus_dict_end_string_array(&iter_dict
,
2655 /***** group cipher */
2657 const char *args
[] = {
2658 "ccmp", "tkip", "wep104", "wep40"
2661 if (!wpa_dbus_dict_append_string_array(
2662 &iter_dict
, "Group", args
,
2666 if (!wpa_dbus_dict_begin_string_array(&iter_dict
, "Group",
2670 ((capa
.enc
& WPA_DRIVER_CAPA_ENC_CCMP_256
) &&
2671 !wpa_dbus_dict_string_array_add_element(
2672 &iter_array
, "ccmp-256")) ||
2673 ((capa
.enc
& WPA_DRIVER_CAPA_ENC_GCMP_256
) &&
2674 !wpa_dbus_dict_string_array_add_element(
2675 &iter_array
, "gcmp-256")) ||
2676 ((capa
.enc
& WPA_DRIVER_CAPA_ENC_CCMP
) &&
2677 !wpa_dbus_dict_string_array_add_element(
2678 &iter_array
, "ccmp")) ||
2679 ((capa
.enc
& WPA_DRIVER_CAPA_ENC_GCMP
) &&
2680 !wpa_dbus_dict_string_array_add_element(
2681 &iter_array
, "gcmp")) ||
2682 ((capa
.enc
& WPA_DRIVER_CAPA_ENC_TKIP
) &&
2683 !wpa_dbus_dict_string_array_add_element(
2684 &iter_array
, "tkip")) ||
2685 ((capa
.enc
& WPA_DRIVER_CAPA_ENC_WEP104
) &&
2686 !wpa_dbus_dict_string_array_add_element(
2687 &iter_array
, "wep104")) ||
2688 ((capa
.enc
& WPA_DRIVER_CAPA_ENC_WEP40
) &&
2689 !wpa_dbus_dict_string_array_add_element(
2690 &iter_array
, "wep40")) ||
2691 !wpa_dbus_dict_end_string_array(&iter_dict
,
2698 if (!wpa_dbus_dict_begin_string_array(&iter_dict
, "GroupMgmt",
2702 (res
== 0 && (capa
.enc
& WPA_DRIVER_CAPA_ENC_BIP
) &&
2703 !wpa_dbus_dict_string_array_add_element(
2704 &iter_array
, "aes-128-cmac")) ||
2705 (res
== 0 && (capa
.enc
& WPA_DRIVER_CAPA_ENC_BIP_GMAC_128
) &&
2706 !wpa_dbus_dict_string_array_add_element(
2707 &iter_array
, "bip-gmac-128")) ||
2708 (res
== 0 && (capa
.enc
& WPA_DRIVER_CAPA_ENC_BIP_GMAC_256
) &&
2709 !wpa_dbus_dict_string_array_add_element(
2710 &iter_array
, "bip-gmac-256")) ||
2711 (res
== 0 && (capa
.enc
& WPA_DRIVER_CAPA_ENC_BIP_CMAC_256
) &&
2712 !wpa_dbus_dict_string_array_add_element(
2713 &iter_array
, "bip-cmac-256")) ||
2714 !wpa_dbus_dict_end_string_array(&iter_dict
,
2720 /***** key management */
2722 const char *args
[] = {
2723 "wpa-psk", "wpa-eap", "ieee8021x", "wpa-none",
2726 #endif /* CONFIG_WPS */
2729 if (!wpa_dbus_dict_append_string_array(
2730 &iter_dict
, "KeyMgmt", args
,
2734 if (!wpa_dbus_dict_begin_string_array(&iter_dict
, "KeyMgmt",
2738 !wpa_dbus_dict_string_array_add_element(&iter_array
,
2740 !wpa_dbus_dict_string_array_add_element(&iter_array
,
2744 if (capa
.key_mgmt
& (WPA_DRIVER_CAPA_KEY_MGMT_WPA
|
2745 WPA_DRIVER_CAPA_KEY_MGMT_WPA2
)) {
2746 if (!wpa_dbus_dict_string_array_add_element(
2747 &iter_array
, "wpa-eap") ||
2748 ((capa
.key_mgmt
& WPA_DRIVER_CAPA_KEY_MGMT_FT
) &&
2749 !wpa_dbus_dict_string_array_add_element(
2750 &iter_array
, "wpa-ft-eap")))
2753 /* TODO: Ensure that driver actually supports sha256 encryption. */
2754 if (!wpa_dbus_dict_string_array_add_element(
2755 &iter_array
, "wpa-eap-sha256"))
2759 if (capa
.key_mgmt
& (WPA_DRIVER_CAPA_KEY_MGMT_WPA_PSK
|
2760 WPA_DRIVER_CAPA_KEY_MGMT_WPA2_PSK
)) {
2761 if (!wpa_dbus_dict_string_array_add_element(
2762 &iter_array
, "wpa-psk") ||
2764 WPA_DRIVER_CAPA_KEY_MGMT_FT_PSK
) &&
2765 !wpa_dbus_dict_string_array_add_element(
2766 &iter_array
, "wpa-ft-psk")))
2769 /* TODO: Ensure that driver actually supports sha256 encryption. */
2770 if (!wpa_dbus_dict_string_array_add_element(
2771 &iter_array
, "wpa-psk-sha256"))
2775 if ((capa
.key_mgmt
& WPA_DRIVER_CAPA_KEY_MGMT_WPA_NONE
) &&
2776 !wpa_dbus_dict_string_array_add_element(&iter_array
,
2782 if (!wpa_dbus_dict_string_array_add_element(&iter_array
,
2785 #endif /* CONFIG_WPS */
2787 if (!wpa_dbus_dict_end_string_array(&iter_dict
,
2794 /***** WPA protocol */
2796 const char *args
[] = { "rsn", "wpa" };
2798 if (!wpa_dbus_dict_append_string_array(
2799 &iter_dict
, "Protocol", args
,
2803 if (!wpa_dbus_dict_begin_string_array(&iter_dict
, "Protocol",
2807 ((capa
.key_mgmt
& (WPA_DRIVER_CAPA_KEY_MGMT_WPA2
|
2808 WPA_DRIVER_CAPA_KEY_MGMT_WPA2_PSK
)) &&
2809 !wpa_dbus_dict_string_array_add_element(
2810 &iter_array
, "rsn")) ||
2811 ((capa
.key_mgmt
& (WPA_DRIVER_CAPA_KEY_MGMT_WPA
|
2812 WPA_DRIVER_CAPA_KEY_MGMT_WPA_PSK
)) &&
2813 !wpa_dbus_dict_string_array_add_element(
2814 &iter_array
, "wpa")) ||
2815 !wpa_dbus_dict_end_string_array(&iter_dict
,
2824 const char *args
[] = { "open", "shared", "leap" };
2826 if (!wpa_dbus_dict_append_string_array(
2827 &iter_dict
, "AuthAlg", args
,
2831 if (!wpa_dbus_dict_begin_string_array(&iter_dict
, "AuthAlg",
2837 if (((capa
.auth
& WPA_DRIVER_AUTH_OPEN
) &&
2838 !wpa_dbus_dict_string_array_add_element(
2839 &iter_array
, "open")) ||
2840 ((capa
.auth
& WPA_DRIVER_AUTH_SHARED
) &&
2841 !wpa_dbus_dict_string_array_add_element(
2842 &iter_array
, "shared")) ||
2843 ((capa
.auth
& WPA_DRIVER_AUTH_LEAP
) &&
2844 !wpa_dbus_dict_string_array_add_element(
2845 &iter_array
, "leap")) ||
2846 !wpa_dbus_dict_end_string_array(&iter_dict
,
2854 if (!wpa_dbus_dict_append_string_array(&iter_dict
, "Scan", scans
,
2859 if (!wpa_dbus_dict_begin_string_array(&iter_dict
, "Modes",
2863 !wpa_dbus_dict_string_array_add_element(
2864 &iter_array
, "infrastructure") ||
2865 (res
>= 0 && (capa
.flags
& WPA_DRIVER_FLAGS_IBSS
) &&
2866 !wpa_dbus_dict_string_array_add_element(
2867 &iter_array
, "ad-hoc")) ||
2868 (res
>= 0 && (capa
.flags
& WPA_DRIVER_FLAGS_AP
) &&
2869 !wpa_dbus_dict_string_array_add_element(
2870 &iter_array
, "ap")) ||
2871 (res
>= 0 && (capa
.flags
& WPA_DRIVER_FLAGS_P2P_CAPABLE
) &&
2872 !wpa_s
->conf
->p2p_disabled
&&
2873 !wpa_dbus_dict_string_array_add_element(
2874 &iter_array
, "p2p")) ||
2876 (res
>= 0 && (capa
.flags
& WPA_DRIVER_FLAGS_MESH
) &&
2877 !wpa_dbus_dict_string_array_add_element(
2878 &iter_array
, "mesh")) ||
2879 #endif /* CONFIG_MESH */
2880 !wpa_dbus_dict_end_string_array(&iter_dict
,
2888 dbus_int32_t max_scan_ssid
= capa
.max_scan_ssids
;
2890 if (!wpa_dbus_dict_append_int32(&iter_dict
, "MaxScanSSID",
2895 if (!wpa_dbus_dict_close_write(&variant_iter
, &iter_dict
) ||
2896 !dbus_message_iter_close_container(iter
, &variant_iter
))
2902 dbus_set_error_const(error
, DBUS_ERROR_NO_MEMORY
, "no memory");
2908 * wpas_dbus_getter_state - Get interface state
2909 * @iter: Pointer to incoming dbus message iter
2910 * @error: Location to store error on failure
2911 * @user_data: Function specific data
2912 * Returns: TRUE on success, FALSE on failure
2914 * Getter for "State" property.
2916 dbus_bool_t
wpas_dbus_getter_state(
2917 const struct wpa_dbus_property_desc
*property_desc
,
2918 DBusMessageIter
*iter
, DBusError
*error
, void *user_data
)
2920 struct wpa_supplicant
*wpa_s
= user_data
;
2921 const char *str_state
;
2922 char *state_ls
, *tmp
;
2923 dbus_bool_t success
= FALSE
;
2925 str_state
= wpa_supplicant_state_txt(wpa_s
->wpa_state
);
2927 /* make state string lowercase to fit new DBus API convention
2929 state_ls
= tmp
= os_strdup(str_state
);
2931 dbus_set_error_const(error
, DBUS_ERROR_NO_MEMORY
, "no memory");
2935 *tmp
= tolower(*tmp
);
2939 success
= wpas_dbus_simple_property_getter(iter
, DBUS_TYPE_STRING
,
2949 * wpas_dbus_new_iface_get_scanning - Get interface scanning state
2950 * @iter: Pointer to incoming dbus message iter
2951 * @error: Location to store error on failure
2952 * @user_data: Function specific data
2953 * Returns: TRUE on success, FALSE on failure
2955 * Getter for "scanning" property.
2957 dbus_bool_t
wpas_dbus_getter_scanning(
2958 const struct wpa_dbus_property_desc
*property_desc
,
2959 DBusMessageIter
*iter
, DBusError
*error
, void *user_data
)
2961 struct wpa_supplicant
*wpa_s
= user_data
;
2962 dbus_bool_t scanning
= wpa_s
->scanning
? TRUE
: FALSE
;
2964 return wpas_dbus_simple_property_getter(iter
, DBUS_TYPE_BOOLEAN
,
2970 * wpas_dbus_getter_ap_scan - Control roaming mode
2971 * @iter: Pointer to incoming dbus message iter
2972 * @error: Location to store error on failure
2973 * @user_data: Function specific data
2974 * Returns: TRUE on success, FALSE on failure
2976 * Getter function for "ApScan" property.
2978 dbus_bool_t
wpas_dbus_getter_ap_scan(
2979 const struct wpa_dbus_property_desc
*property_desc
,
2980 DBusMessageIter
*iter
, DBusError
*error
, void *user_data
)
2982 struct wpa_supplicant
*wpa_s
= user_data
;
2983 dbus_uint32_t ap_scan
= wpa_s
->conf
->ap_scan
;
2985 return wpas_dbus_simple_property_getter(iter
, DBUS_TYPE_UINT32
,
2991 * wpas_dbus_setter_ap_scan - Control roaming mode
2992 * @iter: Pointer to incoming dbus message iter
2993 * @error: Location to store error on failure
2994 * @user_data: Function specific data
2995 * Returns: TRUE on success, FALSE on failure
2997 * Setter function for "ApScan" property.
2999 dbus_bool_t
wpas_dbus_setter_ap_scan(
3000 const struct wpa_dbus_property_desc
*property_desc
,
3001 DBusMessageIter
*iter
, DBusError
*error
, void *user_data
)
3003 struct wpa_supplicant
*wpa_s
= user_data
;
3004 dbus_uint32_t ap_scan
;
3006 if (!wpas_dbus_simple_property_setter(iter
, error
, DBUS_TYPE_UINT32
,
3010 if (wpa_supplicant_set_ap_scan(wpa_s
, ap_scan
)) {
3011 dbus_set_error_const(error
, DBUS_ERROR_FAILED
,
3012 "ap_scan must be 0, 1, or 2");
3020 * wpas_dbus_getter_fast_reauth - Control fast
3021 * reauthentication (TLS session resumption)
3022 * @iter: Pointer to incoming dbus message iter
3023 * @error: Location to store error on failure
3024 * @user_data: Function specific data
3025 * Returns: TRUE on success, FALSE on failure
3027 * Getter function for "FastReauth" property.
3029 dbus_bool_t
wpas_dbus_getter_fast_reauth(
3030 const struct wpa_dbus_property_desc
*property_desc
,
3031 DBusMessageIter
*iter
, DBusError
*error
, void *user_data
)
3033 struct wpa_supplicant
*wpa_s
= user_data
;
3034 dbus_bool_t fast_reauth
= wpa_s
->conf
->fast_reauth
? TRUE
: FALSE
;
3036 return wpas_dbus_simple_property_getter(iter
, DBUS_TYPE_BOOLEAN
,
3037 &fast_reauth
, error
);
3042 * wpas_dbus_setter_fast_reauth - Control fast
3043 * reauthentication (TLS session resumption)
3044 * @iter: Pointer to incoming dbus message iter
3045 * @error: Location to store error on failure
3046 * @user_data: Function specific data
3047 * Returns: TRUE on success, FALSE on failure
3049 * Setter function for "FastReauth" property.
3051 dbus_bool_t
wpas_dbus_setter_fast_reauth(
3052 const struct wpa_dbus_property_desc
*property_desc
,
3053 DBusMessageIter
*iter
, DBusError
*error
, void *user_data
)
3055 struct wpa_supplicant
*wpa_s
= user_data
;
3056 dbus_bool_t fast_reauth
;
3058 if (!wpas_dbus_simple_property_setter(iter
, error
, DBUS_TYPE_BOOLEAN
,
3062 wpa_s
->conf
->fast_reauth
= fast_reauth
;
3068 * wpas_dbus_getter_disconnect_reason - Get most recent reason for disconnect
3069 * @iter: Pointer to incoming dbus message iter
3070 * @error: Location to store error on failure
3071 * @user_data: Function specific data
3072 * Returns: TRUE on success, FALSE on failure
3074 * Getter for "DisconnectReason" property. The reason is negative if it is
3075 * locally generated.
3077 dbus_bool_t
wpas_dbus_getter_disconnect_reason(
3078 const struct wpa_dbus_property_desc
*property_desc
,
3079 DBusMessageIter
*iter
, DBusError
*error
, void *user_data
)
3081 struct wpa_supplicant
*wpa_s
= user_data
;
3082 dbus_int32_t reason
= wpa_s
->disconnect_reason
;
3084 return wpas_dbus_simple_property_getter(iter
, DBUS_TYPE_INT32
,
3090 * wpas_dbus_getter_auth_status_code - Get most recent auth status code
3091 * @iter: Pointer to incoming dbus message iter
3092 * @error: Location to store error on failure
3093 * @user_data: Function specific data
3094 * Returns: TRUE on success, FALSE on failure
3096 * Getter for "AuthStatusCode" property.
3098 dbus_bool_t
wpas_dbus_getter_auth_status_code(
3099 const struct wpa_dbus_property_desc
*property_desc
,
3100 DBusMessageIter
*iter
, DBusError
*error
, void *user_data
)
3102 struct wpa_supplicant
*wpa_s
= user_data
;
3103 dbus_int32_t reason
= wpa_s
->auth_status_code
;
3105 return wpas_dbus_simple_property_getter(iter
, DBUS_TYPE_INT32
,
3111 * wpas_dbus_getter_assoc_status_code - Get most recent failed assoc status code
3112 * @iter: Pointer to incoming dbus message iter
3113 * @error: Location to store error on failure
3114 * @user_data: Function specific data
3115 * Returns: TRUE on success, FALSE on failure
3117 * Getter for "AssocStatusCode" property.
3119 dbus_bool_t
wpas_dbus_getter_assoc_status_code(
3120 const struct wpa_dbus_property_desc
*property_desc
,
3121 DBusMessageIter
*iter
, DBusError
*error
, void *user_data
)
3123 struct wpa_supplicant
*wpa_s
= user_data
;
3124 dbus_int32_t status_code
= wpa_s
->assoc_status_code
;
3126 return wpas_dbus_simple_property_getter(iter
, DBUS_TYPE_INT32
,
3127 &status_code
, error
);
3132 * wpas_dbus_getter_roam_time - Get most recent roam time
3133 * @iter: Pointer to incoming dbus message iter
3134 * @error: Location to store error on failure
3135 * @user_data: Function specific data
3136 * Returns: TRUE on success, FALSE on failure
3138 * Getter for "RoamTime" property.
3140 dbus_bool_t
wpas_dbus_getter_roam_time(
3141 const struct wpa_dbus_property_desc
*property_desc
,
3142 DBusMessageIter
*iter
, DBusError
*error
, void *user_data
)
3144 struct wpa_supplicant
*wpa_s
= user_data
;
3145 dbus_uint32_t roam_time
= wpa_s
->roam_time
.sec
* 1000 +
3146 wpa_s
->roam_time
.usec
/ 1000;
3148 return wpas_dbus_simple_property_getter(iter
, DBUS_TYPE_UINT32
,
3154 * wpas_dbus_getter_roam_complete - Get most recent roam success or failure
3155 * @iter: Pointer to incoming dbus message iter
3156 * @error: Location to store error on failure
3157 * @user_data: Function specific data
3158 * Returns: TRUE on success, FALSE on failure
3160 * Getter for "RoamComplete" property.
3162 dbus_bool_t
wpas_dbus_getter_roam_complete(
3163 const struct wpa_dbus_property_desc
*property_desc
,
3164 DBusMessageIter
*iter
, DBusError
*error
, void *user_data
)
3166 struct wpa_supplicant
*wpa_s
= user_data
;
3167 dbus_bool_t roam_complete
= os_reltime_initialized(&wpa_s
->roam_time
);
3169 return wpas_dbus_simple_property_getter(iter
, DBUS_TYPE_BOOLEAN
,
3170 &roam_complete
, error
);
3175 * wpas_dbus_getter_session_length - Get most recent BSS session length
3176 * @iter: Pointer to incoming dbus message iter
3177 * @error: Location to store error on failure
3178 * @user_data: Function specific data
3179 * Returns: TRUE on success, FALSE on failure
3181 * Getter for "SessionLength" property.
3183 dbus_bool_t
wpas_dbus_getter_session_length(
3184 const struct wpa_dbus_property_desc
*property_desc
,
3185 DBusMessageIter
*iter
, DBusError
*error
, void *user_data
)
3187 struct wpa_supplicant
*wpa_s
= user_data
;
3188 dbus_uint32_t session_length
= wpa_s
->session_length
.sec
* 1000 +
3189 wpa_s
->session_length
.usec
/ 1000;
3191 return wpas_dbus_simple_property_getter(iter
, DBUS_TYPE_UINT32
,
3192 &session_length
, error
);
3197 * wpas_dbus_getter_bss_tm_status - Get most BSS Transition Management request
3199 * @iter: Pointer to incoming dbus message iter
3200 * @error: Location to store error on failure
3201 * @user_data: Function specific data
3202 * Returns: TRUE on success, FALSE on failure
3204 * Getter for "BSSTMStatus" property.
3206 dbus_bool_t
wpas_dbus_getter_bss_tm_status(
3207 const struct wpa_dbus_property_desc
*property_desc
,
3208 DBusMessageIter
*iter
, DBusError
*error
, void *user_data
)
3211 struct wpa_supplicant
*wpa_s
= user_data
;
3212 dbus_uint32_t bss_tm_status
= wpa_s
->bss_tm_status
;
3213 #else /* CONFIG_WNM */
3214 dbus_uint32_t bss_tm_status
= 0;
3215 #endif /* CONFIG_WNM */
3217 return wpas_dbus_simple_property_getter(iter
, DBUS_TYPE_UINT32
,
3218 &bss_tm_status
, error
);
3223 * wpas_dbus_getter_bss_expire_age - Get BSS entry expiration age
3224 * @iter: Pointer to incoming dbus message iter
3225 * @error: Location to store error on failure
3226 * @user_data: Function specific data
3227 * Returns: TRUE on success, FALSE on failure
3229 * Getter function for "BSSExpireAge" property.
3231 dbus_bool_t
wpas_dbus_getter_bss_expire_age(
3232 const struct wpa_dbus_property_desc
*property_desc
,
3233 DBusMessageIter
*iter
, DBusError
*error
, void *user_data
)
3235 struct wpa_supplicant
*wpa_s
= user_data
;
3236 dbus_uint32_t expire_age
= wpa_s
->conf
->bss_expiration_age
;
3238 return wpas_dbus_simple_property_getter(iter
, DBUS_TYPE_UINT32
,
3239 &expire_age
, error
);
3244 * wpas_dbus_setter_bss_expire_age - Control BSS entry expiration age
3245 * @iter: Pointer to incoming dbus message iter
3246 * @error: Location to store error on failure
3247 * @user_data: Function specific data
3248 * Returns: TRUE on success, FALSE on failure
3250 * Setter function for "BSSExpireAge" property.
3252 dbus_bool_t
wpas_dbus_setter_bss_expire_age(
3253 const struct wpa_dbus_property_desc
*property_desc
,
3254 DBusMessageIter
*iter
, DBusError
*error
, void *user_data
)
3256 struct wpa_supplicant
*wpa_s
= user_data
;
3257 dbus_uint32_t expire_age
;
3259 if (!wpas_dbus_simple_property_setter(iter
, error
, DBUS_TYPE_UINT32
,
3263 if (wpa_supplicant_set_bss_expiration_age(wpa_s
, expire_age
)) {
3264 dbus_set_error_const(error
, DBUS_ERROR_FAILED
,
3265 "BSSExpireAge must be >= 10");
3273 * wpas_dbus_getter_bss_expire_count - Get BSS entry expiration scan count
3274 * @iter: Pointer to incoming dbus message iter
3275 * @error: Location to store error on failure
3276 * @user_data: Function specific data
3277 * Returns: TRUE on success, FALSE on failure
3279 * Getter function for "BSSExpireCount" property.
3281 dbus_bool_t
wpas_dbus_getter_bss_expire_count(
3282 const struct wpa_dbus_property_desc
*property_desc
,
3283 DBusMessageIter
*iter
, DBusError
*error
, void *user_data
)
3285 struct wpa_supplicant
*wpa_s
= user_data
;
3286 dbus_uint32_t expire_count
= wpa_s
->conf
->bss_expiration_scan_count
;
3288 return wpas_dbus_simple_property_getter(iter
, DBUS_TYPE_UINT32
,
3289 &expire_count
, error
);
3294 * wpas_dbus_setter_bss_expire_count - Control BSS entry expiration scan count
3295 * @iter: Pointer to incoming dbus message iter
3296 * @error: Location to store error on failure
3297 * @user_data: Function specific data
3298 * Returns: TRUE on success, FALSE on failure
3300 * Setter function for "BSSExpireCount" property.
3302 dbus_bool_t
wpas_dbus_setter_bss_expire_count(
3303 const struct wpa_dbus_property_desc
*property_desc
,
3304 DBusMessageIter
*iter
, DBusError
*error
, void *user_data
)
3306 struct wpa_supplicant
*wpa_s
= user_data
;
3307 dbus_uint32_t expire_count
;
3309 if (!wpas_dbus_simple_property_setter(iter
, error
, DBUS_TYPE_UINT32
,
3313 if (wpa_supplicant_set_bss_expiration_count(wpa_s
, expire_count
)) {
3314 dbus_set_error_const(error
, DBUS_ERROR_FAILED
,
3315 "BSSExpireCount must be > 0");
3323 * wpas_dbus_getter_country - Control country code
3324 * @iter: Pointer to incoming dbus message iter
3325 * @error: Location to store error on failure
3326 * @user_data: Function specific data
3327 * Returns: TRUE on success, FALSE on failure
3329 * Getter function for "Country" property.
3331 dbus_bool_t
wpas_dbus_getter_country(
3332 const struct wpa_dbus_property_desc
*property_desc
,
3333 DBusMessageIter
*iter
, DBusError
*error
, void *user_data
)
3335 struct wpa_supplicant
*wpa_s
= user_data
;
3337 char *str
= country
;
3339 country
[0] = wpa_s
->conf
->country
[0];
3340 country
[1] = wpa_s
->conf
->country
[1];
3343 return wpas_dbus_simple_property_getter(iter
, DBUS_TYPE_STRING
,
3349 * wpas_dbus_setter_country - Control country code
3350 * @iter: Pointer to incoming dbus message iter
3351 * @error: Location to store error on failure
3352 * @user_data: Function specific data
3353 * Returns: TRUE on success, FALSE on failure
3355 * Setter function for "Country" property.
3357 dbus_bool_t
wpas_dbus_setter_country(
3358 const struct wpa_dbus_property_desc
*property_desc
,
3359 DBusMessageIter
*iter
, DBusError
*error
, void *user_data
)
3361 struct wpa_supplicant
*wpa_s
= user_data
;
3362 const char *country
;
3364 if (!wpas_dbus_simple_property_setter(iter
, error
, DBUS_TYPE_STRING
,
3368 if (!country
[0] || !country
[1]) {
3369 dbus_set_error_const(error
, DBUS_ERROR_FAILED
,
3370 "invalid country code");
3374 if (wpa_s
->drv_priv
!= NULL
&& wpa_drv_set_country(wpa_s
, country
)) {
3375 wpa_printf(MSG_DEBUG
, "Failed to set country");
3376 dbus_set_error_const(error
, DBUS_ERROR_FAILED
,
3377 "failed to set country code");
3381 wpa_s
->conf
->country
[0] = country
[0];
3382 wpa_s
->conf
->country
[1] = country
[1];
3388 * wpas_dbus_getter_scan_interval - Get scan interval
3389 * @iter: Pointer to incoming dbus message iter
3390 * @error: Location to store error on failure
3391 * @user_data: Function specific data
3392 * Returns: TRUE on success, FALSE on failure
3394 * Getter function for "ScanInterval" property.
3396 dbus_bool_t
wpas_dbus_getter_scan_interval(
3397 const struct wpa_dbus_property_desc
*property_desc
,
3398 DBusMessageIter
*iter
, DBusError
*error
, void *user_data
)
3400 struct wpa_supplicant
*wpa_s
= user_data
;
3401 dbus_int32_t scan_interval
= wpa_s
->scan_interval
;
3403 return wpas_dbus_simple_property_getter(iter
, DBUS_TYPE_INT32
,
3404 &scan_interval
, error
);
3409 * wpas_dbus_setter_scan_interval - Control scan interval
3410 * @iter: Pointer to incoming dbus message iter
3411 * @error: Location to store error on failure
3412 * @user_data: Function specific data
3413 * Returns: TRUE on success, FALSE on failure
3415 * Setter function for "ScanInterval" property.
3417 dbus_bool_t
wpas_dbus_setter_scan_interval(
3418 const struct wpa_dbus_property_desc
*property_desc
,
3419 DBusMessageIter
*iter
, DBusError
*error
, void *user_data
)
3421 struct wpa_supplicant
*wpa_s
= user_data
;
3422 dbus_int32_t scan_interval
;
3424 if (!wpas_dbus_simple_property_setter(iter
, error
, DBUS_TYPE_INT32
,
3428 if (wpa_supplicant_set_scan_interval(wpa_s
, scan_interval
)) {
3429 dbus_set_error_const(error
, DBUS_ERROR_FAILED
,
3430 "scan_interval must be >= 0");
3438 * wpas_dbus_getter_ifname - Get interface name
3439 * @iter: Pointer to incoming dbus message iter
3440 * @error: Location to store error on failure
3441 * @user_data: Function specific data
3442 * Returns: TRUE on success, FALSE on failure
3444 * Getter for "Ifname" property.
3446 dbus_bool_t
wpas_dbus_getter_ifname(
3447 const struct wpa_dbus_property_desc
*property_desc
,
3448 DBusMessageIter
*iter
, DBusError
*error
, void *user_data
)
3450 struct wpa_supplicant
*wpa_s
= user_data
;
3452 return wpas_dbus_string_property_getter(iter
, wpa_s
->ifname
, error
);
3457 * wpas_dbus_getter_driver - Get interface name
3458 * @iter: Pointer to incoming dbus message iter
3459 * @error: Location to store error on failure
3460 * @user_data: Function specific data
3461 * Returns: TRUE on success, FALSE on failure
3463 * Getter for "Driver" property.
3465 dbus_bool_t
wpas_dbus_getter_driver(
3466 const struct wpa_dbus_property_desc
*property_desc
,
3467 DBusMessageIter
*iter
, DBusError
*error
, void *user_data
)
3469 struct wpa_supplicant
*wpa_s
= user_data
;
3471 if (wpa_s
->driver
== NULL
|| wpa_s
->driver
->name
== NULL
) {
3472 wpa_printf(MSG_DEBUG
, "%s[dbus]: wpa_s has no driver set",
3474 dbus_set_error(error
, DBUS_ERROR_FAILED
, "%s: no driver set",
3479 return wpas_dbus_string_property_getter(iter
, wpa_s
->driver
->name
,
3485 * wpas_dbus_getter_current_bss - Get current bss object path
3486 * @iter: Pointer to incoming dbus message iter
3487 * @error: Location to store error on failure
3488 * @user_data: Function specific data
3489 * Returns: TRUE on success, FALSE on failure
3491 * Getter for "CurrentBSS" property.
3493 dbus_bool_t
wpas_dbus_getter_current_bss(
3494 const struct wpa_dbus_property_desc
*property_desc
,
3495 DBusMessageIter
*iter
, DBusError
*error
, void *user_data
)
3497 struct wpa_supplicant
*wpa_s
= user_data
;
3498 char path_buf
[WPAS_DBUS_OBJECT_PATH_MAX
], *bss_obj_path
= path_buf
;
3500 if (wpa_s
->current_bss
&& wpa_s
->dbus_new_path
)
3501 os_snprintf(bss_obj_path
, WPAS_DBUS_OBJECT_PATH_MAX
,
3502 "%s/" WPAS_DBUS_NEW_BSSIDS_PART
"/%u",
3503 wpa_s
->dbus_new_path
, wpa_s
->current_bss
->id
);
3505 os_snprintf(bss_obj_path
, WPAS_DBUS_OBJECT_PATH_MAX
, "/");
3507 return wpas_dbus_simple_property_getter(iter
, DBUS_TYPE_OBJECT_PATH
,
3508 &bss_obj_path
, error
);
3513 * wpas_dbus_getter_current_network - Get current network object path
3514 * @iter: Pointer to incoming dbus message iter
3515 * @error: Location to store error on failure
3516 * @user_data: Function specific data
3517 * Returns: TRUE on success, FALSE on failure
3519 * Getter for "CurrentNetwork" property.
3521 dbus_bool_t
wpas_dbus_getter_current_network(
3522 const struct wpa_dbus_property_desc
*property_desc
,
3523 DBusMessageIter
*iter
, DBusError
*error
, void *user_data
)
3525 struct wpa_supplicant
*wpa_s
= user_data
;
3526 char path_buf
[WPAS_DBUS_OBJECT_PATH_MAX
], *net_obj_path
= path_buf
;
3528 if (wpa_s
->current_ssid
&& wpa_s
->dbus_new_path
)
3529 os_snprintf(net_obj_path
, WPAS_DBUS_OBJECT_PATH_MAX
,
3530 "%s/" WPAS_DBUS_NEW_NETWORKS_PART
"/%u",
3531 wpa_s
->dbus_new_path
, wpa_s
->current_ssid
->id
);
3533 os_snprintf(net_obj_path
, WPAS_DBUS_OBJECT_PATH_MAX
, "/");
3535 return wpas_dbus_simple_property_getter(iter
, DBUS_TYPE_OBJECT_PATH
,
3536 &net_obj_path
, error
);
3541 * wpas_dbus_getter_current_auth_mode - Get current authentication type
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 "CurrentAuthMode" property.
3549 dbus_bool_t
wpas_dbus_getter_current_auth_mode(
3550 const struct wpa_dbus_property_desc
*property_desc
,
3551 DBusMessageIter
*iter
, DBusError
*error
, void *user_data
)
3553 struct wpa_supplicant
*wpa_s
= user_data
;
3554 const char *eap_mode
;
3555 const char *auth_mode
;
3556 char eap_mode_buf
[WPAS_DBUS_AUTH_MODE_MAX
];
3558 if (wpa_s
->wpa_state
!= WPA_COMPLETED
) {
3559 auth_mode
= "INACTIVE";
3560 } else if (wpa_s
->key_mgmt
== WPA_KEY_MGMT_IEEE8021X
||
3561 wpa_s
->key_mgmt
== WPA_KEY_MGMT_IEEE8021X_NO_WPA
) {
3562 eap_mode
= wpa_supplicant_get_eap_mode(wpa_s
);
3563 os_snprintf(eap_mode_buf
, WPAS_DBUS_AUTH_MODE_MAX
,
3564 "EAP-%s", eap_mode
);
3565 auth_mode
= eap_mode_buf
;
3567 } else if (wpa_s
->current_ssid
) {
3568 auth_mode
= wpa_key_mgmt_txt(wpa_s
->key_mgmt
,
3569 wpa_s
->current_ssid
->proto
);
3571 auth_mode
= "UNKNOWN";
3574 return wpas_dbus_simple_property_getter(iter
, DBUS_TYPE_STRING
,
3580 * wpas_dbus_getter_bridge_ifname - Get interface name
3581 * @iter: Pointer to incoming dbus message iter
3582 * @error: Location to store error on failure
3583 * @user_data: Function specific data
3584 * Returns: TRUE on success, FALSE on failure
3586 * Getter for "BridgeIfname" property.
3588 dbus_bool_t
wpas_dbus_getter_bridge_ifname(
3589 const struct wpa_dbus_property_desc
*property_desc
,
3590 DBusMessageIter
*iter
, DBusError
*error
, void *user_data
)
3592 struct wpa_supplicant
*wpa_s
= user_data
;
3594 return wpas_dbus_string_property_getter(iter
, wpa_s
->bridge_ifname
,
3600 * wpas_dbus_getter_config_file - Get interface configuration file path
3601 * @iter: Pointer to incoming dbus message iter
3602 * @error: Location to store error on failure
3603 * @user_data: Function specific data
3604 * Returns: TRUE on success, FALSE on failure
3606 * Getter for "ConfigFile" property.
3608 dbus_bool_t
wpas_dbus_getter_config_file(
3609 const struct wpa_dbus_property_desc
*property_desc
,
3610 DBusMessageIter
*iter
, DBusError
*error
, void *user_data
)
3612 struct wpa_supplicant
*wpa_s
= user_data
;
3614 return wpas_dbus_string_property_getter(iter
, wpa_s
->confname
, error
);
3619 * wpas_dbus_getter_bsss - Get array of BSSs objects
3620 * @iter: Pointer to incoming dbus message iter
3621 * @error: Location to store error on failure
3622 * @user_data: Function specific data
3623 * Returns: TRUE on success, FALSE on failure
3625 * Getter for "BSSs" property.
3627 dbus_bool_t
wpas_dbus_getter_bsss(
3628 const struct wpa_dbus_property_desc
*property_desc
,
3629 DBusMessageIter
*iter
, DBusError
*error
, void *user_data
)
3631 struct wpa_supplicant
*wpa_s
= user_data
;
3632 struct wpa_bss
*bss
;
3635 dbus_bool_t success
= FALSE
;
3637 if (!wpa_s
->dbus_new_path
) {
3638 dbus_set_error(error
, DBUS_ERROR_FAILED
,
3639 "%s: no D-Bus interface", __func__
);
3643 paths
= os_calloc(wpa_s
->num_bss
, sizeof(char *));
3645 dbus_set_error_const(error
, DBUS_ERROR_NO_MEMORY
, "no memory");
3649 /* Loop through scan results and append each result's object path */
3650 dl_list_for_each(bss
, &wpa_s
->bss_id
, struct wpa_bss
, list_id
) {
3651 paths
[i
] = os_zalloc(WPAS_DBUS_OBJECT_PATH_MAX
);
3652 if (paths
[i
] == NULL
) {
3653 dbus_set_error_const(error
, DBUS_ERROR_NO_MEMORY
,
3657 /* Construct the object path for this BSS. */
3658 os_snprintf(paths
[i
++], WPAS_DBUS_OBJECT_PATH_MAX
,
3659 "%s/" WPAS_DBUS_NEW_BSSIDS_PART
"/%u",
3660 wpa_s
->dbus_new_path
, bss
->id
);
3663 success
= wpas_dbus_simple_array_property_getter(iter
,
3664 DBUS_TYPE_OBJECT_PATH
,
3665 paths
, wpa_s
->num_bss
,
3670 os_free(paths
[--i
]);
3677 * wpas_dbus_getter_networks - Get array of networks objects
3678 * @iter: Pointer to incoming dbus message iter
3679 * @error: Location to store error on failure
3680 * @user_data: Function specific data
3681 * Returns: TRUE on success, FALSE on failure
3683 * Getter for "Networks" property.
3685 dbus_bool_t
wpas_dbus_getter_networks(
3686 const struct wpa_dbus_property_desc
*property_desc
,
3687 DBusMessageIter
*iter
, DBusError
*error
, void *user_data
)
3689 struct wpa_supplicant
*wpa_s
= user_data
;
3690 struct wpa_ssid
*ssid
;
3692 unsigned int i
= 0, num
= 0;
3693 dbus_bool_t success
= FALSE
;
3695 if (!wpa_s
->dbus_new_path
) {
3696 dbus_set_error(error
, DBUS_ERROR_FAILED
,
3697 "%s: no D-Bus interface", __func__
);
3701 for (ssid
= wpa_s
->conf
->ssid
; ssid
; ssid
= ssid
->next
)
3702 if (!network_is_persistent_group(ssid
))
3705 paths
= os_calloc(num
, sizeof(char *));
3707 dbus_set_error(error
, DBUS_ERROR_NO_MEMORY
, "no memory");
3711 /* Loop through configured networks and append object path of each */
3712 for (ssid
= wpa_s
->conf
->ssid
; ssid
; ssid
= ssid
->next
) {
3713 if (network_is_persistent_group(ssid
))
3715 paths
[i
] = os_zalloc(WPAS_DBUS_OBJECT_PATH_MAX
);
3716 if (paths
[i
] == NULL
) {
3717 dbus_set_error(error
, DBUS_ERROR_NO_MEMORY
,
3722 /* Construct the object path for this network. */
3723 os_snprintf(paths
[i
++], WPAS_DBUS_OBJECT_PATH_MAX
,
3724 "%s/" WPAS_DBUS_NEW_NETWORKS_PART
"/%d",
3725 wpa_s
->dbus_new_path
, ssid
->id
);
3728 success
= wpas_dbus_simple_array_property_getter(iter
,
3729 DBUS_TYPE_OBJECT_PATH
,
3734 os_free(paths
[--i
]);
3741 * wpas_dbus_getter_pkcs11_engine_path - Get PKCS #11 engine path
3742 * @iter: Pointer to incoming dbus message iter
3743 * @error: Location to store error on failure
3744 * @user_data: Function specific data
3745 * Returns: A dbus message containing the PKCS #11 engine path
3747 * Getter for "PKCS11EnginePath" property.
3749 dbus_bool_t
wpas_dbus_getter_pkcs11_engine_path(
3750 const struct wpa_dbus_property_desc
*property_desc
,
3751 DBusMessageIter
*iter
, DBusError
*error
, void *user_data
)
3753 struct wpa_supplicant
*wpa_s
= user_data
;
3755 return wpas_dbus_string_property_getter(iter
,
3756 wpa_s
->conf
->pkcs11_engine_path
,
3762 * wpas_dbus_getter_pkcs11_module_path - Get PKCS #11 module path
3763 * @iter: Pointer to incoming dbus message iter
3764 * @error: Location to store error on failure
3765 * @user_data: Function specific data
3766 * Returns: A dbus message containing the PKCS #11 module path
3768 * Getter for "PKCS11ModulePath" property.
3770 dbus_bool_t
wpas_dbus_getter_pkcs11_module_path(
3771 const struct wpa_dbus_property_desc
*property_desc
,
3772 DBusMessageIter
*iter
, DBusError
*error
, void *user_data
)
3774 struct wpa_supplicant
*wpa_s
= user_data
;
3776 return wpas_dbus_string_property_getter(iter
,
3777 wpa_s
->conf
->pkcs11_module_path
,
3783 * wpas_dbus_getter_blobs - Get all blobs defined for this interface
3784 * @iter: Pointer to incoming dbus message iter
3785 * @error: Location to store error on failure
3786 * @user_data: Function specific data
3787 * Returns: TRUE on success, FALSE on failure
3789 * Getter for "Blobs" property.
3791 dbus_bool_t
wpas_dbus_getter_blobs(
3792 const struct wpa_dbus_property_desc
*property_desc
,
3793 DBusMessageIter
*iter
, DBusError
*error
, void *user_data
)
3795 struct wpa_supplicant
*wpa_s
= user_data
;
3796 DBusMessageIter variant_iter
, dict_iter
, entry_iter
, array_iter
;
3797 struct wpa_config_blob
*blob
;
3799 if (!dbus_message_iter_open_container(iter
, DBUS_TYPE_VARIANT
,
3800 "a{say}", &variant_iter
) ||
3801 !dbus_message_iter_open_container(&variant_iter
, DBUS_TYPE_ARRAY
,
3802 "{say}", &dict_iter
)) {
3803 dbus_set_error_const(error
, DBUS_ERROR_NO_MEMORY
, "no memory");
3807 blob
= wpa_s
->conf
->blobs
;
3809 if (!dbus_message_iter_open_container(&dict_iter
,
3810 DBUS_TYPE_DICT_ENTRY
,
3811 NULL
, &entry_iter
) ||
3812 !dbus_message_iter_append_basic(&entry_iter
,
3815 !dbus_message_iter_open_container(&entry_iter
,
3817 DBUS_TYPE_BYTE_AS_STRING
,
3819 !dbus_message_iter_append_fixed_array(&array_iter
,
3823 !dbus_message_iter_close_container(&entry_iter
,
3825 !dbus_message_iter_close_container(&dict_iter
,
3827 dbus_set_error_const(error
, DBUS_ERROR_NO_MEMORY
,
3835 if (!dbus_message_iter_close_container(&variant_iter
, &dict_iter
) ||
3836 !dbus_message_iter_close_container(iter
, &variant_iter
)) {
3837 dbus_set_error_const(error
, DBUS_ERROR_NO_MEMORY
, "no memory");
3845 dbus_bool_t
wpas_dbus_getter_iface_global(
3846 const struct wpa_dbus_property_desc
*property_desc
,
3847 DBusMessageIter
*iter
, DBusError
*error
, void *user_data
)
3849 struct wpa_supplicant
*wpa_s
= user_data
;
3854 if (!property_desc
->data
) {
3855 dbus_set_error(error
, DBUS_ERROR_INVALID_ARGS
,
3856 "Unhandled interface property %s",
3857 property_desc
->dbus_property
);
3861 ret
= wpa_config_get_value(property_desc
->data
, wpa_s
->conf
, buf
,
3866 return wpas_dbus_simple_property_getter(iter
, DBUS_TYPE_STRING
, &p
,
3871 dbus_bool_t
wpas_dbus_setter_iface_global(
3872 const struct wpa_dbus_property_desc
*property_desc
,
3873 DBusMessageIter
*iter
, DBusError
*error
, void *user_data
)
3875 struct wpa_supplicant
*wpa_s
= user_data
;
3876 const char *new_value
= NULL
;
3878 size_t combined_len
;
3881 if (!wpas_dbus_simple_property_setter(iter
, error
, DBUS_TYPE_STRING
,
3885 combined_len
= os_strlen(property_desc
->data
) + os_strlen(new_value
) +
3887 if (combined_len
>= sizeof(buf
)) {
3888 dbus_set_error(error
, DBUS_ERROR_INVALID_ARGS
,
3889 "Interface property %s value too large",
3890 property_desc
->dbus_property
);
3897 ret
= os_snprintf(buf
, combined_len
, "%s=%s", property_desc
->data
,
3899 if (os_snprintf_error(combined_len
, ret
)) {
3900 dbus_set_error(error
, WPAS_DBUS_ERROR_UNKNOWN_ERROR
,
3901 "Failed to construct new interface property %s",
3902 property_desc
->dbus_property
);
3906 if (wpa_config_process_global(wpa_s
->conf
, buf
, -1)) {
3907 dbus_set_error(error
, DBUS_ERROR_INVALID_ARGS
,
3908 "Failed to set interface property %s",
3909 property_desc
->dbus_property
);
3913 wpa_supplicant_update_config(wpa_s
);
3919 * wpas_dbus_getter_stas - Get connected stations for an interface
3920 * @iter: Pointer to incoming dbus message iter
3921 * @error: Location to store error on failure
3922 * @user_data: Function specific data
3923 * Returns: a list of stations
3925 * Getter for "Stations" property.
3927 dbus_bool_t
wpas_dbus_getter_stas(
3928 const struct wpa_dbus_property_desc
*property_desc
,
3929 DBusMessageIter
*iter
, DBusError
*error
, void *user_data
)
3931 struct wpa_supplicant
*wpa_s
= user_data
;
3932 struct sta_info
*sta
= NULL
;
3933 char **paths
= NULL
;
3934 unsigned int i
= 0, num
= 0;
3935 dbus_bool_t success
= FALSE
;
3937 if (!wpa_s
->dbus_new_path
) {
3938 dbus_set_error(error
, DBUS_ERROR_FAILED
,
3939 "%s: no D-Bus interface", __func__
);
3944 if (wpa_s
->ap_iface
) {
3945 struct hostapd_data
*hapd
;
3947 hapd
= wpa_s
->ap_iface
->bss
[0];
3948 sta
= hapd
->sta_list
;
3949 num
= hapd
->num_sta
;
3951 #endif /* CONFIG_AP */
3953 paths
= os_calloc(num
, sizeof(char *));
3955 dbus_set_error_const(error
, DBUS_ERROR_NO_MEMORY
, "no memory");
3959 /* Loop through scan results and append each result's object path */
3960 for (; sta
; sta
= sta
->next
) {
3961 paths
[i
] = os_zalloc(WPAS_DBUS_OBJECT_PATH_MAX
);
3963 dbus_set_error_const(error
, DBUS_ERROR_NO_MEMORY
,
3967 /* Construct the object path for this BSS. */
3968 os_snprintf(paths
[i
++], WPAS_DBUS_OBJECT_PATH_MAX
,
3969 "%s/" WPAS_DBUS_NEW_STAS_PART
"/" COMPACT_MACSTR
,
3970 wpa_s
->dbus_new_path
, MAC2STR(sta
->addr
));
3973 success
= wpas_dbus_simple_array_property_getter(iter
,
3974 DBUS_TYPE_OBJECT_PATH
,
3980 os_free(paths
[--i
]);
3987 * wpas_dbus_getter_sta_address - Return the address of a connected station
3988 * @iter: Pointer to incoming dbus message iter
3989 * @error: Location to store error on failure
3990 * @user_data: Function specific data
3991 * Returns: TRUE on success, FALSE on failure
3993 * Getter for "Address" property.
3995 dbus_bool_t
wpas_dbus_getter_sta_address(
3996 const struct wpa_dbus_property_desc
*property_desc
,
3997 DBusMessageIter
*iter
, DBusError
*error
, void *user_data
)
4000 struct sta_handler_args
*args
= user_data
;
4001 struct sta_info
*sta
;
4003 sta
= ap_get_sta(args
->wpa_s
->ap_iface
->bss
[0], args
->sta
);
4007 return wpas_dbus_simple_array_property_getter(iter
, DBUS_TYPE_BYTE
,
4008 sta
->addr
, ETH_ALEN
,
4010 #else /* CONFIG_AP */
4012 #endif /* CONFIG_AP */
4017 * wpas_dbus_getter_sta_aid - Return the AID of a connected station
4018 * @iter: Pointer to incoming dbus message iter
4019 * @error: Location to store error on failure
4020 * @user_data: Function specific data
4021 * Returns: TRUE on success, FALSE on failure
4023 * Getter for "AID" property.
4025 dbus_bool_t
wpas_dbus_getter_sta_aid(
4026 const struct wpa_dbus_property_desc
*property_desc
,
4027 DBusMessageIter
*iter
, DBusError
*error
, void *user_data
)
4030 struct sta_handler_args
*args
= user_data
;
4031 struct sta_info
*sta
;
4033 sta
= ap_get_sta(args
->wpa_s
->ap_iface
->bss
[0], args
->sta
);
4037 return wpas_dbus_simple_property_getter(iter
, DBUS_TYPE_UINT16
,
4040 #else /* CONFIG_AP */
4042 #endif /* CONFIG_AP */
4047 * wpas_dbus_getter_sta_caps - Return the capabilities of a station
4048 * @iter: Pointer to incoming dbus message iter
4049 * @error: Location to store error on failure
4050 * @user_data: Function specific data
4051 * Returns: TRUE on success, FALSE on failure
4053 * Getter for "Capabilities" property.
4055 dbus_bool_t
wpas_dbus_getter_sta_caps(
4056 const struct wpa_dbus_property_desc
*property_desc
,
4057 DBusMessageIter
*iter
, DBusError
*error
, void *user_data
)
4060 struct sta_handler_args
*args
= user_data
;
4061 struct sta_info
*sta
;
4063 sta
= ap_get_sta(args
->wpa_s
->ap_iface
->bss
[0], args
->sta
);
4067 return wpas_dbus_simple_property_getter(iter
, DBUS_TYPE_UINT16
,
4070 #else /* CONFIG_AP */
4072 #endif /* CONFIG_AP */
4077 * wpas_dbus_getter_rx_packets - Return the received packets for a station
4078 * @iter: Pointer to incoming dbus message iter
4079 * @error: Location to store error on failure
4080 * @user_data: Function specific data
4081 * Returns: TRUE on success, FALSE on failure
4083 * Getter for "RxPackets" property.
4085 dbus_bool_t
wpas_dbus_getter_sta_rx_packets(
4086 const struct wpa_dbus_property_desc
*property_desc
,
4087 DBusMessageIter
*iter
, DBusError
*error
, void *user_data
)
4090 struct sta_handler_args
*args
= user_data
;
4091 struct sta_info
*sta
;
4092 struct hostap_sta_driver_data data
;
4093 struct hostapd_data
*hapd
;
4095 if (!args
->wpa_s
->ap_iface
)
4098 hapd
= args
->wpa_s
->ap_iface
->bss
[0];
4099 sta
= ap_get_sta(hapd
, args
->sta
);
4103 if (hostapd_drv_read_sta_data(hapd
, &data
, sta
->addr
) < 0)
4106 return wpas_dbus_simple_property_getter(iter
, DBUS_TYPE_UINT64
,
4109 #else /* CONFIG_AP */
4111 #endif /* CONFIG_AP */
4116 * wpas_dbus_getter_tx_packets - Return the transmitted packets for a station
4117 * @iter: Pointer to incoming dbus message iter
4118 * @error: Location to store error on failure
4119 * @user_data: Function specific data
4120 * Returns: TRUE on success, FALSE on failure
4122 * Getter for "TxPackets" property.
4124 dbus_bool_t
wpas_dbus_getter_sta_tx_packets(
4125 const struct wpa_dbus_property_desc
*property_desc
,
4126 DBusMessageIter
*iter
, DBusError
*error
, void *user_data
)
4129 struct sta_handler_args
*args
= user_data
;
4130 struct sta_info
*sta
;
4131 struct hostap_sta_driver_data data
;
4132 struct hostapd_data
*hapd
;
4134 if (!args
->wpa_s
->ap_iface
)
4137 hapd
= args
->wpa_s
->ap_iface
->bss
[0];
4138 sta
= ap_get_sta(hapd
, args
->sta
);
4142 if (hostapd_drv_read_sta_data(hapd
, &data
, sta
->addr
) < 0)
4145 return wpas_dbus_simple_property_getter(iter
, DBUS_TYPE_UINT64
,
4148 #else /* CONFIG_AP */
4150 #endif /* CONFIG_AP */
4155 * wpas_dbus_getter_tx_bytes - Return the transmitted bytes for a station
4156 * @iter: Pointer to incoming dbus message iter
4157 * @error: Location to store error on failure
4158 * @user_data: Function specific data
4159 * Returns: TRUE on success, FALSE on failure
4161 * Getter for "TxBytes" property.
4163 dbus_bool_t
wpas_dbus_getter_sta_tx_bytes(
4164 const struct wpa_dbus_property_desc
*property_desc
,
4165 DBusMessageIter
*iter
, DBusError
*error
, void *user_data
)
4168 struct sta_handler_args
*args
= user_data
;
4169 struct sta_info
*sta
;
4170 struct hostap_sta_driver_data data
;
4171 struct hostapd_data
*hapd
;
4173 if (!args
->wpa_s
->ap_iface
)
4176 hapd
= args
->wpa_s
->ap_iface
->bss
[0];
4177 sta
= ap_get_sta(hapd
, args
->sta
);
4181 if (hostapd_drv_read_sta_data(hapd
, &data
, sta
->addr
) < 0)
4184 return wpas_dbus_simple_property_getter(iter
, DBUS_TYPE_UINT64
,
4187 #else /* CONFIG_AP */
4189 #endif /* CONFIG_AP */
4194 * wpas_dbus_getter_rx_bytes - Return the received bytes for a station
4195 * @iter: Pointer to incoming dbus message iter
4196 * @error: Location to store error on failure
4197 * @user_data: Function specific data
4198 * Returns: TRUE on success, FALSE on failure
4200 * Getter for "RxBytes" property.
4202 dbus_bool_t
wpas_dbus_getter_sta_rx_bytes(
4203 const struct wpa_dbus_property_desc
*property_desc
,
4204 DBusMessageIter
*iter
, DBusError
*error
, void *user_data
)
4207 struct sta_handler_args
*args
= user_data
;
4208 struct sta_info
*sta
;
4209 struct hostap_sta_driver_data data
;
4210 struct hostapd_data
*hapd
;
4212 if (!args
->wpa_s
->ap_iface
)
4215 hapd
= args
->wpa_s
->ap_iface
->bss
[0];
4216 sta
= ap_get_sta(hapd
, args
->sta
);
4220 if (hostapd_drv_read_sta_data(hapd
, &data
, sta
->addr
) < 0)
4223 return wpas_dbus_simple_property_getter(iter
, DBUS_TYPE_UINT64
,
4226 #else /* CONFIG_AP */
4228 #endif /* CONFIG_AP */
4232 static struct wpa_bss
* get_bss_helper(struct bss_handler_args
*args
,
4233 DBusError
*error
, const char *func_name
)
4235 struct wpa_bss
*res
= wpa_bss_get_id(args
->wpa_s
, args
->id
);
4238 wpa_printf(MSG_ERROR
, "%s[dbus]: no bss with id %d found",
4239 func_name
, args
->id
);
4240 dbus_set_error(error
, DBUS_ERROR_FAILED
,
4241 "%s: BSS %d not found",
4242 func_name
, args
->id
);
4250 * wpas_dbus_getter_bss_bssid - Return the BSSID of a BSS
4251 * @iter: Pointer to incoming dbus message iter
4252 * @error: Location to store error on failure
4253 * @user_data: Function specific data
4254 * Returns: TRUE on success, FALSE on failure
4256 * Getter for "BSSID" property.
4258 dbus_bool_t
wpas_dbus_getter_bss_bssid(
4259 const struct wpa_dbus_property_desc
*property_desc
,
4260 DBusMessageIter
*iter
, DBusError
*error
, void *user_data
)
4262 struct bss_handler_args
*args
= user_data
;
4263 struct wpa_bss
*res
;
4265 res
= get_bss_helper(args
, error
, __func__
);
4269 return wpas_dbus_simple_array_property_getter(iter
, DBUS_TYPE_BYTE
,
4270 res
->bssid
, ETH_ALEN
,
4276 * wpas_dbus_getter_bss_ssid - Return the SSID of a BSS
4277 * @iter: Pointer to incoming dbus message iter
4278 * @error: Location to store error on failure
4279 * @user_data: Function specific data
4280 * Returns: TRUE on success, FALSE on failure
4282 * Getter for "SSID" property.
4284 dbus_bool_t
wpas_dbus_getter_bss_ssid(
4285 const struct wpa_dbus_property_desc
*property_desc
,
4286 DBusMessageIter
*iter
, DBusError
*error
, void *user_data
)
4288 struct bss_handler_args
*args
= user_data
;
4289 struct wpa_bss
*res
;
4291 res
= get_bss_helper(args
, error
, __func__
);
4295 return wpas_dbus_simple_array_property_getter(iter
, DBUS_TYPE_BYTE
,
4296 res
->ssid
, res
->ssid_len
,
4302 * wpas_dbus_getter_bss_privacy - Return the privacy flag of a BSS
4303 * @iter: Pointer to incoming dbus message iter
4304 * @error: Location to store error on failure
4305 * @user_data: Function specific data
4306 * Returns: TRUE on success, FALSE on failure
4308 * Getter for "Privacy" property.
4310 dbus_bool_t
wpas_dbus_getter_bss_privacy(
4311 const struct wpa_dbus_property_desc
*property_desc
,
4312 DBusMessageIter
*iter
, DBusError
*error
, void *user_data
)
4314 struct bss_handler_args
*args
= user_data
;
4315 struct wpa_bss
*res
;
4316 dbus_bool_t privacy
;
4318 res
= get_bss_helper(args
, error
, __func__
);
4322 privacy
= (res
->caps
& IEEE80211_CAP_PRIVACY
) ? TRUE
: FALSE
;
4323 return wpas_dbus_simple_property_getter(iter
, DBUS_TYPE_BOOLEAN
,
4329 * wpas_dbus_getter_bss_mode - Return the mode of a BSS
4330 * @iter: Pointer to incoming dbus message iter
4331 * @error: Location to store error on failure
4332 * @user_data: Function specific data
4333 * Returns: TRUE on success, FALSE on failure
4335 * Getter for "Mode" property.
4337 dbus_bool_t
wpas_dbus_getter_bss_mode(
4338 const struct wpa_dbus_property_desc
*property_desc
,
4339 DBusMessageIter
*iter
, DBusError
*error
, void *user_data
)
4341 struct bss_handler_args
*args
= user_data
;
4342 struct wpa_bss
*res
;
4346 res
= get_bss_helper(args
, error
, __func__
);
4349 if (bss_is_dmg(res
)) {
4350 switch (res
->caps
& IEEE80211_CAP_DMG_MASK
) {
4351 case IEEE80211_CAP_DMG_PBSS
:
4352 case IEEE80211_CAP_DMG_IBSS
:
4355 case IEEE80211_CAP_DMG_AP
:
4356 mode
= "infrastructure";
4363 mesh
= wpa_bss_get_ie(res
, WLAN_EID_MESH_ID
);
4366 else if (res
->caps
& IEEE80211_CAP_IBSS
)
4369 mode
= "infrastructure";
4372 return wpas_dbus_simple_property_getter(iter
, DBUS_TYPE_STRING
,
4378 * wpas_dbus_getter_bss_level - Return the signal strength of a BSS
4379 * @iter: Pointer to incoming dbus message iter
4380 * @error: Location to store error on failure
4381 * @user_data: Function specific data
4382 * Returns: TRUE on success, FALSE on failure
4384 * Getter for "Level" property.
4386 dbus_bool_t
wpas_dbus_getter_bss_signal(
4387 const struct wpa_dbus_property_desc
*property_desc
,
4388 DBusMessageIter
*iter
, DBusError
*error
, void *user_data
)
4390 struct bss_handler_args
*args
= user_data
;
4391 struct wpa_bss
*res
;
4394 res
= get_bss_helper(args
, error
, __func__
);
4398 level
= (s16
) res
->level
;
4399 return wpas_dbus_simple_property_getter(iter
, DBUS_TYPE_INT16
,
4405 * wpas_dbus_getter_bss_frequency - Return the frequency of a BSS
4406 * @iter: Pointer to incoming dbus message iter
4407 * @error: Location to store error on failure
4408 * @user_data: Function specific data
4409 * Returns: TRUE on success, FALSE on failure
4411 * Getter for "Frequency" property.
4413 dbus_bool_t
wpas_dbus_getter_bss_frequency(
4414 const struct wpa_dbus_property_desc
*property_desc
,
4415 DBusMessageIter
*iter
, DBusError
*error
, void *user_data
)
4417 struct bss_handler_args
*args
= user_data
;
4418 struct wpa_bss
*res
;
4421 res
= get_bss_helper(args
, error
, __func__
);
4425 freq
= (u16
) res
->freq
;
4426 return wpas_dbus_simple_property_getter(iter
, DBUS_TYPE_UINT16
,
4431 static int cmp_u8s_desc(const void *a
, const void *b
)
4433 return (*(u8
*) b
- *(u8
*) a
);
4438 * wpas_dbus_getter_bss_rates - Return available bit rates of a BSS
4439 * @iter: Pointer to incoming dbus message iter
4440 * @error: Location to store error on failure
4441 * @user_data: Function specific data
4442 * Returns: TRUE on success, FALSE on failure
4444 * Getter for "Rates" property.
4446 dbus_bool_t
wpas_dbus_getter_bss_rates(
4447 const struct wpa_dbus_property_desc
*property_desc
,
4448 DBusMessageIter
*iter
, DBusError
*error
, void *user_data
)
4450 struct bss_handler_args
*args
= user_data
;
4451 struct wpa_bss
*res
;
4452 u8
*ie_rates
= NULL
;
4455 dbus_bool_t success
= FALSE
;
4457 res
= get_bss_helper(args
, error
, __func__
);
4461 rates_num
= wpa_bss_get_bit_rates(res
, &ie_rates
);
4465 qsort(ie_rates
, rates_num
, 1, cmp_u8s_desc
);
4467 real_rates
= os_malloc(sizeof(u32
) * rates_num
);
4470 dbus_set_error_const(error
, DBUS_ERROR_NO_MEMORY
, "no memory");
4474 for (i
= 0; i
< rates_num
; i
++)
4475 real_rates
[i
] = ie_rates
[i
] * 500000;
4477 success
= wpas_dbus_simple_array_property_getter(iter
, DBUS_TYPE_UINT32
,
4478 real_rates
, rates_num
,
4482 os_free(real_rates
);
4487 static dbus_bool_t
wpas_dbus_get_bss_security_prop(
4488 const struct wpa_dbus_property_desc
*property_desc
,
4489 DBusMessageIter
*iter
, struct wpa_ie_data
*ie_data
, DBusError
*error
)
4491 DBusMessageIter iter_dict
, variant_iter
;
4493 const char *pairwise
[5]; /* max 5 pairwise ciphers is supported */
4494 const char *key_mgmt
[15]; /* max 15 key managements may be supported */
4497 if (!dbus_message_iter_open_container(iter
, DBUS_TYPE_VARIANT
,
4498 "a{sv}", &variant_iter
))
4501 if (!wpa_dbus_dict_open_write(&variant_iter
, &iter_dict
))
4507 * When adding a new entry here, please take care to extend key_mgmt[]
4508 * and keep documentation in doc/dbus.doxygen up to date.
4511 if (ie_data
->key_mgmt
& WPA_KEY_MGMT_PSK
)
4512 key_mgmt
[n
++] = "wpa-psk";
4513 if (ie_data
->key_mgmt
& WPA_KEY_MGMT_FT_PSK
)
4514 key_mgmt
[n
++] = "wpa-ft-psk";
4515 if (ie_data
->key_mgmt
& WPA_KEY_MGMT_PSK_SHA256
)
4516 key_mgmt
[n
++] = "wpa-psk-sha256";
4517 if (ie_data
->key_mgmt
& WPA_KEY_MGMT_IEEE8021X
)
4518 key_mgmt
[n
++] = "wpa-eap";
4519 if (ie_data
->key_mgmt
& WPA_KEY_MGMT_FT_IEEE8021X
)
4520 key_mgmt
[n
++] = "wpa-ft-eap";
4521 if (ie_data
->key_mgmt
& WPA_KEY_MGMT_IEEE8021X_SHA256
)
4522 key_mgmt
[n
++] = "wpa-eap-sha256";
4523 #ifdef CONFIG_SUITEB
4524 if (ie_data
->key_mgmt
& WPA_KEY_MGMT_IEEE8021X_SUITE_B
)
4525 key_mgmt
[n
++] = "wpa-eap-suite-b";
4526 #endif /* CONFIG_SUITEB */
4527 #ifdef CONFIG_SUITEB192
4528 if (ie_data
->key_mgmt
& WPA_KEY_MGMT_IEEE8021X_SUITE_B_192
)
4529 key_mgmt
[n
++] = "wpa-eap-suite-b-192";
4530 #endif /* CONFIG_SUITEB192 */
4532 if (ie_data
->key_mgmt
& WPA_KEY_MGMT_FILS_SHA256
)
4533 key_mgmt
[n
++] = "wpa-fils-sha256";
4534 if (ie_data
->key_mgmt
& WPA_KEY_MGMT_FILS_SHA384
)
4535 key_mgmt
[n
++] = "wpa-fils-sha384";
4536 if (ie_data
->key_mgmt
& WPA_KEY_MGMT_FT_FILS_SHA256
)
4537 key_mgmt
[n
++] = "wpa-ft-fils-sha256";
4538 if (ie_data
->key_mgmt
& WPA_KEY_MGMT_FT_FILS_SHA384
)
4539 key_mgmt
[n
++] = "wpa-ft-fils-sha384";
4540 #endif /* CONFIG_FILS */
4542 if (ie_data
->key_mgmt
& WPA_KEY_MGMT_SAE
)
4543 key_mgmt
[n
++] = "sae";
4544 if (ie_data
->key_mgmt
& WPA_KEY_MGMT_FT_SAE
)
4545 key_mgmt
[n
++] = "ft-sae";
4546 #endif /* CONFIG_SAE */
4547 if (ie_data
->key_mgmt
& WPA_KEY_MGMT_NONE
)
4548 key_mgmt
[n
++] = "wpa-none";
4550 if (!wpa_dbus_dict_append_string_array(&iter_dict
, "KeyMgmt",
4555 switch (ie_data
->group_cipher
) {
4556 case WPA_CIPHER_WEP40
:
4559 case WPA_CIPHER_TKIP
:
4562 case WPA_CIPHER_CCMP
:
4565 case WPA_CIPHER_GCMP
:
4568 case WPA_CIPHER_WEP104
:
4571 case WPA_CIPHER_CCMP_256
:
4574 case WPA_CIPHER_GCMP_256
:
4582 if (!wpa_dbus_dict_append_string(&iter_dict
, "Group", group
))
4587 if (ie_data
->pairwise_cipher
& WPA_CIPHER_TKIP
)
4588 pairwise
[n
++] = "tkip";
4589 if (ie_data
->pairwise_cipher
& WPA_CIPHER_CCMP
)
4590 pairwise
[n
++] = "ccmp";
4591 if (ie_data
->pairwise_cipher
& WPA_CIPHER_GCMP
)
4592 pairwise
[n
++] = "gcmp";
4593 if (ie_data
->pairwise_cipher
& WPA_CIPHER_CCMP_256
)
4594 pairwise
[n
++] = "ccmp-256";
4595 if (ie_data
->pairwise_cipher
& WPA_CIPHER_GCMP_256
)
4596 pairwise
[n
++] = "gcmp-256";
4598 if (!wpa_dbus_dict_append_string_array(&iter_dict
, "Pairwise",
4602 /* Management group (RSN only) */
4603 if (ie_data
->proto
== WPA_PROTO_RSN
) {
4604 switch (ie_data
->mgmt_group_cipher
) {
4605 case WPA_CIPHER_AES_128_CMAC
:
4606 group
= "aes128cmac";
4613 if (!wpa_dbus_dict_append_string(&iter_dict
, "MgmtGroup",
4618 if (!wpa_dbus_dict_close_write(&variant_iter
, &iter_dict
) ||
4619 !dbus_message_iter_close_container(iter
, &variant_iter
))
4625 dbus_set_error_const(error
, DBUS_ERROR_NO_MEMORY
, "no memory");
4631 * wpas_dbus_getter_bss_wpa - Return the WPA options of a BSS
4632 * @iter: Pointer to incoming dbus message iter
4633 * @error: Location to store error on failure
4634 * @user_data: Function specific data
4635 * Returns: TRUE on success, FALSE on failure
4637 * Getter for "WPA" property.
4639 dbus_bool_t
wpas_dbus_getter_bss_wpa(
4640 const struct wpa_dbus_property_desc
*property_desc
,
4641 DBusMessageIter
*iter
, DBusError
*error
, void *user_data
)
4643 struct bss_handler_args
*args
= user_data
;
4644 struct wpa_bss
*res
;
4645 struct wpa_ie_data wpa_data
;
4648 res
= get_bss_helper(args
, error
, __func__
);
4652 os_memset(&wpa_data
, 0, sizeof(wpa_data
));
4653 ie
= wpa_bss_get_vendor_ie(res
, WPA_IE_VENDOR_TYPE
);
4654 if (ie
&& wpa_parse_wpa_ie(ie
, 2 + ie
[1], &wpa_data
) < 0) {
4655 dbus_set_error_const(error
, DBUS_ERROR_FAILED
,
4656 "failed to parse WPA IE");
4660 return wpas_dbus_get_bss_security_prop(property_desc
, iter
, &wpa_data
, error
);
4665 * wpas_dbus_getter_bss_rsn - Return the RSN options of a BSS
4666 * @iter: Pointer to incoming dbus message iter
4667 * @error: Location to store error on failure
4668 * @user_data: Function specific data
4669 * Returns: TRUE on success, FALSE on failure
4671 * Getter for "RSN" property.
4673 dbus_bool_t
wpas_dbus_getter_bss_rsn(
4674 const struct wpa_dbus_property_desc
*property_desc
,
4675 DBusMessageIter
*iter
, DBusError
*error
, void *user_data
)
4677 struct bss_handler_args
*args
= user_data
;
4678 struct wpa_bss
*res
;
4679 struct wpa_ie_data wpa_data
;
4682 res
= get_bss_helper(args
, error
, __func__
);
4686 os_memset(&wpa_data
, 0, sizeof(wpa_data
));
4687 ie
= wpa_bss_get_ie(res
, WLAN_EID_RSN
);
4688 if (ie
&& wpa_parse_wpa_ie(ie
, 2 + ie
[1], &wpa_data
) < 0) {
4689 dbus_set_error_const(error
, DBUS_ERROR_FAILED
,
4690 "failed to parse RSN IE");
4694 return wpas_dbus_get_bss_security_prop(property_desc
, iter
, &wpa_data
, error
);
4699 * wpas_dbus_getter_bss_wps - Return the WPS options of a BSS
4700 * @iter: Pointer to incoming dbus message iter
4701 * @error: Location to store error on failure
4702 * @user_data: Function specific data
4703 * Returns: TRUE on success, FALSE on failure
4705 * Getter for "WPS" property.
4707 dbus_bool_t
wpas_dbus_getter_bss_wps(
4708 const struct wpa_dbus_property_desc
*property_desc
,
4709 DBusMessageIter
*iter
, DBusError
*error
, void *user_data
)
4711 struct bss_handler_args
*args
= user_data
;
4712 struct wpa_bss
*res
;
4714 struct wpabuf
*wps_ie
;
4715 #endif /* CONFIG_WPS */
4716 DBusMessageIter iter_dict
, variant_iter
;
4717 int wps_support
= 0;
4718 const char *type
= "";
4720 res
= get_bss_helper(args
, error
, __func__
);
4724 if (!dbus_message_iter_open_container(iter
, DBUS_TYPE_VARIANT
,
4725 "a{sv}", &variant_iter
) ||
4726 !wpa_dbus_dict_open_write(&variant_iter
, &iter_dict
))
4730 wps_ie
= wpa_bss_get_vendor_ie_multi(res
, WPS_IE_VENDOR_TYPE
);
4733 if (wps_is_selected_pbc_registrar(wps_ie
))
4735 else if (wps_is_selected_pin_registrar(wps_ie
))
4738 wpabuf_free(wps_ie
);
4740 #endif /* CONFIG_WPS */
4742 if ((wps_support
&& !wpa_dbus_dict_append_string(&iter_dict
, "Type", type
)) ||
4743 !wpa_dbus_dict_close_write(&variant_iter
, &iter_dict
) ||
4744 !dbus_message_iter_close_container(iter
, &variant_iter
))
4750 dbus_set_error_const(error
, DBUS_ERROR_NO_MEMORY
, "no memory");
4756 * wpas_dbus_getter_bss_ies - Return all IEs of a BSS
4757 * @iter: Pointer to incoming dbus message iter
4758 * @error: Location to store error on failure
4759 * @user_data: Function specific data
4760 * Returns: TRUE on success, FALSE on failure
4762 * Getter for "IEs" property.
4764 dbus_bool_t
wpas_dbus_getter_bss_ies(
4765 const struct wpa_dbus_property_desc
*property_desc
,
4766 DBusMessageIter
*iter
, DBusError
*error
, void *user_data
)
4768 struct bss_handler_args
*args
= user_data
;
4769 struct wpa_bss
*res
;
4771 res
= get_bss_helper(args
, error
, __func__
);
4775 return wpas_dbus_simple_array_property_getter(iter
, DBUS_TYPE_BYTE
,
4776 res
+ 1, res
->ie_len
,
4782 * wpas_dbus_getter_bss_age - Return time in seconds since BSS was last seen
4783 * @iter: Pointer to incoming dbus message iter
4784 * @error: Location to store error on failure
4785 * @user_data: Function specific data
4786 * Returns: TRUE on success, FALSE on failure
4788 * Getter for BSS age
4790 dbus_bool_t
wpas_dbus_getter_bss_age(
4791 const struct wpa_dbus_property_desc
*property_desc
,
4792 DBusMessageIter
*iter
, DBusError
*error
, void *user_data
)
4794 struct bss_handler_args
*args
= user_data
;
4795 struct wpa_bss
*res
;
4796 struct os_reltime now
, diff
= { 0, 0 };
4799 res
= get_bss_helper(args
, error
, __func__
);
4803 os_get_reltime(&now
);
4804 os_reltime_sub(&now
, &res
->last_update
, &diff
);
4805 age
= diff
.sec
> 0 ? diff
.sec
: 0;
4806 return wpas_dbus_simple_property_getter(iter
, DBUS_TYPE_UINT32
, &age
,
4812 * wpas_dbus_getter_enabled - Check whether network is enabled or disabled
4813 * @iter: Pointer to incoming dbus message iter
4814 * @error: Location to store error on failure
4815 * @user_data: Function specific data
4816 * Returns: TRUE on success, FALSE on failure
4818 * Getter for "enabled" property of a configured network.
4820 dbus_bool_t
wpas_dbus_getter_enabled(
4821 const struct wpa_dbus_property_desc
*property_desc
,
4822 DBusMessageIter
*iter
, DBusError
*error
, void *user_data
)
4824 struct network_handler_args
*net
= user_data
;
4825 dbus_bool_t enabled
= net
->ssid
->disabled
? FALSE
: TRUE
;
4827 return wpas_dbus_simple_property_getter(iter
, DBUS_TYPE_BOOLEAN
,
4833 * wpas_dbus_setter_enabled - Mark a configured network as enabled or disabled
4834 * @iter: Pointer to incoming dbus message iter
4835 * @error: Location to store error on failure
4836 * @user_data: Function specific data
4837 * Returns: TRUE on success, FALSE on failure
4839 * Setter for "Enabled" property of a configured network.
4841 dbus_bool_t
wpas_dbus_setter_enabled(
4842 const struct wpa_dbus_property_desc
*property_desc
,
4843 DBusMessageIter
*iter
, DBusError
*error
, void *user_data
)
4845 struct network_handler_args
*net
= user_data
;
4846 struct wpa_supplicant
*wpa_s
;
4847 struct wpa_ssid
*ssid
;
4850 if (!wpas_dbus_simple_property_setter(iter
, error
, DBUS_TYPE_BOOLEAN
,
4858 wpa_supplicant_enable_network(wpa_s
, ssid
);
4860 wpa_supplicant_disable_network(wpa_s
, ssid
);
4867 * wpas_dbus_getter_network_properties - Get options for a configured network
4868 * @iter: Pointer to incoming dbus message iter
4869 * @error: Location to store error on failure
4870 * @user_data: Function specific data
4871 * Returns: TRUE on success, FALSE on failure
4873 * Getter for "Properties" property of a configured network.
4875 dbus_bool_t
wpas_dbus_getter_network_properties(
4876 const struct wpa_dbus_property_desc
*property_desc
,
4877 DBusMessageIter
*iter
, DBusError
*error
, void *user_data
)
4879 struct network_handler_args
*net
= user_data
;
4880 DBusMessageIter variant_iter
, dict_iter
;
4882 char **props
= wpa_config_get_all(net
->ssid
, 1);
4883 dbus_bool_t success
= FALSE
;
4886 dbus_set_error_const(error
, DBUS_ERROR_NO_MEMORY
, "no memory");
4890 if (!dbus_message_iter_open_container(iter
, DBUS_TYPE_VARIANT
, "a{sv}",
4892 !wpa_dbus_dict_open_write(&variant_iter
, &dict_iter
)) {
4893 dbus_set_error_const(error
, DBUS_ERROR_NO_MEMORY
, "no memory");
4899 if (!wpa_dbus_dict_append_string(&dict_iter
, *iterator
,
4901 dbus_set_error_const(error
, DBUS_ERROR_NO_MEMORY
,
4909 if (!wpa_dbus_dict_close_write(&variant_iter
, &dict_iter
) ||
4910 !dbus_message_iter_close_container(iter
, &variant_iter
)) {
4911 dbus_set_error_const(error
, DBUS_ERROR_NO_MEMORY
, "no memory");
4929 * wpas_dbus_setter_network_properties - Set options for a configured network
4930 * @iter: Pointer to incoming dbus message iter
4931 * @error: Location to store error on failure
4932 * @user_data: Function specific data
4933 * Returns: TRUE on success, FALSE on failure
4935 * Setter for "Properties" property of a configured network.
4937 dbus_bool_t
wpas_dbus_setter_network_properties(
4938 const struct wpa_dbus_property_desc
*property_desc
,
4939 DBusMessageIter
*iter
, DBusError
*error
, void *user_data
)
4941 struct network_handler_args
*net
= user_data
;
4942 struct wpa_ssid
*ssid
= net
->ssid
;
4943 DBusMessageIter variant_iter
;
4945 dbus_message_iter_recurse(iter
, &variant_iter
);
4946 return set_network_properties(net
->wpa_s
, ssid
, &variant_iter
, error
);
4952 DBusMessage
* wpas_dbus_handler_subscribe_preq(
4953 DBusMessage
*message
, struct wpa_supplicant
*wpa_s
)
4955 struct wpas_dbus_priv
*priv
= wpa_s
->global
->dbus
;
4958 if (wpa_s
->preq_notify_peer
!= NULL
) {
4959 if (os_strcmp(dbus_message_get_sender(message
),
4960 wpa_s
->preq_notify_peer
) == 0)
4963 return dbus_message_new_error(message
,
4964 WPAS_DBUS_ERROR_SUBSCRIPTION_IN_USE
,
4965 "Another application is already subscribed");
4968 name
= os_strdup(dbus_message_get_sender(message
));
4970 return wpas_dbus_error_no_memory(message
);
4972 wpa_s
->preq_notify_peer
= name
;
4974 /* Subscribe to clean up if application closes socket */
4975 wpas_dbus_subscribe_noc(priv
);
4978 * Double-check it's still alive to make sure that we didn't
4979 * miss the NameOwnerChanged signal, e.g. while strdup'ing.
4981 if (!dbus_bus_name_has_owner(priv
->con
, name
, NULL
)) {
4983 * Application no longer exists, clean up.
4984 * The return value is irrelevant now.
4986 * Need to check if the NameOwnerChanged handling
4987 * already cleaned up because we have processed
4988 * DBus messages while checking if the name still
4991 if (!wpa_s
->preq_notify_peer
)
4993 os_free(wpa_s
->preq_notify_peer
);
4994 wpa_s
->preq_notify_peer
= NULL
;
4995 wpas_dbus_unsubscribe_noc(priv
);
5002 DBusMessage
* wpas_dbus_handler_unsubscribe_preq(
5003 DBusMessage
*message
, struct wpa_supplicant
*wpa_s
)
5005 struct wpas_dbus_priv
*priv
= wpa_s
->global
->dbus
;
5007 if (!wpa_s
->preq_notify_peer
)
5008 return dbus_message_new_error(message
,
5009 WPAS_DBUS_ERROR_NO_SUBSCRIPTION
,
5012 if (os_strcmp(wpa_s
->preq_notify_peer
,
5013 dbus_message_get_sender(message
)))
5014 return dbus_message_new_error(message
,
5015 WPAS_DBUS_ERROR_SUBSCRIPTION_EPERM
,
5016 "Can't unsubscribe others");
5018 os_free(wpa_s
->preq_notify_peer
);
5019 wpa_s
->preq_notify_peer
= NULL
;
5020 wpas_dbus_unsubscribe_noc(priv
);
5025 void wpas_dbus_signal_preq(struct wpa_supplicant
*wpa_s
,
5026 const u8
*addr
, const u8
*dst
, const u8
*bssid
,
5027 const u8
*ie
, size_t ie_len
, u32 ssi_signal
)
5030 DBusMessageIter iter
, dict_iter
;
5031 struct wpas_dbus_priv
*priv
= wpa_s
->global
->dbus
;
5033 /* Do nothing if the control interface is not turned on */
5034 if (priv
== NULL
|| !wpa_s
->dbus_new_path
)
5037 if (wpa_s
->preq_notify_peer
== NULL
)
5040 msg
= dbus_message_new_signal(wpa_s
->dbus_new_path
,
5041 WPAS_DBUS_NEW_IFACE_INTERFACE
,
5046 dbus_message_set_destination(msg
, wpa_s
->preq_notify_peer
);
5048 dbus_message_iter_init_append(msg
, &iter
);
5050 if (!wpa_dbus_dict_open_write(&iter
, &dict_iter
) ||
5051 (addr
&& !wpa_dbus_dict_append_byte_array(&dict_iter
, "addr",
5052 (const char *) addr
,
5054 (dst
&& !wpa_dbus_dict_append_byte_array(&dict_iter
, "dst",
5057 (bssid
&& !wpa_dbus_dict_append_byte_array(&dict_iter
, "bssid",
5058 (const char *) bssid
,
5060 (ie
&& ie_len
&& !wpa_dbus_dict_append_byte_array(&dict_iter
, "ies",
5063 (ssi_signal
&& !wpa_dbus_dict_append_int32(&dict_iter
, "signal",
5065 !wpa_dbus_dict_close_write(&iter
, &dict_iter
))
5068 dbus_connection_send(priv
->con
, msg
, NULL
);
5071 wpa_printf(MSG_ERROR
, "dbus: Failed to construct signal");
5073 dbus_message_unref(msg
);
5076 #endif /* CONFIG_AP */
5079 DBusMessage
* wpas_dbus_handler_vendor_elem_add(DBusMessage
*message
,
5080 struct wpa_supplicant
*wpa_s
)
5084 struct ieee802_11_elems elems
;
5085 dbus_int32_t frame_id
;
5086 DBusMessageIter iter
, array
;
5088 dbus_message_iter_init(message
, &iter
);
5089 dbus_message_iter_get_basic(&iter
, &frame_id
);
5090 if (frame_id
< 0 || frame_id
>= NUM_VENDOR_ELEM_FRAMES
) {
5091 return dbus_message_new_error(message
, DBUS_ERROR_INVALID_ARGS
,
5095 dbus_message_iter_next(&iter
);
5096 dbus_message_iter_recurse(&iter
, &array
);
5097 dbus_message_iter_get_fixed_array(&array
, &ielems
, &len
);
5098 if (!ielems
|| len
== 0) {
5099 return dbus_message_new_error(
5100 message
, DBUS_ERROR_INVALID_ARGS
, "Invalid value");
5103 if (ieee802_11_parse_elems(ielems
, len
, &elems
, 0) == ParseFailed
) {
5104 return dbus_message_new_error(message
, DBUS_ERROR_INVALID_ARGS
,
5108 wpa_s
= wpas_vendor_elem(wpa_s
, frame_id
);
5109 if (!wpa_s
->vendor_elem
[frame_id
]) {
5110 wpa_s
->vendor_elem
[frame_id
] = wpabuf_alloc_copy(ielems
, len
);
5111 wpas_vendor_elem_update(wpa_s
);
5115 if (wpabuf_resize(&wpa_s
->vendor_elem
[frame_id
], len
) < 0) {
5116 return dbus_message_new_error(message
, DBUS_ERROR_INVALID_ARGS
,
5120 wpabuf_put_data(wpa_s
->vendor_elem
[frame_id
], ielems
, len
);
5121 wpas_vendor_elem_update(wpa_s
);
5126 DBusMessage
* wpas_dbus_handler_vendor_elem_get(DBusMessage
*message
,
5127 struct wpa_supplicant
*wpa_s
)
5130 DBusMessageIter iter
, array_iter
;
5131 dbus_int32_t frame_id
;
5135 dbus_message_iter_init(message
, &iter
);
5136 dbus_message_iter_get_basic(&iter
, &frame_id
);
5138 if (frame_id
< 0 || frame_id
>= NUM_VENDOR_ELEM_FRAMES
) {
5139 return dbus_message_new_error(message
, DBUS_ERROR_INVALID_ARGS
,
5143 wpa_s
= wpas_vendor_elem(wpa_s
, frame_id
);
5144 if (!wpa_s
->vendor_elem
[frame_id
]) {
5145 return dbus_message_new_error(message
, DBUS_ERROR_INVALID_ARGS
,
5146 "ID value does not exist");
5149 reply
= dbus_message_new_method_return(message
);
5151 return wpas_dbus_error_no_memory(message
);
5153 dbus_message_iter_init_append(reply
, &iter
);
5155 elem
= wpabuf_head_u8(wpa_s
->vendor_elem
[frame_id
]);
5156 elem_len
= wpabuf_len(wpa_s
->vendor_elem
[frame_id
]);
5158 if (!dbus_message_iter_open_container(&iter
, DBUS_TYPE_ARRAY
,
5159 DBUS_TYPE_BYTE_AS_STRING
,
5161 !dbus_message_iter_append_fixed_array(&array_iter
, DBUS_TYPE_BYTE
,
5163 !dbus_message_iter_close_container(&iter
, &array_iter
)) {
5164 dbus_message_unref(reply
);
5165 reply
= wpas_dbus_error_no_memory(message
);
5172 DBusMessage
* wpas_dbus_handler_vendor_elem_remove(DBusMessage
*message
,
5173 struct wpa_supplicant
*wpa_s
)
5177 struct ieee802_11_elems elems
;
5178 DBusMessageIter iter
, array
;
5179 dbus_int32_t frame_id
;
5181 dbus_message_iter_init(message
, &iter
);
5182 dbus_message_iter_get_basic(&iter
, &frame_id
);
5183 if (frame_id
< 0 || frame_id
>= NUM_VENDOR_ELEM_FRAMES
) {
5184 return dbus_message_new_error(message
, DBUS_ERROR_INVALID_ARGS
,
5188 dbus_message_iter_next(&iter
);
5189 dbus_message_iter_recurse(&iter
, &array
);
5190 dbus_message_iter_get_fixed_array(&array
, &ielems
, &len
);
5191 if (!ielems
|| len
== 0) {
5192 return dbus_message_new_error(message
, DBUS_ERROR_INVALID_ARGS
,
5196 wpa_s
= wpas_vendor_elem(wpa_s
, frame_id
);
5198 if (len
== 1 && *ielems
== '*') {
5199 wpabuf_free(wpa_s
->vendor_elem
[frame_id
]);
5200 wpa_s
->vendor_elem
[frame_id
] = NULL
;
5201 wpas_vendor_elem_update(wpa_s
);
5205 if (!wpa_s
->vendor_elem
[frame_id
]) {
5206 return dbus_message_new_error(message
, DBUS_ERROR_INVALID_ARGS
,
5207 "ID value does not exist");
5210 if (ieee802_11_parse_elems(ielems
, len
, &elems
, 0) == ParseFailed
) {
5211 return dbus_message_new_error(message
, DBUS_ERROR_INVALID_ARGS
,
5215 if (wpas_vendor_elem_remove(wpa_s
, frame_id
, ielems
, len
) == 0)
5218 return dbus_message_new_error(message
, DBUS_ERROR_INVALID_ARGS
,
5226 * wpas_dbus_getter_mesh_peers - Get connected mesh peers
5227 * @iter: Pointer to incoming dbus message iter
5228 * @error: Location to store error on failure
5229 * @user_data: Function specific data
5230 * Returns: TRUE on success, FALSE on failure
5232 * Getter for "MeshPeers" property.
5234 dbus_bool_t
wpas_dbus_getter_mesh_peers(
5235 const struct wpa_dbus_property_desc
*property_desc
,
5236 DBusMessageIter
*iter
, DBusError
*error
, void *user_data
)
5238 struct wpa_supplicant
*wpa_s
= user_data
;
5239 struct hostapd_data
*hapd
;
5240 struct sta_info
*sta
;
5241 DBusMessageIter variant_iter
, array_iter
;
5243 DBusMessageIter inner_array_iter
;
5247 hapd
= wpa_s
->ifmsh
->bss
[0];
5249 if (!dbus_message_iter_open_container(iter
, DBUS_TYPE_VARIANT
,
5250 DBUS_TYPE_ARRAY_AS_STRING
5251 DBUS_TYPE_ARRAY_AS_STRING
5252 DBUS_TYPE_BYTE_AS_STRING
,
5254 !dbus_message_iter_open_container(&variant_iter
, DBUS_TYPE_ARRAY
,
5255 DBUS_TYPE_ARRAY_AS_STRING
5256 DBUS_TYPE_BYTE_AS_STRING
,
5260 for (sta
= hapd
->sta_list
; sta
; sta
= sta
->next
) {
5261 if (!dbus_message_iter_open_container(
5262 &array_iter
, DBUS_TYPE_ARRAY
,
5263 DBUS_TYPE_BYTE_AS_STRING
,
5267 for (i
= 0; i
< ETH_ALEN
; i
++) {
5268 if (!dbus_message_iter_append_basic(&inner_array_iter
,
5274 if (!dbus_message_iter_close_container(
5275 &array_iter
, &inner_array_iter
))
5279 if (!dbus_message_iter_close_container(&variant_iter
, &array_iter
) ||
5280 !dbus_message_iter_close_container(iter
, &variant_iter
))
5288 * wpas_dbus_getter_mesh_group - Get mesh group
5289 * @iter: Pointer to incoming dbus message iter
5290 * @error: Location to store error on failure
5291 * @user_data: Function specific data
5292 * Returns: TRUE on success, FALSE on failure
5294 * Getter for "MeshGroup" property.
5296 dbus_bool_t
wpas_dbus_getter_mesh_group(
5297 const struct wpa_dbus_property_desc
*property_desc
,
5298 DBusMessageIter
*iter
, DBusError
*error
, void *user_data
)
5300 struct wpa_supplicant
*wpa_s
= user_data
;
5301 struct wpa_ssid
*ssid
= wpa_s
->current_ssid
;
5303 if (!wpa_s
->ifmsh
|| !ssid
)
5306 if (!wpas_dbus_simple_array_property_getter(iter
, DBUS_TYPE_BYTE
,
5307 (char *) ssid
->ssid
,
5308 ssid
->ssid_len
, error
)) {
5309 dbus_set_error(error
, DBUS_ERROR_FAILED
,
5310 "%s: error constructing reply", __func__
);
5317 #endif /* CONFIG_MESH */