2 * WPA Supplicant / dbus-based control interface
3 * Copyright (c) 2006, Dan Williams <dcbw@redhat.com> and Red Hat, Inc.
4 * Copyright (c) 2009-2010, Witold Sowa <witold.sowa@gmail.com>
5 * Copyright (c) 2009-2015, Jouni Malinen <j@w1.fi>
7 * This software may be distributed under the terms of the BSD license.
8 * See README for more details.
14 #include "common/ieee802_11_defs.h"
15 #include "eap_peer/eap_methods.h"
16 #include "eapol_supp/eapol_supp_sm.h"
17 #include "rsn_supp/wpa.h"
18 #include "../config.h"
19 #include "../wpa_supplicant_i.h"
20 #include "../driver_i.h"
21 #include "../notify.h"
24 #include "../autoscan.h"
25 #include "dbus_new_helpers.h"
27 #include "dbus_new_handlers.h"
28 #include "dbus_dict_helpers.h"
29 #include "dbus_common_i.h"
30 #include "drivers/driver.h"
32 static const char * const debug_strings
[] = {
33 "excessive", "msgdump", "debug", "info", "warning", "error", NULL
38 * wpas_dbus_error_unknown_error - Return a new UnknownError error message
39 * @message: Pointer to incoming dbus message this error refers to
40 * @arg: Optional string appended to error message
41 * Returns: a dbus error message
43 * Convenience function to create and return an UnknownError
45 DBusMessage
* wpas_dbus_error_unknown_error(DBusMessage
*message
,
48 return dbus_message_new_error(message
, WPAS_DBUS_ERROR_UNKNOWN_ERROR
,
54 * wpas_dbus_error_iface_unknown - Return a new invalid interface error message
55 * @message: Pointer to incoming dbus message this error refers to
56 * Returns: A dbus error message
58 * Convenience function to create and return an invalid interface error
60 static DBusMessage
* wpas_dbus_error_iface_unknown(DBusMessage
*message
)
62 return dbus_message_new_error(
63 message
, WPAS_DBUS_ERROR_IFACE_UNKNOWN
,
64 "wpa_supplicant knows nothing about this interface.");
69 * wpas_dbus_error_network_unknown - Return a new NetworkUnknown error message
70 * @message: Pointer to incoming dbus message this error refers to
71 * Returns: a dbus error message
73 * Convenience function to create and return an invalid network error
75 static DBusMessage
* wpas_dbus_error_network_unknown(DBusMessage
*message
)
77 return dbus_message_new_error(
78 message
, WPAS_DBUS_ERROR_NETWORK_UNKNOWN
,
79 "There is no such a network in this interface.");
84 * wpas_dbus_error_invalid_args - Return a new InvalidArgs error message
85 * @message: Pointer to incoming dbus message this error refers to
86 * Returns: a dbus error message
88 * Convenience function to create and return an invalid options error
90 DBusMessage
* wpas_dbus_error_invalid_args(DBusMessage
*message
,
95 reply
= dbus_message_new_error(
96 message
, WPAS_DBUS_ERROR_INVALID_ARGS
,
97 "Did not receive correct message arguments.");
99 dbus_message_append_args(reply
, DBUS_TYPE_STRING
, &arg
,
107 * wpas_dbus_error_scan_error - Return a new ScanError error message
108 * @message: Pointer to incoming dbus message this error refers to
109 * @error: Optional string to be used as the error message
110 * Returns: a dbus error message
112 * Convenience function to create and return a scan error
114 static DBusMessage
* wpas_dbus_error_scan_error(DBusMessage
*message
,
117 return dbus_message_new_error(message
,
118 WPAS_DBUS_ERROR_IFACE_SCAN_ERROR
,
123 DBusMessage
* wpas_dbus_error_no_memory(DBusMessage
*message
)
125 wpa_printf(MSG_DEBUG
, "dbus: Failed to allocate memory");
126 return dbus_message_new_error(message
, DBUS_ERROR_NO_MEMORY
, NULL
);
130 static const char * const dont_quote
[] = {
131 "key_mgmt", "proto", "pairwise", "auth_alg", "group", "eap",
132 "opensc_engine_path", "pkcs11_engine_path", "pkcs11_module_path",
133 "bssid", "scan_freq", "freq_list", NULL
136 static dbus_bool_t
should_quote_opt(const char *key
)
140 while (dont_quote
[i
] != NULL
) {
141 if (os_strcmp(key
, dont_quote
[i
]) == 0)
149 * get_iface_by_dbus_path - Get a new network interface
150 * @global: Pointer to global data from wpa_supplicant_init()
151 * @path: Pointer to a dbus object path representing an interface
152 * Returns: Pointer to the interface or %NULL if not found
154 static struct wpa_supplicant
* get_iface_by_dbus_path(
155 struct wpa_global
*global
, const char *path
)
157 struct wpa_supplicant
*wpa_s
;
159 for (wpa_s
= global
->ifaces
; wpa_s
; wpa_s
= wpa_s
->next
) {
160 if (wpa_s
->dbus_new_path
&&
161 os_strcmp(wpa_s
->dbus_new_path
, path
) == 0)
169 * set_network_properties - Set properties of a configured network
170 * @wpa_s: wpa_supplicant structure for a network interface
171 * @ssid: wpa_ssid structure for a configured network
172 * @iter: DBus message iterator containing dictionary of network
174 * @error: On failure, an error describing the failure
175 * Returns: TRUE if the request succeeds, FALSE if it failed
177 * Sets network configuration with parameters given id DBus dictionary
179 dbus_bool_t
set_network_properties(struct wpa_supplicant
*wpa_s
,
180 struct wpa_ssid
*ssid
,
181 DBusMessageIter
*iter
,
184 struct wpa_dbus_dict_entry entry
= { .type
= DBUS_TYPE_STRING
};
185 DBusMessageIter iter_dict
;
188 if (!wpa_dbus_dict_open_read(iter
, &iter_dict
, error
))
191 while (wpa_dbus_dict_has_dict_entry(&iter_dict
)) {
195 if (!wpa_dbus_dict_get_entry(&iter_dict
, &entry
))
199 if (entry
.type
== DBUS_TYPE_ARRAY
&&
200 entry
.array_type
== DBUS_TYPE_BYTE
) {
201 if (entry
.array_len
<= 0)
204 size
= entry
.array_len
* 2 + 1;
205 value
= os_zalloc(size
);
209 ret
= wpa_snprintf_hex(value
, size
,
210 (u8
*) entry
.bytearray_value
,
214 } else if (entry
.type
== DBUS_TYPE_STRING
) {
215 if (should_quote_opt(entry
.key
)) {
216 size
= os_strlen(entry
.str_value
);
221 value
= os_zalloc(size
);
225 ret
= os_snprintf(value
, size
, "\"%s\"",
227 if (os_snprintf_error(size
, ret
))
230 value
= os_strdup(entry
.str_value
);
234 } else if (entry
.type
== DBUS_TYPE_UINT32
) {
235 value
= os_zalloc(size
);
239 ret
= os_snprintf(value
, size
, "%u",
241 if (os_snprintf_error(size
, ret
))
243 } else if (entry
.type
== DBUS_TYPE_INT32
) {
244 value
= os_zalloc(size
);
248 ret
= os_snprintf(value
, size
, "%d",
250 if (os_snprintf_error(size
, ret
))
255 if (wpa_config_set(ssid
, entry
.key
, value
, 0) < 0)
258 if (os_strcmp(entry
.key
, "bssid") != 0 &&
259 os_strcmp(entry
.key
, "priority") != 0)
260 wpa_sm_pmksa_cache_flush(wpa_s
->wpa
, ssid
);
262 if (wpa_s
->current_ssid
== ssid
||
263 wpa_s
->current_ssid
== NULL
) {
265 * Invalidate the EAP session cache if anything in the
266 * current or previously used configuration changes.
268 eapol_sm_invalidate_cached_session(wpa_s
->eapol
);
271 if ((os_strcmp(entry
.key
, "psk") == 0 &&
272 value
[0] == '"' && ssid
->ssid_len
) ||
273 (os_strcmp(entry
.key
, "ssid") == 0 && ssid
->passphrase
))
274 wpa_config_update_psk(ssid
);
275 else if (os_strcmp(entry
.key
, "priority") == 0)
276 wpa_config_update_prio_list(wpa_s
->conf
);
280 wpa_dbus_dict_entry_clear(&entry
);
287 wpa_dbus_dict_entry_clear(&entry
);
288 dbus_set_error_const(error
, DBUS_ERROR_INVALID_ARGS
,
289 "invalid message format");
295 * wpas_dbus_simple_property_getter - Get basic type property
296 * @iter: Message iter to use when appending arguments
297 * @type: DBus type of property (must be basic type)
298 * @val: pointer to place holding property value
299 * @error: On failure an error describing the failure
300 * Returns: TRUE if the request was successful, FALSE if it failed
302 * Generic getter for basic type properties. Type is required to be basic.
304 dbus_bool_t
wpas_dbus_simple_property_getter(DBusMessageIter
*iter
,
309 DBusMessageIter variant_iter
;
311 if (!dbus_type_is_basic(type
)) {
312 dbus_set_error(error
, DBUS_ERROR_FAILED
,
313 "%s: given type is not basic", __func__
);
317 if (!dbus_message_iter_open_container(iter
, DBUS_TYPE_VARIANT
,
318 wpa_dbus_type_as_string(type
),
320 !dbus_message_iter_append_basic(&variant_iter
, type
, val
) ||
321 !dbus_message_iter_close_container(iter
, &variant_iter
)) {
322 dbus_set_error(error
, DBUS_ERROR_FAILED
,
323 "%s: error constructing reply", __func__
);
332 * wpas_dbus_simple_property_setter - Set basic type property
333 * @message: Pointer to incoming dbus message
334 * @type: DBus type of property (must be basic type)
335 * @val: pointer to place where value being set will be stored
336 * Returns: TRUE if the request was successful, FALSE if it failed
338 * Generic setter for basic type properties. Type is required to be basic.
340 dbus_bool_t
wpas_dbus_simple_property_setter(DBusMessageIter
*iter
,
342 const int type
, void *val
)
344 DBusMessageIter variant_iter
;
346 if (!dbus_type_is_basic(type
)) {
347 dbus_set_error(error
, DBUS_ERROR_FAILED
,
348 "%s: given type is not basic", __func__
);
352 /* Look at the new value */
353 dbus_message_iter_recurse(iter
, &variant_iter
);
354 if (dbus_message_iter_get_arg_type(&variant_iter
) != type
) {
355 dbus_set_error_const(error
, DBUS_ERROR_FAILED
,
356 "wrong property type");
359 dbus_message_iter_get_basic(&variant_iter
, val
);
366 * wpas_dbus_simple_array_property_getter - Get array type property
367 * @iter: Pointer to incoming dbus message iterator
368 * @type: DBus type of property array elements (must be basic type)
369 * @array: pointer to array of elements to put into response message
370 * @array_len: length of above array
371 * @error: a pointer to an error to fill on failure
372 * Returns: TRUE if the request succeeded, FALSE if it failed
374 * Generic getter for array type properties. Array elements type is
375 * required to be basic.
377 dbus_bool_t
wpas_dbus_simple_array_property_getter(DBusMessageIter
*iter
,
383 DBusMessageIter variant_iter
, array_iter
;
384 char type_str
[] = "a?"; /* ? will be replaced with subtype letter; */
385 const char *sub_type_str
;
386 size_t element_size
, i
;
388 if (!dbus_type_is_basic(type
)) {
389 dbus_set_error(error
, DBUS_ERROR_FAILED
,
390 "%s: given type is not basic", __func__
);
394 sub_type_str
= wpa_dbus_type_as_string(type
);
395 type_str
[1] = sub_type_str
[0];
397 if (!dbus_message_iter_open_container(iter
, DBUS_TYPE_VARIANT
,
398 type_str
, &variant_iter
) ||
399 !dbus_message_iter_open_container(&variant_iter
, DBUS_TYPE_ARRAY
,
400 sub_type_str
, &array_iter
)) {
401 dbus_set_error(error
, DBUS_ERROR_FAILED
,
402 "%s: failed to construct message", __func__
);
408 case DBUS_TYPE_BOOLEAN
:
411 case DBUS_TYPE_INT16
:
412 case DBUS_TYPE_UINT16
:
413 element_size
= sizeof(uint16_t);
415 case DBUS_TYPE_INT32
:
416 case DBUS_TYPE_UINT32
:
417 element_size
= sizeof(uint32_t);
419 case DBUS_TYPE_INT64
:
420 case DBUS_TYPE_UINT64
:
421 element_size
= sizeof(uint64_t);
423 case DBUS_TYPE_DOUBLE
:
424 element_size
= sizeof(double);
426 case DBUS_TYPE_STRING
:
427 case DBUS_TYPE_OBJECT_PATH
:
428 element_size
= sizeof(char *);
431 dbus_set_error(error
, DBUS_ERROR_FAILED
,
432 "%s: unknown element type %d", __func__
, type
);
436 for (i
= 0; i
< array_len
; i
++) {
437 if (!dbus_message_iter_append_basic(&array_iter
, type
,
438 array
+ i
* element_size
)) {
439 dbus_set_error(error
, DBUS_ERROR_FAILED
,
440 "%s: failed to construct message 2.5",
446 if (!dbus_message_iter_close_container(&variant_iter
, &array_iter
) ||
447 !dbus_message_iter_close_container(iter
, &variant_iter
)) {
448 dbus_set_error(error
, DBUS_ERROR_FAILED
,
449 "%s: failed to construct message 3", __func__
);
458 * wpas_dbus_simple_array_array_property_getter - Get array array type property
459 * @iter: Pointer to incoming dbus message iterator
460 * @type: DBus type of property array elements (must be basic type)
461 * @array: pointer to array of elements to put into response message
462 * @array_len: length of above array
463 * @error: a pointer to an error to fill on failure
464 * Returns: TRUE if the request succeeded, FALSE if it failed
466 * Generic getter for array type properties. Array elements type is
467 * required to be basic.
469 dbus_bool_t
wpas_dbus_simple_array_array_property_getter(DBusMessageIter
*iter
,
471 struct wpabuf
**array
,
475 DBusMessageIter variant_iter
, array_iter
;
476 char type_str
[] = "aa?";
477 char inner_type_str
[] = "a?";
478 const char *sub_type_str
;
481 if (!dbus_type_is_basic(type
)) {
482 dbus_set_error(error
, DBUS_ERROR_FAILED
,
483 "%s: given type is not basic", __func__
);
487 sub_type_str
= wpa_dbus_type_as_string(type
);
488 type_str
[2] = sub_type_str
[0];
489 inner_type_str
[1] = sub_type_str
[0];
491 if (!dbus_message_iter_open_container(iter
, DBUS_TYPE_VARIANT
,
492 type_str
, &variant_iter
) ||
493 !dbus_message_iter_open_container(&variant_iter
, DBUS_TYPE_ARRAY
,
494 inner_type_str
, &array_iter
)) {
495 dbus_set_error(error
, DBUS_ERROR_FAILED
,
496 "%s: failed to construct message", __func__
);
500 for (i
= 0; i
< array_len
&& array
[i
]; i
++) {
501 wpa_dbus_dict_bin_array_add_element(&array_iter
,
502 wpabuf_head(array
[i
]),
503 wpabuf_len(array
[i
]));
507 if (!dbus_message_iter_close_container(&variant_iter
, &array_iter
) ||
508 !dbus_message_iter_close_container(iter
, &variant_iter
)) {
509 dbus_set_error(error
, DBUS_ERROR_FAILED
,
510 "%s: failed to close message", __func__
);
519 * wpas_dbus_handler_create_interface - Request registration of a network iface
520 * @message: Pointer to incoming dbus message
521 * @global: %wpa_supplicant global data structure
522 * Returns: The object path of the new interface object,
523 * or a dbus error message with more information
525 * Handler function for "CreateInterface" method call. Handles requests
526 * by dbus clients to register a network interface that wpa_supplicant
529 DBusMessage
* wpas_dbus_handler_create_interface(DBusMessage
*message
,
530 struct wpa_global
*global
)
532 DBusMessageIter iter_dict
;
533 DBusMessage
*reply
= NULL
;
534 DBusMessageIter iter
;
535 struct wpa_dbus_dict_entry entry
;
538 char *confname
= NULL
;
539 char *bridge_ifname
= NULL
;
541 dbus_message_iter_init(message
, &iter
);
543 if (!wpa_dbus_dict_open_read(&iter
, &iter_dict
, NULL
))
545 while (wpa_dbus_dict_has_dict_entry(&iter_dict
)) {
546 if (!wpa_dbus_dict_get_entry(&iter_dict
, &entry
))
548 if (os_strcmp(entry
.key
, "Driver") == 0 &&
549 entry
.type
== DBUS_TYPE_STRING
) {
551 driver
= os_strdup(entry
.str_value
);
552 wpa_dbus_dict_entry_clear(&entry
);
555 } else if (os_strcmp(entry
.key
, "Ifname") == 0 &&
556 entry
.type
== DBUS_TYPE_STRING
) {
558 ifname
= os_strdup(entry
.str_value
);
559 wpa_dbus_dict_entry_clear(&entry
);
562 } else if (os_strcmp(entry
.key
, "ConfigFile") == 0 &&
563 entry
.type
== DBUS_TYPE_STRING
) {
565 confname
= os_strdup(entry
.str_value
);
566 wpa_dbus_dict_entry_clear(&entry
);
567 if (confname
== NULL
)
569 } else if (os_strcmp(entry
.key
, "BridgeIfname") == 0 &&
570 entry
.type
== DBUS_TYPE_STRING
) {
571 os_free(bridge_ifname
);
572 bridge_ifname
= os_strdup(entry
.str_value
);
573 wpa_dbus_dict_entry_clear(&entry
);
574 if (bridge_ifname
== NULL
)
577 wpa_dbus_dict_entry_clear(&entry
);
583 goto error
; /* Required Ifname argument missing */
586 * Try to get the wpa_supplicant record for this iface, return
587 * an error if we already control it.
589 if (wpa_supplicant_get_iface(global
, ifname
) != NULL
) {
590 reply
= dbus_message_new_error(
591 message
, WPAS_DBUS_ERROR_IFACE_EXISTS
,
592 "wpa_supplicant already controls this interface.");
594 struct wpa_supplicant
*wpa_s
;
595 struct wpa_interface iface
;
597 os_memset(&iface
, 0, sizeof(iface
));
598 iface
.driver
= driver
;
599 iface
.ifname
= ifname
;
600 iface
.confname
= confname
;
601 iface
.bridge_ifname
= bridge_ifname
;
602 /* Otherwise, have wpa_supplicant attach to it. */
603 wpa_s
= wpa_supplicant_add_iface(global
, &iface
, NULL
);
604 if (wpa_s
&& wpa_s
->dbus_new_path
) {
605 const char *path
= wpa_s
->dbus_new_path
;
607 reply
= dbus_message_new_method_return(message
);
608 dbus_message_append_args(reply
, DBUS_TYPE_OBJECT_PATH
,
609 &path
, DBUS_TYPE_INVALID
);
611 reply
= wpas_dbus_error_unknown_error(
613 "wpa_supplicant couldn't grab this interface.");
621 os_free(bridge_ifname
);
625 reply
= wpas_dbus_error_invalid_args(message
, NULL
);
628 reply
= wpas_dbus_error_no_memory(message
);
634 * wpas_dbus_handler_remove_interface - Request deregistration of an interface
635 * @message: Pointer to incoming dbus message
636 * @global: wpa_supplicant global data structure
637 * Returns: a dbus message containing a UINT32 indicating success (1) or
638 * failure (0), or returns a dbus error message with more information
640 * Handler function for "removeInterface" method call. Handles requests
641 * by dbus clients to deregister a network interface that wpa_supplicant
644 DBusMessage
* wpas_dbus_handler_remove_interface(DBusMessage
*message
,
645 struct wpa_global
*global
)
647 struct wpa_supplicant
*wpa_s
;
649 DBusMessage
*reply
= NULL
;
651 dbus_message_get_args(message
, NULL
, DBUS_TYPE_OBJECT_PATH
, &path
,
654 wpa_s
= get_iface_by_dbus_path(global
, path
);
656 reply
= wpas_dbus_error_iface_unknown(message
);
657 else if (wpa_supplicant_remove_iface(global
, wpa_s
, 0)) {
658 reply
= wpas_dbus_error_unknown_error(
660 "wpa_supplicant couldn't remove this interface.");
668 * wpas_dbus_handler_get_interface - Get the object path for an interface name
669 * @message: Pointer to incoming dbus message
670 * @global: %wpa_supplicant global data structure
671 * Returns: The object path of the interface object,
672 * or a dbus error message with more information
674 * Handler function for "getInterface" method call.
676 DBusMessage
* wpas_dbus_handler_get_interface(DBusMessage
*message
,
677 struct wpa_global
*global
)
679 DBusMessage
*reply
= NULL
;
682 struct wpa_supplicant
*wpa_s
;
684 dbus_message_get_args(message
, NULL
, DBUS_TYPE_STRING
, &ifname
,
687 wpa_s
= wpa_supplicant_get_iface(global
, ifname
);
688 if (wpa_s
== NULL
|| wpa_s
->dbus_new_path
== NULL
)
689 return wpas_dbus_error_iface_unknown(message
);
691 path
= wpa_s
->dbus_new_path
;
692 reply
= dbus_message_new_method_return(message
);
694 return wpas_dbus_error_no_memory(message
);
695 if (!dbus_message_append_args(reply
, DBUS_TYPE_OBJECT_PATH
, &path
,
696 DBUS_TYPE_INVALID
)) {
697 dbus_message_unref(reply
);
698 return wpas_dbus_error_no_memory(message
);
706 * wpas_dbus_getter_debug_level - Get debug level
707 * @iter: Pointer to incoming dbus message iter
708 * @error: Location to store error on failure
709 * @user_data: Function specific data
710 * Returns: TRUE on success, FALSE on failure
712 * Getter for "DebugLevel" property.
714 dbus_bool_t
wpas_dbus_getter_debug_level(DBusMessageIter
*iter
,
719 int idx
= wpa_debug_level
;
725 str
= debug_strings
[idx
];
726 return wpas_dbus_simple_property_getter(iter
, DBUS_TYPE_STRING
,
732 * wpas_dbus_getter_debug_timestamp - Get debug timestamp
733 * @iter: Pointer to incoming dbus message iter
734 * @error: Location to store error on failure
735 * @user_data: Function specific data
736 * Returns: TRUE on success, FALSE on failure
738 * Getter for "DebugTimestamp" property.
740 dbus_bool_t
wpas_dbus_getter_debug_timestamp(DBusMessageIter
*iter
,
744 return wpas_dbus_simple_property_getter(iter
, DBUS_TYPE_BOOLEAN
,
745 &wpa_debug_timestamp
, error
);
751 * wpas_dbus_getter_debug_show_keys - Get debug show keys
752 * @iter: Pointer to incoming dbus message iter
753 * @error: Location to store error on failure
754 * @user_data: Function specific data
755 * Returns: TRUE on success, FALSE on failure
757 * Getter for "DebugShowKeys" property.
759 dbus_bool_t
wpas_dbus_getter_debug_show_keys(DBusMessageIter
*iter
,
763 return wpas_dbus_simple_property_getter(iter
, DBUS_TYPE_BOOLEAN
,
764 &wpa_debug_show_keys
, error
);
769 * wpas_dbus_setter_debug_level - Set debug level
770 * @iter: Pointer to incoming dbus message iter
771 * @error: Location to store error on failure
772 * @user_data: Function specific data
773 * Returns: TRUE on success, FALSE on failure
775 * Setter for "DebugLevel" property.
777 dbus_bool_t
wpas_dbus_setter_debug_level(DBusMessageIter
*iter
,
778 DBusError
*error
, void *user_data
)
780 struct wpa_global
*global
= user_data
;
781 const char *str
= NULL
;
784 if (!wpas_dbus_simple_property_setter(iter
, error
, DBUS_TYPE_STRING
,
788 for (i
= 0; debug_strings
[i
]; i
++)
789 if (os_strcmp(debug_strings
[i
], str
) == 0) {
795 wpa_supplicant_set_debug_params(global
, val
, wpa_debug_timestamp
,
796 wpa_debug_show_keys
)) {
797 dbus_set_error_const(error
, DBUS_ERROR_FAILED
,
798 "wrong debug level value");
807 * wpas_dbus_setter_debug_timestamp - Set debug timestamp
808 * @iter: Pointer to incoming dbus message iter
809 * @error: Location to store error on failure
810 * @user_data: Function specific data
811 * Returns: TRUE on success, FALSE on failure
813 * Setter for "DebugTimestamp" property.
815 dbus_bool_t
wpas_dbus_setter_debug_timestamp(DBusMessageIter
*iter
,
819 struct wpa_global
*global
= user_data
;
822 if (!wpas_dbus_simple_property_setter(iter
, error
, DBUS_TYPE_BOOLEAN
,
826 wpa_supplicant_set_debug_params(global
, wpa_debug_level
, val
? 1 : 0,
827 wpa_debug_show_keys
);
833 * wpas_dbus_setter_debug_show_keys - Set debug show keys
834 * @iter: Pointer to incoming dbus message iter
835 * @error: Location to store error on failure
836 * @user_data: Function specific data
837 * Returns: TRUE on success, FALSE on failure
839 * Setter for "DebugShowKeys" property.
841 dbus_bool_t
wpas_dbus_setter_debug_show_keys(DBusMessageIter
*iter
,
845 struct wpa_global
*global
= user_data
;
848 if (!wpas_dbus_simple_property_setter(iter
, error
, DBUS_TYPE_BOOLEAN
,
852 wpa_supplicant_set_debug_params(global
, wpa_debug_level
,
860 * wpas_dbus_getter_interfaces - Request registered interfaces list
861 * @iter: Pointer to incoming dbus message iter
862 * @error: Location to store error on failure
863 * @user_data: Function specific data
864 * Returns: TRUE on success, FALSE on failure
866 * Getter for "Interfaces" property. Handles requests
867 * by dbus clients to return list of registered interfaces objects
870 dbus_bool_t
wpas_dbus_getter_interfaces(DBusMessageIter
*iter
,
874 struct wpa_global
*global
= user_data
;
875 struct wpa_supplicant
*wpa_s
;
877 unsigned int i
= 0, num
= 0;
880 for (wpa_s
= global
->ifaces
; wpa_s
; wpa_s
= wpa_s
->next
) {
881 if (wpa_s
->dbus_new_path
)
885 paths
= os_calloc(num
, sizeof(char *));
887 dbus_set_error_const(error
, DBUS_ERROR_NO_MEMORY
, "no memory");
891 for (wpa_s
= global
->ifaces
; wpa_s
; wpa_s
= wpa_s
->next
) {
892 if (wpa_s
->dbus_new_path
)
893 paths
[i
++] = wpa_s
->dbus_new_path
;
896 success
= wpas_dbus_simple_array_property_getter(iter
,
897 DBUS_TYPE_OBJECT_PATH
,
906 * wpas_dbus_getter_eap_methods - Request supported EAP methods list
907 * @iter: Pointer to incoming dbus message iter
908 * @error: Location to store error on failure
909 * @user_data: Function specific data
910 * Returns: TRUE on success, FALSE on failure
912 * Getter for "EapMethods" property. Handles requests
913 * by dbus clients to return list of strings with supported EAP methods
915 dbus_bool_t
wpas_dbus_getter_eap_methods(DBusMessageIter
*iter
,
916 DBusError
*error
, void *user_data
)
919 size_t num_items
= 0;
922 eap_methods
= eap_get_names_as_string_array(&num_items
);
924 dbus_set_error_const(error
, DBUS_ERROR_NO_MEMORY
, "no memory");
928 success
= wpas_dbus_simple_array_property_getter(iter
,
934 os_free(eap_methods
[--num_items
]);
935 os_free(eap_methods
);
941 * wpas_dbus_getter_global_capabilities - Request supported global capabilities
942 * @iter: Pointer to incoming dbus message iter
943 * @error: Location to store error on failure
944 * @user_data: Function specific data
945 * Returns: TRUE on success, FALSE on failure
947 * Getter for "Capabilities" property. Handles requests by dbus clients to
948 * return a list of strings with supported capabilities like AP, RSN IBSS,
949 * and P2P that are determined at compile time.
951 dbus_bool_t
wpas_dbus_getter_global_capabilities(DBusMessageIter
*iter
,
955 const char *capabilities
[5] = { NULL
, NULL
, NULL
, NULL
, NULL
};
956 size_t num_items
= 0;
959 capabilities
[num_items
++] = "ap";
960 #endif /* CONFIG_AP */
961 #ifdef CONFIG_IBSS_RSN
962 capabilities
[num_items
++] = "ibss-rsn";
963 #endif /* CONFIG_IBSS_RSN */
965 capabilities
[num_items
++] = "p2p";
966 #endif /* CONFIG_P2P */
967 #ifdef CONFIG_INTERWORKING
968 capabilities
[num_items
++] = "interworking";
969 #endif /* CONFIG_INTERWORKING */
971 return wpas_dbus_simple_array_property_getter(iter
,
978 static int wpas_dbus_get_scan_type(DBusMessage
*message
, DBusMessageIter
*var
,
979 char **type
, DBusMessage
**reply
)
981 if (dbus_message_iter_get_arg_type(var
) != DBUS_TYPE_STRING
) {
982 wpa_printf(MSG_DEBUG
, "%s[dbus]: Type must be a string",
984 *reply
= wpas_dbus_error_invalid_args(
985 message
, "Wrong Type value type. String required");
988 dbus_message_iter_get_basic(var
, type
);
993 static int wpas_dbus_get_scan_ssids(DBusMessage
*message
, DBusMessageIter
*var
,
994 struct wpa_driver_scan_params
*params
,
997 struct wpa_driver_scan_ssid
*ssids
= params
->ssids
;
998 size_t ssids_num
= 0;
1000 DBusMessageIter array_iter
, sub_array_iter
;
1004 if (dbus_message_iter_get_arg_type(var
) != DBUS_TYPE_ARRAY
) {
1005 wpa_printf(MSG_DEBUG
,
1006 "%s[dbus]: ssids must be an array of arrays of bytes",
1008 *reply
= wpas_dbus_error_invalid_args(
1010 "Wrong SSIDs value type. Array of arrays of bytes required");
1014 dbus_message_iter_recurse(var
, &array_iter
);
1016 if (dbus_message_iter_get_arg_type(&array_iter
) != DBUS_TYPE_ARRAY
||
1017 dbus_message_iter_get_element_type(&array_iter
) != DBUS_TYPE_BYTE
) {
1018 wpa_printf(MSG_DEBUG
,
1019 "%s[dbus]: ssids must be an array of arrays of bytes",
1021 *reply
= wpas_dbus_error_invalid_args(
1023 "Wrong SSIDs value type. Array of arrays of bytes required");
1027 while (dbus_message_iter_get_arg_type(&array_iter
) == DBUS_TYPE_ARRAY
) {
1028 if (ssids_num
>= WPAS_MAX_SCAN_SSIDS
) {
1029 wpa_printf(MSG_DEBUG
,
1030 "%s[dbus]: Too many ssids specified on scan dbus call",
1032 *reply
= wpas_dbus_error_invalid_args(
1034 "Too many ssids specified. Specify at most four");
1038 dbus_message_iter_recurse(&array_iter
, &sub_array_iter
);
1040 dbus_message_iter_get_fixed_array(&sub_array_iter
, &val
, &len
);
1042 if (len
> SSID_MAX_LEN
) {
1043 wpa_printf(MSG_DEBUG
,
1044 "%s[dbus]: SSID too long (len=%d max_len=%d)",
1045 __func__
, len
, SSID_MAX_LEN
);
1046 *reply
= wpas_dbus_error_invalid_args(
1047 message
, "Invalid SSID: too long");
1052 ssid
= os_malloc(len
);
1054 *reply
= wpas_dbus_error_no_memory(message
);
1057 os_memcpy(ssid
, val
, len
);
1059 /* Allow zero-length SSIDs */
1063 ssids
[ssids_num
].ssid
= ssid
;
1064 ssids
[ssids_num
].ssid_len
= len
;
1066 dbus_message_iter_next(&array_iter
);
1070 params
->num_ssids
= ssids_num
;
1075 static int wpas_dbus_get_scan_ies(DBusMessage
*message
, DBusMessageIter
*var
,
1076 struct wpa_driver_scan_params
*params
,
1077 DBusMessage
**reply
)
1079 u8
*ies
= NULL
, *nies
;
1081 DBusMessageIter array_iter
, sub_array_iter
;
1085 if (dbus_message_iter_get_arg_type(var
) != DBUS_TYPE_ARRAY
) {
1086 wpa_printf(MSG_DEBUG
,
1087 "%s[dbus]: ies must be an array of arrays of bytes",
1089 *reply
= wpas_dbus_error_invalid_args(
1091 "Wrong IEs value type. Array of arrays of bytes required");
1095 dbus_message_iter_recurse(var
, &array_iter
);
1097 if (dbus_message_iter_get_arg_type(&array_iter
) != DBUS_TYPE_ARRAY
||
1098 dbus_message_iter_get_element_type(&array_iter
) != DBUS_TYPE_BYTE
) {
1099 wpa_printf(MSG_DEBUG
,
1100 "%s[dbus]: ies must be an array of arrays of bytes",
1102 *reply
= wpas_dbus_error_invalid_args(
1103 message
, "Wrong IEs value type. Array required");
1107 while (dbus_message_iter_get_arg_type(&array_iter
) == DBUS_TYPE_ARRAY
) {
1108 dbus_message_iter_recurse(&array_iter
, &sub_array_iter
);
1110 dbus_message_iter_get_fixed_array(&sub_array_iter
, &val
, &len
);
1112 dbus_message_iter_next(&array_iter
);
1116 nies
= os_realloc(ies
, ies_len
+ len
);
1119 *reply
= wpas_dbus_error_no_memory(message
);
1123 os_memcpy(ies
+ ies_len
, val
, len
);
1126 dbus_message_iter_next(&array_iter
);
1129 params
->extra_ies
= ies
;
1130 params
->extra_ies_len
= ies_len
;
1135 static int wpas_dbus_get_scan_channels(DBusMessage
*message
,
1136 DBusMessageIter
*var
,
1137 struct wpa_driver_scan_params
*params
,
1138 DBusMessage
**reply
)
1140 DBusMessageIter array_iter
, sub_array_iter
;
1141 int *freqs
= NULL
, *nfreqs
;
1144 if (dbus_message_iter_get_arg_type(var
) != DBUS_TYPE_ARRAY
) {
1145 wpa_printf(MSG_DEBUG
,
1146 "%s[dbus]: Channels must be an array of structs",
1148 *reply
= wpas_dbus_error_invalid_args(
1150 "Wrong Channels value type. Array of structs required");
1154 dbus_message_iter_recurse(var
, &array_iter
);
1156 if (dbus_message_iter_get_arg_type(&array_iter
) != DBUS_TYPE_STRUCT
) {
1157 wpa_printf(MSG_DEBUG
,
1158 "%s[dbus]: Channels must be an array of structs",
1160 *reply
= wpas_dbus_error_invalid_args(
1162 "Wrong Channels value type. Array of structs required");
1166 while (dbus_message_iter_get_arg_type(&array_iter
) == DBUS_TYPE_STRUCT
)
1170 dbus_message_iter_recurse(&array_iter
, &sub_array_iter
);
1172 if (dbus_message_iter_get_arg_type(&sub_array_iter
) !=
1174 wpa_printf(MSG_DEBUG
,
1175 "%s[dbus]: Channel must by specified by struct of two UINT32s %c",
1177 dbus_message_iter_get_arg_type(
1179 *reply
= wpas_dbus_error_invalid_args(
1181 "Wrong Channel struct. Two UINT32s required");
1185 dbus_message_iter_get_basic(&sub_array_iter
, &freq
);
1187 if (!dbus_message_iter_next(&sub_array_iter
) ||
1188 dbus_message_iter_get_arg_type(&sub_array_iter
) !=
1190 wpa_printf(MSG_DEBUG
,
1191 "%s[dbus]: Channel must by specified by struct of two UINT32s",
1193 *reply
= wpas_dbus_error_invalid_args(
1195 "Wrong Channel struct. Two UINT32s required");
1200 dbus_message_iter_get_basic(&sub_array_iter
, &width
);
1202 #define FREQS_ALLOC_CHUNK 32
1203 if (freqs_num
% FREQS_ALLOC_CHUNK
== 0) {
1204 nfreqs
= os_realloc_array(
1205 freqs
, freqs_num
+ FREQS_ALLOC_CHUNK
,
1211 if (freqs
== NULL
) {
1212 *reply
= wpas_dbus_error_no_memory(message
);
1216 freqs
[freqs_num
] = freq
;
1219 dbus_message_iter_next(&array_iter
);
1222 nfreqs
= os_realloc_array(freqs
, freqs_num
+ 1, sizeof(int));
1226 if (freqs
== NULL
) {
1227 *reply
= wpas_dbus_error_no_memory(message
);
1230 freqs
[freqs_num
] = 0;
1232 params
->freqs
= freqs
;
1237 static int wpas_dbus_get_scan_allow_roam(DBusMessage
*message
,
1238 DBusMessageIter
*var
,
1240 DBusMessage
**reply
)
1242 if (dbus_message_iter_get_arg_type(var
) != DBUS_TYPE_BOOLEAN
) {
1243 wpa_printf(MSG_DEBUG
, "%s[dbus]: Type must be a boolean",
1245 *reply
= wpas_dbus_error_invalid_args(
1246 message
, "Wrong Type value type. Boolean required");
1249 dbus_message_iter_get_basic(var
, allow
);
1255 * wpas_dbus_handler_scan - Request a wireless scan on an interface
1256 * @message: Pointer to incoming dbus message
1257 * @wpa_s: wpa_supplicant structure for a network interface
1258 * Returns: NULL indicating success or DBus error message on failure
1260 * Handler function for "Scan" method call of a network device. Requests
1261 * that wpa_supplicant perform a wireless scan as soon as possible
1262 * on a particular wireless interface.
1264 DBusMessage
* wpas_dbus_handler_scan(DBusMessage
*message
,
1265 struct wpa_supplicant
*wpa_s
)
1267 DBusMessage
*reply
= NULL
;
1268 DBusMessageIter iter
, dict_iter
, entry_iter
, variant_iter
;
1269 char *key
= NULL
, *type
= NULL
;
1270 struct wpa_driver_scan_params params
;
1272 dbus_bool_t allow_roam
= 1;
1274 os_memset(¶ms
, 0, sizeof(params
));
1276 dbus_message_iter_init(message
, &iter
);
1278 dbus_message_iter_recurse(&iter
, &dict_iter
);
1280 while (dbus_message_iter_get_arg_type(&dict_iter
) ==
1281 DBUS_TYPE_DICT_ENTRY
) {
1282 dbus_message_iter_recurse(&dict_iter
, &entry_iter
);
1283 dbus_message_iter_get_basic(&entry_iter
, &key
);
1284 dbus_message_iter_next(&entry_iter
);
1285 dbus_message_iter_recurse(&entry_iter
, &variant_iter
);
1287 if (os_strcmp(key
, "Type") == 0) {
1288 if (wpas_dbus_get_scan_type(message
, &variant_iter
,
1291 } else if (os_strcmp(key
, "SSIDs") == 0) {
1292 if (wpas_dbus_get_scan_ssids(message
, &variant_iter
,
1293 ¶ms
, &reply
) < 0)
1295 } else if (os_strcmp(key
, "IEs") == 0) {
1296 if (wpas_dbus_get_scan_ies(message
, &variant_iter
,
1297 ¶ms
, &reply
) < 0)
1299 } else if (os_strcmp(key
, "Channels") == 0) {
1300 if (wpas_dbus_get_scan_channels(message
, &variant_iter
,
1301 ¶ms
, &reply
) < 0)
1303 } else if (os_strcmp(key
, "AllowRoam") == 0) {
1304 if (wpas_dbus_get_scan_allow_roam(message
,
1310 wpa_printf(MSG_DEBUG
, "%s[dbus]: Unknown argument %s",
1312 reply
= wpas_dbus_error_invalid_args(message
, key
);
1316 dbus_message_iter_next(&dict_iter
);
1320 wpa_printf(MSG_DEBUG
, "%s[dbus]: Scan type not specified",
1322 reply
= wpas_dbus_error_invalid_args(message
, key
);
1326 if (os_strcmp(type
, "passive") == 0) {
1327 if (params
.num_ssids
|| params
.extra_ies_len
) {
1328 wpa_printf(MSG_DEBUG
,
1329 "%s[dbus]: SSIDs or IEs specified for passive scan.",
1331 reply
= wpas_dbus_error_invalid_args(
1333 "You can specify only Channels in passive scan");
1336 if (wpa_s
->sched_scanning
) {
1337 wpa_printf(MSG_DEBUG
,
1338 "%s[dbus]: Stop ongoing sched_scan to allow requested scan to proceed",
1340 wpa_supplicant_cancel_sched_scan(wpa_s
);
1343 if (params
.freqs
&& params
.freqs
[0]) {
1344 wpa_s
->last_scan_req
= MANUAL_SCAN_REQ
;
1345 if (wpa_supplicant_trigger_scan(wpa_s
,
1347 reply
= wpas_dbus_error_scan_error(
1349 "Scan request rejected");
1352 wpa_s
->scan_req
= MANUAL_SCAN_REQ
;
1353 wpa_supplicant_req_scan(wpa_s
, 0, 0);
1356 } else if (os_strcmp(type
, "active") == 0) {
1357 if (!params
.num_ssids
) {
1358 /* Add wildcard ssid */
1361 #ifdef CONFIG_AUTOSCAN
1362 autoscan_deinit(wpa_s
);
1363 #endif /* CONFIG_AUTOSCAN */
1364 if (wpa_s
->sched_scanning
) {
1365 wpa_printf(MSG_DEBUG
,
1366 "%s[dbus]: Stop ongoing sched_scan to allow requested scan to proceed",
1368 wpa_supplicant_cancel_sched_scan(wpa_s
);
1371 wpa_s
->last_scan_req
= MANUAL_SCAN_REQ
;
1372 if (wpa_supplicant_trigger_scan(wpa_s
, ¶ms
)) {
1373 reply
= wpas_dbus_error_scan_error(
1374 message
, "Scan request rejected");
1377 wpa_printf(MSG_DEBUG
, "%s[dbus]: Unknown scan type: %s",
1379 reply
= wpas_dbus_error_invalid_args(message
,
1385 wpa_s
->scan_res_handler
= scan_only_handler
;
1388 for (i
= 0; i
< WPAS_MAX_SCAN_SSIDS
; i
++)
1389 os_free((u8
*) params
.ssids
[i
].ssid
);
1390 os_free((u8
*) params
.extra_ies
);
1391 os_free(params
.freqs
);
1397 * wpas_dbus_handler_signal_poll - Request immediate signal properties
1398 * @message: Pointer to incoming dbus message
1399 * @wpa_s: wpa_supplicant structure for a network interface
1400 * Returns: NULL indicating success or DBus error message on failure
1402 * Handler function for "SignalPoll" method call of a network device. Requests
1403 * that wpa_supplicant read signal properties like RSSI, noise, and link
1404 * speed and return them.
1406 DBusMessage
* wpas_dbus_handler_signal_poll(DBusMessage
*message
,
1407 struct wpa_supplicant
*wpa_s
)
1409 struct wpa_signal_info si
;
1410 DBusMessage
*reply
= NULL
;
1411 DBusMessageIter iter
, iter_dict
, variant_iter
;
1414 ret
= wpa_drv_signal_poll(wpa_s
, &si
);
1416 return dbus_message_new_error(message
, DBUS_ERROR_FAILED
,
1417 "Failed to read signal");
1420 reply
= dbus_message_new_method_return(message
);
1424 dbus_message_iter_init_append(reply
, &iter
);
1426 if (!dbus_message_iter_open_container(&iter
, DBUS_TYPE_VARIANT
,
1427 "a{sv}", &variant_iter
) ||
1428 !wpa_dbus_dict_open_write(&variant_iter
, &iter_dict
) ||
1429 !wpa_dbus_dict_append_int32(&iter_dict
, "rssi",
1430 si
.current_signal
) ||
1431 !wpa_dbus_dict_append_int32(&iter_dict
, "linkspeed",
1432 si
.current_txrate
/ 1000) ||
1433 !wpa_dbus_dict_append_int32(&iter_dict
, "noise",
1434 si
.current_noise
) ||
1435 !wpa_dbus_dict_append_uint32(&iter_dict
, "frequency",
1437 (si
.chanwidth
!= CHAN_WIDTH_UNKNOWN
&&
1438 !wpa_dbus_dict_append_string(
1439 &iter_dict
, "width",
1440 channel_width_to_string(si
.chanwidth
))) ||
1441 (si
.center_frq1
> 0 && si
.center_frq2
> 0 &&
1442 (!wpa_dbus_dict_append_int32(&iter_dict
, "center-frq1",
1444 !wpa_dbus_dict_append_int32(&iter_dict
, "center-frq2",
1445 si
.center_frq2
))) ||
1447 !wpa_dbus_dict_append_int32(&iter_dict
, "avg-rssi",
1449 !wpa_dbus_dict_close_write(&variant_iter
, &iter_dict
) ||
1450 !dbus_message_iter_close_container(&iter
, &variant_iter
))
1457 dbus_message_unref(reply
);
1458 return wpas_dbus_error_no_memory(message
);
1463 * wpas_dbus_handler_disconnect - Terminate the current connection
1464 * @message: Pointer to incoming dbus message
1465 * @wpa_s: wpa_supplicant structure for a network interface
1466 * Returns: NotConnected DBus error message if already not connected
1467 * or NULL otherwise.
1469 * Handler function for "Disconnect" method call of network interface.
1471 DBusMessage
* wpas_dbus_handler_disconnect(DBusMessage
*message
,
1472 struct wpa_supplicant
*wpa_s
)
1474 if (wpa_s
->current_ssid
!= NULL
) {
1475 wpa_s
->disconnected
= 1;
1476 wpa_supplicant_deauthenticate(wpa_s
,
1477 WLAN_REASON_DEAUTH_LEAVING
);
1482 return dbus_message_new_error(message
, WPAS_DBUS_ERROR_NOT_CONNECTED
,
1483 "This interface is not connected");
1488 * wpas_dbus_new_iface_add_network - Add a new configured network
1489 * @message: Pointer to incoming dbus message
1490 * @wpa_s: wpa_supplicant structure for a network interface
1491 * Returns: A dbus message containing the object path of the new network
1493 * Handler function for "AddNetwork" method call of a network interface.
1495 DBusMessage
* wpas_dbus_handler_add_network(DBusMessage
*message
,
1496 struct wpa_supplicant
*wpa_s
)
1498 DBusMessage
*reply
= NULL
;
1499 DBusMessageIter iter
;
1500 struct wpa_ssid
*ssid
= NULL
;
1501 char path_buf
[WPAS_DBUS_OBJECT_PATH_MAX
], *path
= path_buf
;
1504 dbus_message_iter_init(message
, &iter
);
1506 if (wpa_s
->dbus_new_path
)
1507 ssid
= wpa_config_add_network(wpa_s
->conf
);
1509 wpa_printf(MSG_ERROR
, "%s[dbus]: can't add new interface.",
1511 reply
= wpas_dbus_error_unknown_error(
1513 "wpa_supplicant could not add a network on this interface.");
1516 wpas_notify_network_added(wpa_s
, ssid
);
1518 wpa_config_set_network_defaults(ssid
);
1520 dbus_error_init(&error
);
1521 if (!set_network_properties(wpa_s
, ssid
, &iter
, &error
)) {
1522 wpa_printf(MSG_DEBUG
,
1523 "%s[dbus]: control interface couldn't set network properties",
1525 reply
= wpas_dbus_reply_new_from_error(message
, &error
,
1526 DBUS_ERROR_INVALID_ARGS
,
1527 "Failed to add network");
1528 dbus_error_free(&error
);
1532 /* Construct the object path for this network. */
1533 os_snprintf(path
, WPAS_DBUS_OBJECT_PATH_MAX
,
1534 "%s/" WPAS_DBUS_NEW_NETWORKS_PART
"/%d",
1535 wpa_s
->dbus_new_path
, ssid
->id
);
1537 reply
= dbus_message_new_method_return(message
);
1538 if (reply
== NULL
) {
1539 reply
= wpas_dbus_error_no_memory(message
);
1542 if (!dbus_message_append_args(reply
, DBUS_TYPE_OBJECT_PATH
, &path
,
1543 DBUS_TYPE_INVALID
)) {
1544 dbus_message_unref(reply
);
1545 reply
= wpas_dbus_error_no_memory(message
);
1553 wpas_notify_network_removed(wpa_s
, ssid
);
1554 wpa_config_remove_network(wpa_s
->conf
, ssid
->id
);
1561 * wpas_dbus_handler_reassociate - Reassociate
1562 * @message: Pointer to incoming dbus message
1563 * @wpa_s: wpa_supplicant structure for a network interface
1564 * Returns: InterfaceDisabled DBus error message if disabled
1565 * or NULL otherwise.
1567 * Handler function for "Reassociate" method call of network interface.
1569 DBusMessage
* wpas_dbus_handler_reassociate(DBusMessage
*message
,
1570 struct wpa_supplicant
*wpa_s
)
1572 if (wpa_s
->wpa_state
!= WPA_INTERFACE_DISABLED
) {
1573 wpas_request_connection(wpa_s
);
1577 return dbus_message_new_error(message
, WPAS_DBUS_ERROR_IFACE_DISABLED
,
1578 "This interface is disabled");
1583 * wpas_dbus_handler_reattach - Reattach to current AP
1584 * @message: Pointer to incoming dbus message
1585 * @wpa_s: wpa_supplicant structure for a network interface
1586 * Returns: NotConnected DBus error message if not connected
1587 * or NULL otherwise.
1589 * Handler function for "Reattach" method call of network interface.
1591 DBusMessage
* wpas_dbus_handler_reattach(DBusMessage
*message
,
1592 struct wpa_supplicant
*wpa_s
)
1594 if (wpa_s
->current_ssid
!= NULL
) {
1595 wpa_s
->reattach
= 1;
1596 wpas_request_connection(wpa_s
);
1600 return dbus_message_new_error(message
, WPAS_DBUS_ERROR_NOT_CONNECTED
,
1601 "This interface is not connected");
1606 * wpas_dbus_handler_reconnect - Reconnect if disconnected
1607 * @message: Pointer to incoming dbus message
1608 * @wpa_s: wpa_supplicant structure for a network interface
1609 * Returns: InterfaceDisabled DBus error message if disabled
1610 * or NULL otherwise.
1612 * Handler function for "Reconnect" method call of network interface.
1614 DBusMessage
* wpas_dbus_handler_reconnect(DBusMessage
*message
,
1615 struct wpa_supplicant
*wpa_s
)
1617 if (wpa_s
->wpa_state
== WPA_INTERFACE_DISABLED
) {
1618 return dbus_message_new_error(message
,
1619 WPAS_DBUS_ERROR_IFACE_DISABLED
,
1620 "This interface is disabled");
1623 if (wpa_s
->disconnected
)
1624 wpas_request_connection(wpa_s
);
1630 * wpas_dbus_handler_remove_network - Remove a configured network
1631 * @message: Pointer to incoming dbus message
1632 * @wpa_s: wpa_supplicant structure for a network interface
1633 * Returns: NULL on success or dbus error on failure
1635 * Handler function for "RemoveNetwork" method call of a network interface.
1637 DBusMessage
* wpas_dbus_handler_remove_network(DBusMessage
*message
,
1638 struct wpa_supplicant
*wpa_s
)
1640 DBusMessage
*reply
= NULL
;
1642 char *iface
, *net_id
;
1644 struct wpa_ssid
*ssid
;
1647 dbus_message_get_args(message
, NULL
, DBUS_TYPE_OBJECT_PATH
, &op
,
1650 /* Extract the network ID and ensure the network */
1651 /* is actually a child of this interface */
1652 iface
= wpas_dbus_new_decompose_object_path(op
,
1653 WPAS_DBUS_NEW_NETWORKS_PART
,
1655 if (iface
== NULL
|| net_id
== NULL
|| !wpa_s
->dbus_new_path
||
1656 os_strcmp(iface
, wpa_s
->dbus_new_path
) != 0) {
1657 reply
= wpas_dbus_error_invalid_args(message
, op
);
1662 id
= strtoul(net_id
, NULL
, 10);
1664 reply
= wpas_dbus_error_invalid_args(message
, op
);
1668 ssid
= wpa_config_get_network(wpa_s
->conf
, id
);
1670 reply
= wpas_dbus_error_network_unknown(message
);
1674 was_disabled
= ssid
->disabled
;
1676 wpas_notify_network_removed(wpa_s
, ssid
);
1678 if (ssid
== wpa_s
->current_ssid
)
1679 wpa_supplicant_deauthenticate(wpa_s
,
1680 WLAN_REASON_DEAUTH_LEAVING
);
1681 else if (!was_disabled
&& wpa_s
->sched_scanning
) {
1682 wpa_printf(MSG_DEBUG
,
1683 "Stop ongoing sched_scan to remove network from filters");
1684 wpa_supplicant_cancel_sched_scan(wpa_s
);
1685 wpa_supplicant_req_scan(wpa_s
, 0, 0);
1688 if (wpa_config_remove_network(wpa_s
->conf
, id
) < 0) {
1689 wpa_printf(MSG_ERROR
,
1690 "%s[dbus]: error occurred when removing network %d",
1692 reply
= wpas_dbus_error_unknown_error(
1694 "error removing the specified network on is interface.");
1704 static void remove_network(void *arg
, struct wpa_ssid
*ssid
)
1706 struct wpa_supplicant
*wpa_s
= arg
;
1708 wpas_notify_network_removed(wpa_s
, ssid
);
1710 if (wpa_config_remove_network(wpa_s
->conf
, ssid
->id
) < 0) {
1711 wpa_printf(MSG_ERROR
,
1712 "%s[dbus]: error occurred when removing network %d",
1713 __func__
, ssid
->id
);
1717 if (ssid
== wpa_s
->current_ssid
)
1718 wpa_supplicant_deauthenticate(wpa_s
,
1719 WLAN_REASON_DEAUTH_LEAVING
);
1724 * wpas_dbus_handler_remove_all_networks - Remove all configured networks
1725 * @message: Pointer to incoming dbus message
1726 * @wpa_s: wpa_supplicant structure for a network interface
1727 * Returns: NULL on success or dbus error on failure
1729 * Handler function for "RemoveAllNetworks" method call of a network interface.
1731 DBusMessage
* wpas_dbus_handler_remove_all_networks(
1732 DBusMessage
*message
, struct wpa_supplicant
*wpa_s
)
1734 if (wpa_s
->sched_scanning
)
1735 wpa_supplicant_cancel_sched_scan(wpa_s
);
1737 /* NB: could check for failure and return an error */
1738 wpa_config_foreach_network(wpa_s
->conf
, remove_network
, wpa_s
);
1744 * wpas_dbus_handler_select_network - Attempt association with a network
1745 * @message: Pointer to incoming dbus message
1746 * @wpa_s: wpa_supplicant structure for a network interface
1747 * Returns: NULL on success or dbus error on failure
1749 * Handler function for "SelectNetwork" method call of network interface.
1751 DBusMessage
* wpas_dbus_handler_select_network(DBusMessage
*message
,
1752 struct wpa_supplicant
*wpa_s
)
1754 DBusMessage
*reply
= NULL
;
1756 char *iface
, *net_id
;
1758 struct wpa_ssid
*ssid
;
1760 dbus_message_get_args(message
, NULL
, DBUS_TYPE_OBJECT_PATH
, &op
,
1763 /* Extract the network ID and ensure the network */
1764 /* is actually a child of this interface */
1765 iface
= wpas_dbus_new_decompose_object_path(op
,
1766 WPAS_DBUS_NEW_NETWORKS_PART
,
1768 if (iface
== NULL
|| net_id
== NULL
|| !wpa_s
->dbus_new_path
||
1769 os_strcmp(iface
, wpa_s
->dbus_new_path
) != 0) {
1770 reply
= wpas_dbus_error_invalid_args(message
, op
);
1775 id
= strtoul(net_id
, NULL
, 10);
1777 reply
= wpas_dbus_error_invalid_args(message
, op
);
1781 ssid
= wpa_config_get_network(wpa_s
->conf
, id
);
1783 reply
= wpas_dbus_error_network_unknown(message
);
1787 /* Finally, associate with the network */
1788 wpa_supplicant_select_network(wpa_s
, ssid
);
1797 * wpas_dbus_handler_network_reply - Reply to a NetworkRequest signal
1798 * @message: Pointer to incoming dbus message
1799 * @wpa_s: wpa_supplicant structure for a network interface
1800 * Returns: NULL on success or dbus error on failure
1802 * Handler function for "NetworkReply" method call of network interface.
1804 DBusMessage
* wpas_dbus_handler_network_reply(DBusMessage
*message
,
1805 struct wpa_supplicant
*wpa_s
)
1807 #ifdef IEEE8021X_EAPOL
1808 DBusMessage
*reply
= NULL
;
1809 const char *op
, *field
, *value
;
1810 char *iface
, *net_id
;
1812 struct wpa_ssid
*ssid
;
1814 if (!dbus_message_get_args(message
, NULL
,
1815 DBUS_TYPE_OBJECT_PATH
, &op
,
1816 DBUS_TYPE_STRING
, &field
,
1817 DBUS_TYPE_STRING
, &value
,
1819 return wpas_dbus_error_invalid_args(message
, NULL
);
1821 /* Extract the network ID and ensure the network */
1822 /* is actually a child of this interface */
1823 iface
= wpas_dbus_new_decompose_object_path(op
,
1824 WPAS_DBUS_NEW_NETWORKS_PART
,
1826 if (iface
== NULL
|| net_id
== NULL
|| !wpa_s
->dbus_new_path
||
1827 os_strcmp(iface
, wpa_s
->dbus_new_path
) != 0) {
1828 reply
= wpas_dbus_error_invalid_args(message
, op
);
1833 id
= strtoul(net_id
, NULL
, 10);
1835 reply
= wpas_dbus_error_invalid_args(message
, net_id
);
1839 ssid
= wpa_config_get_network(wpa_s
->conf
, id
);
1841 reply
= wpas_dbus_error_network_unknown(message
);
1845 if (wpa_supplicant_ctrl_iface_ctrl_rsp_handle(wpa_s
, ssid
,
1847 reply
= wpas_dbus_error_invalid_args(message
, field
);
1849 /* Tell EAP to retry immediately */
1850 eapol_sm_notify_ctrl_response(wpa_s
->eapol
);
1856 #else /* IEEE8021X_EAPOL */
1857 wpa_printf(MSG_DEBUG
, "CTRL_IFACE: 802.1X not included");
1858 return wpas_dbus_error_unknown_error(message
, "802.1X not included");
1859 #endif /* IEEE8021X_EAPOL */
1863 #ifndef CONFIG_NO_CONFIG_BLOBS
1866 * wpas_dbus_handler_add_blob - Store named binary blob (ie, for certificates)
1867 * @message: Pointer to incoming dbus message
1868 * @wpa_s: %wpa_supplicant data structure
1869 * Returns: A dbus message containing an error on failure or NULL on success
1871 * Asks wpa_supplicant to internally store a binary blobs.
1873 DBusMessage
* wpas_dbus_handler_add_blob(DBusMessage
*message
,
1874 struct wpa_supplicant
*wpa_s
)
1876 DBusMessage
*reply
= NULL
;
1877 DBusMessageIter iter
, array_iter
;
1882 struct wpa_config_blob
*blob
= NULL
;
1884 dbus_message_iter_init(message
, &iter
);
1885 dbus_message_iter_get_basic(&iter
, &blob_name
);
1887 if (wpa_config_get_blob(wpa_s
->conf
, blob_name
)) {
1888 return dbus_message_new_error(message
,
1889 WPAS_DBUS_ERROR_BLOB_EXISTS
,
1893 dbus_message_iter_next(&iter
);
1894 dbus_message_iter_recurse(&iter
, &array_iter
);
1896 dbus_message_iter_get_fixed_array(&array_iter
, &blob_data
, &blob_len
);
1898 blob
= os_zalloc(sizeof(*blob
));
1900 reply
= wpas_dbus_error_no_memory(message
);
1904 blob
->data
= os_malloc(blob_len
);
1905 blob
->name
= os_strdup(blob_name
);
1906 if (!blob
->data
|| !blob
->name
) {
1907 reply
= wpas_dbus_error_no_memory(message
);
1910 os_memcpy(blob
->data
, blob_data
, blob_len
);
1911 blob
->len
= blob_len
;
1913 wpa_config_set_blob(wpa_s
->conf
, blob
);
1914 wpas_notify_blob_added(wpa_s
, blob
->name
);
1920 os_free(blob
->name
);
1921 os_free(blob
->data
);
1929 * wpas_dbus_handler_get_blob - Get named binary blob (ie, for certificates)
1930 * @message: Pointer to incoming dbus message
1931 * @wpa_s: %wpa_supplicant data structure
1932 * Returns: A dbus message containing array of bytes (blob)
1934 * Gets one wpa_supplicant's binary blobs.
1936 DBusMessage
* wpas_dbus_handler_get_blob(DBusMessage
*message
,
1937 struct wpa_supplicant
*wpa_s
)
1939 DBusMessage
*reply
= NULL
;
1940 DBusMessageIter iter
, array_iter
;
1943 const struct wpa_config_blob
*blob
;
1945 dbus_message_get_args(message
, NULL
, DBUS_TYPE_STRING
, &blob_name
,
1948 blob
= wpa_config_get_blob(wpa_s
->conf
, blob_name
);
1950 return dbus_message_new_error(message
,
1951 WPAS_DBUS_ERROR_BLOB_UNKNOWN
,
1955 reply
= dbus_message_new_method_return(message
);
1957 return wpas_dbus_error_no_memory(message
);
1959 dbus_message_iter_init_append(reply
, &iter
);
1961 if (!dbus_message_iter_open_container(&iter
, DBUS_TYPE_ARRAY
,
1962 DBUS_TYPE_BYTE_AS_STRING
,
1964 !dbus_message_iter_append_fixed_array(&array_iter
, DBUS_TYPE_BYTE
,
1965 &(blob
->data
), blob
->len
) ||
1966 !dbus_message_iter_close_container(&iter
, &array_iter
)) {
1967 dbus_message_unref(reply
);
1968 reply
= wpas_dbus_error_no_memory(message
);
1976 * wpas_remove_handler_remove_blob - Remove named binary blob
1977 * @message: Pointer to incoming dbus message
1978 * @wpa_s: %wpa_supplicant data structure
1979 * Returns: NULL on success or dbus error
1981 * Asks wpa_supplicant to internally remove a binary blobs.
1983 DBusMessage
* wpas_dbus_handler_remove_blob(DBusMessage
*message
,
1984 struct wpa_supplicant
*wpa_s
)
1986 DBusMessage
*reply
= NULL
;
1989 dbus_message_get_args(message
, NULL
, DBUS_TYPE_STRING
, &blob_name
,
1992 if (wpa_config_remove_blob(wpa_s
->conf
, blob_name
)) {
1993 return dbus_message_new_error(message
,
1994 WPAS_DBUS_ERROR_BLOB_UNKNOWN
,
1997 wpas_notify_blob_removed(wpa_s
, blob_name
);
2003 #endif /* CONFIG_NO_CONFIG_BLOBS */
2007 * wpas_dbus_handler_flush_bss - Flush the BSS cache
2008 * @message: Pointer to incoming dbus message
2009 * @wpa_s: wpa_supplicant structure for a network interface
2012 * Handler function for "FlushBSS" method call of network interface.
2014 DBusMessage
* wpas_dbus_handler_flush_bss(DBusMessage
*message
,
2015 struct wpa_supplicant
*wpa_s
)
2019 dbus_message_get_args(message
, NULL
, DBUS_TYPE_UINT32
, &age
,
2023 wpa_bss_flush(wpa_s
);
2025 wpa_bss_flush_by_age(wpa_s
, age
);
2031 #ifdef CONFIG_AUTOSCAN
2033 * wpas_dbus_handler_autoscan - Set autoscan parameters for the interface
2034 * @message: Pointer to incoming dbus message
2035 * @wpa_s: wpa_supplicant structure for a network interface
2038 * Handler function for "AutoScan" method call of network interface.
2040 DBusMessage
* wpas_dbus_handler_autoscan(DBusMessage
*message
,
2041 struct wpa_supplicant
*wpa_s
)
2043 DBusMessage
*reply
= NULL
;
2044 enum wpa_states state
= wpa_s
->wpa_state
;
2047 dbus_message_get_args(message
, NULL
, DBUS_TYPE_STRING
, &arg
,
2050 if (arg
!= NULL
&& os_strlen(arg
) > 0) {
2053 tmp
= os_strdup(arg
);
2055 reply
= wpas_dbus_error_no_memory(message
);
2057 os_free(wpa_s
->conf
->autoscan
);
2058 wpa_s
->conf
->autoscan
= tmp
;
2059 if (state
== WPA_DISCONNECTED
|| state
== WPA_INACTIVE
)
2060 autoscan_init(wpa_s
, 1);
2061 else if (state
== WPA_SCANNING
)
2062 wpa_supplicant_reinit_autoscan(wpa_s
);
2064 } else if (arg
!= NULL
&& os_strlen(arg
) == 0) {
2065 os_free(wpa_s
->conf
->autoscan
);
2066 wpa_s
->conf
->autoscan
= NULL
;
2067 autoscan_deinit(wpa_s
);
2069 reply
= dbus_message_new_error(message
,
2070 DBUS_ERROR_INVALID_ARGS
,
2075 #endif /* CONFIG_AUTOSCAN */
2079 * wpas_dbus_handler_eap_logoff - IEEE 802.1X EAPOL state machine logoff
2080 * @message: Pointer to incoming dbus message
2081 * @wpa_s: wpa_supplicant structure for a network interface
2084 * Handler function for "EAPLogoff" method call of network interface.
2086 DBusMessage
* wpas_dbus_handler_eap_logoff(DBusMessage
*message
,
2087 struct wpa_supplicant
*wpa_s
)
2089 eapol_sm_notify_logoff(wpa_s
->eapol
, TRUE
);
2095 * wpas_dbus_handler_eap_logon - IEEE 802.1X EAPOL state machine logon
2096 * @message: Pointer to incoming dbus message
2097 * @wpa_s: wpa_supplicant structure for a network interface
2100 * Handler function for "EAPLogin" method call of network interface.
2102 DBusMessage
* wpas_dbus_handler_eap_logon(DBusMessage
*message
,
2103 struct wpa_supplicant
*wpa_s
)
2105 eapol_sm_notify_logoff(wpa_s
->eapol
, FALSE
);
2112 static int get_peer_hwaddr_helper(DBusMessage
*message
, const char *func_name
,
2113 u8
*peer_address
, DBusMessage
**error
)
2115 const char *peer_string
;
2119 if (!dbus_message_get_args(message
, NULL
,
2120 DBUS_TYPE_STRING
, &peer_string
,
2121 DBUS_TYPE_INVALID
)) {
2122 *error
= wpas_dbus_error_invalid_args(message
, NULL
);
2126 if (hwaddr_aton(peer_string
, peer_address
)) {
2127 wpa_printf(MSG_DEBUG
, "%s: invalid address '%s'",
2128 func_name
, peer_string
);
2129 *error
= wpas_dbus_error_invalid_args(
2130 message
, "Invalid hardware address format");
2139 * wpas_dbus_handler_tdls_discover - Discover TDLS peer
2140 * @message: Pointer to incoming dbus message
2141 * @wpa_s: wpa_supplicant structure for a network interface
2142 * Returns: NULL indicating success or DBus error message on failure
2144 * Handler function for "TDLSDiscover" method call of network interface.
2146 DBusMessage
* wpas_dbus_handler_tdls_discover(DBusMessage
*message
,
2147 struct wpa_supplicant
*wpa_s
)
2150 DBusMessage
*error_reply
;
2153 if (get_peer_hwaddr_helper(message
, __func__
, peer
, &error_reply
) < 0)
2156 wpa_printf(MSG_DEBUG
, "DBUS TDLS_DISCOVER " MACSTR
, MAC2STR(peer
));
2158 if (wpa_tdls_is_external_setup(wpa_s
->wpa
))
2159 ret
= wpa_tdls_send_discovery_request(wpa_s
->wpa
, peer
);
2161 ret
= wpa_drv_tdls_oper(wpa_s
, TDLS_DISCOVERY_REQ
, peer
);
2164 return wpas_dbus_error_unknown_error(
2165 message
, "error performing TDLS discovery");
2173 * wpas_dbus_handler_tdls_setup - Setup TDLS session
2174 * @message: Pointer to incoming dbus message
2175 * @wpa_s: wpa_supplicant structure for a network interface
2176 * Returns: NULL indicating success or DBus error message on failure
2178 * Handler function for "TDLSSetup" method call of network interface.
2180 DBusMessage
* wpas_dbus_handler_tdls_setup(DBusMessage
*message
,
2181 struct wpa_supplicant
*wpa_s
)
2184 DBusMessage
*error_reply
;
2187 if (get_peer_hwaddr_helper(message
, __func__
, peer
, &error_reply
) < 0)
2190 wpa_printf(MSG_DEBUG
, "DBUS TDLS_SETUP " MACSTR
, MAC2STR(peer
));
2192 wpa_tdls_remove(wpa_s
->wpa
, peer
);
2193 if (wpa_tdls_is_external_setup(wpa_s
->wpa
))
2194 ret
= wpa_tdls_start(wpa_s
->wpa
, peer
);
2196 ret
= wpa_drv_tdls_oper(wpa_s
, TDLS_SETUP
, peer
);
2199 return wpas_dbus_error_unknown_error(
2200 message
, "error performing TDLS setup");
2208 * wpas_dbus_handler_tdls_status - Return TDLS session status
2209 * @message: Pointer to incoming dbus message
2210 * @wpa_s: wpa_supplicant structure for a network interface
2211 * Returns: A string representing the state of the link to this TDLS peer
2213 * Handler function for "TDLSStatus" method call of network interface.
2215 DBusMessage
* wpas_dbus_handler_tdls_status(DBusMessage
*message
,
2216 struct wpa_supplicant
*wpa_s
)
2220 const char *tdls_status
;
2222 if (get_peer_hwaddr_helper(message
, __func__
, peer
, &reply
) < 0)
2225 wpa_printf(MSG_DEBUG
, "DBUS TDLS_STATUS " MACSTR
, MAC2STR(peer
));
2227 tdls_status
= wpa_tdls_get_link_status(wpa_s
->wpa
, peer
);
2229 reply
= dbus_message_new_method_return(message
);
2230 dbus_message_append_args(reply
, DBUS_TYPE_STRING
,
2231 &tdls_status
, DBUS_TYPE_INVALID
);
2237 * wpas_dbus_handler_tdls_teardown - Teardown TDLS session
2238 * @message: Pointer to incoming dbus message
2239 * @wpa_s: wpa_supplicant structure for a network interface
2240 * Returns: NULL indicating success or DBus error message on failure
2242 * Handler function for "TDLSTeardown" method call of network interface.
2244 DBusMessage
* wpas_dbus_handler_tdls_teardown(DBusMessage
*message
,
2245 struct wpa_supplicant
*wpa_s
)
2248 DBusMessage
*error_reply
;
2251 if (get_peer_hwaddr_helper(message
, __func__
, peer
, &error_reply
) < 0)
2254 wpa_printf(MSG_DEBUG
, "DBUS TDLS_TEARDOWN " MACSTR
, MAC2STR(peer
));
2256 if (wpa_tdls_is_external_setup(wpa_s
->wpa
))
2257 ret
= wpa_tdls_teardown_link(
2259 WLAN_REASON_TDLS_TEARDOWN_UNSPECIFIED
);
2261 ret
= wpa_drv_tdls_oper(wpa_s
, TDLS_TEARDOWN
, peer
);
2264 return wpas_dbus_error_unknown_error(
2265 message
, "error performing TDLS teardown");
2271 #endif /* CONFIG_TDLS */
2275 * wpas_dbus_handler_set_pkcs11_engine_and_module_path - Set PKCS #11 engine and module path
2276 * @message: Pointer to incoming dbus message
2277 * @wpa_s: %wpa_supplicant data structure
2278 * Returns: A dbus message containing an error on failure or NULL on success
2280 * Sets the PKCS #11 engine and module path.
2282 DBusMessage
* wpas_dbus_handler_set_pkcs11_engine_and_module_path(
2283 DBusMessage
*message
, struct wpa_supplicant
*wpa_s
)
2285 DBusMessageIter iter
;
2287 char *pkcs11_engine_path
= NULL
;
2288 char *pkcs11_module_path
= NULL
;
2290 dbus_message_iter_init(message
, &iter
);
2291 dbus_message_iter_get_basic(&iter
, &value
);
2292 if (value
== NULL
) {
2293 return dbus_message_new_error(
2294 message
, DBUS_ERROR_INVALID_ARGS
,
2295 "Invalid pkcs11_engine_path argument");
2297 /* Empty path defaults to NULL */
2298 if (os_strlen(value
))
2299 pkcs11_engine_path
= value
;
2301 dbus_message_iter_next(&iter
);
2302 dbus_message_iter_get_basic(&iter
, &value
);
2303 if (value
== NULL
) {
2304 os_free(pkcs11_engine_path
);
2305 return dbus_message_new_error(
2306 message
, DBUS_ERROR_INVALID_ARGS
,
2307 "Invalid pkcs11_module_path argument");
2309 /* Empty path defaults to NULL */
2310 if (os_strlen(value
))
2311 pkcs11_module_path
= value
;
2313 if (wpas_set_pkcs11_engine_and_module_path(wpa_s
, pkcs11_engine_path
,
2314 pkcs11_module_path
))
2315 return dbus_message_new_error(
2316 message
, DBUS_ERROR_FAILED
,
2317 "Reinit of the EAPOL state machine with the new PKCS #11 engine and module path failed.");
2319 if (wpa_s
->dbus_new_path
) {
2320 wpa_dbus_mark_property_changed(
2321 wpa_s
->global
->dbus
, wpa_s
->dbus_new_path
,
2322 WPAS_DBUS_NEW_IFACE_INTERFACE
, "PKCS11EnginePath");
2323 wpa_dbus_mark_property_changed(
2324 wpa_s
->global
->dbus
, wpa_s
->dbus_new_path
,
2325 WPAS_DBUS_NEW_IFACE_INTERFACE
, "PKCS11ModulePath");
2333 * wpas_dbus_getter_capabilities - Return interface capabilities
2334 * @iter: Pointer to incoming dbus message iter
2335 * @error: Location to store error on failure
2336 * @user_data: Function specific data
2337 * Returns: TRUE on success, FALSE on failure
2339 * Getter for "Capabilities" property of an interface.
2341 dbus_bool_t
wpas_dbus_getter_capabilities(DBusMessageIter
*iter
,
2342 DBusError
*error
, void *user_data
)
2344 struct wpa_supplicant
*wpa_s
= user_data
;
2345 struct wpa_driver_capa capa
;
2347 DBusMessageIter iter_dict
, iter_dict_entry
, iter_dict_val
, iter_array
,
2349 const char *scans
[] = { "active", "passive", "ssid" };
2351 if (!dbus_message_iter_open_container(iter
, DBUS_TYPE_VARIANT
,
2352 "a{sv}", &variant_iter
) ||
2353 !wpa_dbus_dict_open_write(&variant_iter
, &iter_dict
))
2356 res
= wpa_drv_get_capa(wpa_s
, &capa
);
2358 /***** pairwise cipher */
2360 const char *args
[] = {"ccmp", "tkip", "none"};
2362 if (!wpa_dbus_dict_append_string_array(
2363 &iter_dict
, "Pairwise", args
,
2367 if (!wpa_dbus_dict_begin_string_array(&iter_dict
, "Pairwise",
2371 ((capa
.enc
& WPA_DRIVER_CAPA_ENC_CCMP_256
) &&
2372 !wpa_dbus_dict_string_array_add_element(
2373 &iter_array
, "ccmp-256")) ||
2374 ((capa
.enc
& WPA_DRIVER_CAPA_ENC_GCMP_256
) &&
2375 !wpa_dbus_dict_string_array_add_element(
2376 &iter_array
, "gcmp-256")) ||
2377 ((capa
.enc
& WPA_DRIVER_CAPA_ENC_CCMP
) &&
2378 !wpa_dbus_dict_string_array_add_element(
2379 &iter_array
, "ccmp")) ||
2380 ((capa
.enc
& WPA_DRIVER_CAPA_ENC_GCMP
) &&
2381 !wpa_dbus_dict_string_array_add_element(
2382 &iter_array
, "gcmp")) ||
2383 ((capa
.enc
& WPA_DRIVER_CAPA_ENC_TKIP
) &&
2384 !wpa_dbus_dict_string_array_add_element(
2385 &iter_array
, "tkip")) ||
2386 ((capa
.key_mgmt
& WPA_DRIVER_CAPA_KEY_MGMT_WPA_NONE
) &&
2387 !wpa_dbus_dict_string_array_add_element(
2388 &iter_array
, "none")) ||
2389 !wpa_dbus_dict_end_string_array(&iter_dict
,
2396 /***** group cipher */
2398 const char *args
[] = {
2399 "ccmp", "tkip", "wep104", "wep40"
2402 if (!wpa_dbus_dict_append_string_array(
2403 &iter_dict
, "Group", args
,
2407 if (!wpa_dbus_dict_begin_string_array(&iter_dict
, "Group",
2411 ((capa
.enc
& WPA_DRIVER_CAPA_ENC_CCMP_256
) &&
2412 !wpa_dbus_dict_string_array_add_element(
2413 &iter_array
, "ccmp-256")) ||
2414 ((capa
.enc
& WPA_DRIVER_CAPA_ENC_GCMP_256
) &&
2415 !wpa_dbus_dict_string_array_add_element(
2416 &iter_array
, "gcmp-256")) ||
2417 ((capa
.enc
& WPA_DRIVER_CAPA_ENC_CCMP
) &&
2418 !wpa_dbus_dict_string_array_add_element(
2419 &iter_array
, "ccmp")) ||
2420 ((capa
.enc
& WPA_DRIVER_CAPA_ENC_GCMP
) &&
2421 !wpa_dbus_dict_string_array_add_element(
2422 &iter_array
, "gcmp")) ||
2423 ((capa
.enc
& WPA_DRIVER_CAPA_ENC_TKIP
) &&
2424 !wpa_dbus_dict_string_array_add_element(
2425 &iter_array
, "tkip")) ||
2426 ((capa
.enc
& WPA_DRIVER_CAPA_ENC_WEP104
) &&
2427 !wpa_dbus_dict_string_array_add_element(
2428 &iter_array
, "wep104")) ||
2429 ((capa
.enc
& WPA_DRIVER_CAPA_ENC_WEP40
) &&
2430 !wpa_dbus_dict_string_array_add_element(
2431 &iter_array
, "wep40")) ||
2432 !wpa_dbus_dict_end_string_array(&iter_dict
,
2439 /***** key management */
2441 const char *args
[] = {
2442 "wpa-psk", "wpa-eap", "ieee8021x", "wpa-none",
2445 #endif /* CONFIG_WPS */
2448 if (!wpa_dbus_dict_append_string_array(
2449 &iter_dict
, "KeyMgmt", args
,
2453 if (!wpa_dbus_dict_begin_string_array(&iter_dict
, "KeyMgmt",
2457 !wpa_dbus_dict_string_array_add_element(&iter_array
,
2459 !wpa_dbus_dict_string_array_add_element(&iter_array
,
2463 if (capa
.key_mgmt
& (WPA_DRIVER_CAPA_KEY_MGMT_WPA
|
2464 WPA_DRIVER_CAPA_KEY_MGMT_WPA2
)) {
2465 if (!wpa_dbus_dict_string_array_add_element(
2466 &iter_array
, "wpa-eap") ||
2467 ((capa
.key_mgmt
& WPA_DRIVER_CAPA_KEY_MGMT_FT
) &&
2468 !wpa_dbus_dict_string_array_add_element(
2469 &iter_array
, "wpa-ft-eap")))
2472 /* TODO: Ensure that driver actually supports sha256 encryption. */
2473 #ifdef CONFIG_IEEE80211W
2474 if (!wpa_dbus_dict_string_array_add_element(
2475 &iter_array
, "wpa-eap-sha256"))
2477 #endif /* CONFIG_IEEE80211W */
2480 if (capa
.key_mgmt
& (WPA_DRIVER_CAPA_KEY_MGMT_WPA_PSK
|
2481 WPA_DRIVER_CAPA_KEY_MGMT_WPA2_PSK
)) {
2482 if (!wpa_dbus_dict_string_array_add_element(
2483 &iter_array
, "wpa-psk") ||
2485 WPA_DRIVER_CAPA_KEY_MGMT_FT_PSK
) &&
2486 !wpa_dbus_dict_string_array_add_element(
2487 &iter_array
, "wpa-ft-psk")))
2490 /* TODO: Ensure that driver actually supports sha256 encryption. */
2491 #ifdef CONFIG_IEEE80211W
2492 if (!wpa_dbus_dict_string_array_add_element(
2493 &iter_array
, "wpa-psk-sha256"))
2495 #endif /* CONFIG_IEEE80211W */
2498 if ((capa
.key_mgmt
& WPA_DRIVER_CAPA_KEY_MGMT_WPA_NONE
) &&
2499 !wpa_dbus_dict_string_array_add_element(&iter_array
,
2505 if (!wpa_dbus_dict_string_array_add_element(&iter_array
,
2508 #endif /* CONFIG_WPS */
2510 if (!wpa_dbus_dict_end_string_array(&iter_dict
,
2517 /***** WPA protocol */
2519 const char *args
[] = { "rsn", "wpa" };
2521 if (!wpa_dbus_dict_append_string_array(
2522 &iter_dict
, "Protocol", args
,
2526 if (!wpa_dbus_dict_begin_string_array(&iter_dict
, "Protocol",
2530 ((capa
.key_mgmt
& (WPA_DRIVER_CAPA_KEY_MGMT_WPA2
|
2531 WPA_DRIVER_CAPA_KEY_MGMT_WPA2_PSK
)) &&
2532 !wpa_dbus_dict_string_array_add_element(
2533 &iter_array
, "rsn")) ||
2534 ((capa
.key_mgmt
& (WPA_DRIVER_CAPA_KEY_MGMT_WPA
|
2535 WPA_DRIVER_CAPA_KEY_MGMT_WPA_PSK
)) &&
2536 !wpa_dbus_dict_string_array_add_element(
2537 &iter_array
, "wpa")) ||
2538 !wpa_dbus_dict_end_string_array(&iter_dict
,
2547 const char *args
[] = { "open", "shared", "leap" };
2549 if (!wpa_dbus_dict_append_string_array(
2550 &iter_dict
, "AuthAlg", args
,
2554 if (!wpa_dbus_dict_begin_string_array(&iter_dict
, "AuthAlg",
2560 if (((capa
.auth
& WPA_DRIVER_AUTH_OPEN
) &&
2561 !wpa_dbus_dict_string_array_add_element(
2562 &iter_array
, "open")) ||
2563 ((capa
.auth
& WPA_DRIVER_AUTH_SHARED
) &&
2564 !wpa_dbus_dict_string_array_add_element(
2565 &iter_array
, "shared")) ||
2566 ((capa
.auth
& WPA_DRIVER_AUTH_LEAP
) &&
2567 !wpa_dbus_dict_string_array_add_element(
2568 &iter_array
, "leap")) ||
2569 !wpa_dbus_dict_end_string_array(&iter_dict
,
2577 if (!wpa_dbus_dict_append_string_array(&iter_dict
, "Scan", scans
,
2582 if (!wpa_dbus_dict_begin_string_array(&iter_dict
, "Modes",
2586 !wpa_dbus_dict_string_array_add_element(
2587 &iter_array
, "infrastructure") ||
2588 !wpa_dbus_dict_string_array_add_element(
2589 &iter_array
, "ad-hoc") ||
2590 (res
>= 0 && (capa
.flags
& WPA_DRIVER_FLAGS_AP
) &&
2591 !wpa_dbus_dict_string_array_add_element(
2592 &iter_array
, "ap")) ||
2593 (res
>= 0 && (capa
.flags
& WPA_DRIVER_FLAGS_P2P_CAPABLE
) &&
2594 !wpa_dbus_dict_string_array_add_element(
2595 &iter_array
, "p2p")) ||
2596 !wpa_dbus_dict_end_string_array(&iter_dict
,
2604 dbus_int32_t max_scan_ssid
= capa
.max_scan_ssids
;
2606 if (!wpa_dbus_dict_append_int32(&iter_dict
, "MaxScanSSID",
2611 if (!wpa_dbus_dict_close_write(&variant_iter
, &iter_dict
) ||
2612 !dbus_message_iter_close_container(iter
, &variant_iter
))
2618 dbus_set_error_const(error
, DBUS_ERROR_NO_MEMORY
, "no memory");
2624 * wpas_dbus_getter_state - Get interface state
2625 * @iter: Pointer to incoming dbus message iter
2626 * @error: Location to store error on failure
2627 * @user_data: Function specific data
2628 * Returns: TRUE on success, FALSE on failure
2630 * Getter for "State" property.
2632 dbus_bool_t
wpas_dbus_getter_state(DBusMessageIter
*iter
, DBusError
*error
,
2635 struct wpa_supplicant
*wpa_s
= user_data
;
2636 const char *str_state
;
2637 char *state_ls
, *tmp
;
2638 dbus_bool_t success
= FALSE
;
2640 str_state
= wpa_supplicant_state_txt(wpa_s
->wpa_state
);
2642 /* make state string lowercase to fit new DBus API convention
2644 state_ls
= tmp
= os_strdup(str_state
);
2646 dbus_set_error_const(error
, DBUS_ERROR_NO_MEMORY
, "no memory");
2650 *tmp
= tolower(*tmp
);
2654 success
= wpas_dbus_simple_property_getter(iter
, DBUS_TYPE_STRING
,
2664 * wpas_dbus_new_iface_get_scanning - Get interface scanning state
2665 * @iter: Pointer to incoming dbus message iter
2666 * @error: Location to store error on failure
2667 * @user_data: Function specific data
2668 * Returns: TRUE on success, FALSE on failure
2670 * Getter for "scanning" property.
2672 dbus_bool_t
wpas_dbus_getter_scanning(DBusMessageIter
*iter
, DBusError
*error
,
2675 struct wpa_supplicant
*wpa_s
= user_data
;
2676 dbus_bool_t scanning
= wpa_s
->scanning
? TRUE
: FALSE
;
2678 return wpas_dbus_simple_property_getter(iter
, DBUS_TYPE_BOOLEAN
,
2684 * wpas_dbus_getter_ap_scan - Control roaming mode
2685 * @iter: Pointer to incoming dbus message iter
2686 * @error: Location to store error on failure
2687 * @user_data: Function specific data
2688 * Returns: TRUE on success, FALSE on failure
2690 * Getter function for "ApScan" property.
2692 dbus_bool_t
wpas_dbus_getter_ap_scan(DBusMessageIter
*iter
, DBusError
*error
,
2695 struct wpa_supplicant
*wpa_s
= user_data
;
2696 dbus_uint32_t ap_scan
= wpa_s
->conf
->ap_scan
;
2698 return wpas_dbus_simple_property_getter(iter
, DBUS_TYPE_UINT32
,
2704 * wpas_dbus_setter_ap_scan - Control roaming mode
2705 * @iter: Pointer to incoming dbus message iter
2706 * @error: Location to store error on failure
2707 * @user_data: Function specific data
2708 * Returns: TRUE on success, FALSE on failure
2710 * Setter function for "ApScan" property.
2712 dbus_bool_t
wpas_dbus_setter_ap_scan(DBusMessageIter
*iter
, DBusError
*error
,
2715 struct wpa_supplicant
*wpa_s
= user_data
;
2716 dbus_uint32_t ap_scan
;
2718 if (!wpas_dbus_simple_property_setter(iter
, error
, DBUS_TYPE_UINT32
,
2722 if (wpa_supplicant_set_ap_scan(wpa_s
, ap_scan
)) {
2723 dbus_set_error_const(error
, DBUS_ERROR_FAILED
,
2724 "ap_scan must be 0, 1, or 2");
2732 * wpas_dbus_getter_fast_reauth - Control fast
2733 * reauthentication (TLS session resumption)
2734 * @iter: Pointer to incoming dbus message iter
2735 * @error: Location to store error on failure
2736 * @user_data: Function specific data
2737 * Returns: TRUE on success, FALSE on failure
2739 * Getter function for "FastReauth" property.
2741 dbus_bool_t
wpas_dbus_getter_fast_reauth(DBusMessageIter
*iter
,
2745 struct wpa_supplicant
*wpa_s
= user_data
;
2746 dbus_bool_t fast_reauth
= wpa_s
->conf
->fast_reauth
? TRUE
: FALSE
;
2748 return wpas_dbus_simple_property_getter(iter
, DBUS_TYPE_BOOLEAN
,
2749 &fast_reauth
, error
);
2754 * wpas_dbus_setter_fast_reauth - Control fast
2755 * reauthentication (TLS session resumption)
2756 * @iter: Pointer to incoming dbus message iter
2757 * @error: Location to store error on failure
2758 * @user_data: Function specific data
2759 * Returns: TRUE on success, FALSE on failure
2761 * Setter function for "FastReauth" property.
2763 dbus_bool_t
wpas_dbus_setter_fast_reauth(DBusMessageIter
*iter
,
2767 struct wpa_supplicant
*wpa_s
= user_data
;
2768 dbus_bool_t fast_reauth
;
2770 if (!wpas_dbus_simple_property_setter(iter
, error
, DBUS_TYPE_BOOLEAN
,
2774 wpa_s
->conf
->fast_reauth
= fast_reauth
;
2780 * wpas_dbus_getter_disconnect_reason - Get most recent reason for disconnect
2781 * @iter: Pointer to incoming dbus message iter
2782 * @error: Location to store error on failure
2783 * @user_data: Function specific data
2784 * Returns: TRUE on success, FALSE on failure
2786 * Getter for "DisconnectReason" property. The reason is negative if it is
2787 * locally generated.
2789 dbus_bool_t
wpas_dbus_getter_disconnect_reason(DBusMessageIter
*iter
,
2793 struct wpa_supplicant
*wpa_s
= user_data
;
2794 dbus_int32_t reason
= wpa_s
->disconnect_reason
;
2796 return wpas_dbus_simple_property_getter(iter
, DBUS_TYPE_INT32
,
2802 * wpas_dbus_getter_bss_expire_age - Get BSS entry expiration age
2803 * @iter: Pointer to incoming dbus message iter
2804 * @error: Location to store error on failure
2805 * @user_data: Function specific data
2806 * Returns: TRUE on success, FALSE on failure
2808 * Getter function for "BSSExpireAge" property.
2810 dbus_bool_t
wpas_dbus_getter_bss_expire_age(DBusMessageIter
*iter
,
2814 struct wpa_supplicant
*wpa_s
= user_data
;
2815 dbus_uint32_t expire_age
= wpa_s
->conf
->bss_expiration_age
;
2817 return wpas_dbus_simple_property_getter(iter
, DBUS_TYPE_UINT32
,
2818 &expire_age
, error
);
2823 * wpas_dbus_setter_bss_expire_age - Control BSS entry expiration age
2824 * @iter: Pointer to incoming dbus message iter
2825 * @error: Location to store error on failure
2826 * @user_data: Function specific data
2827 * Returns: TRUE on success, FALSE on failure
2829 * Setter function for "BSSExpireAge" property.
2831 dbus_bool_t
wpas_dbus_setter_bss_expire_age(DBusMessageIter
*iter
,
2835 struct wpa_supplicant
*wpa_s
= user_data
;
2836 dbus_uint32_t expire_age
;
2838 if (!wpas_dbus_simple_property_setter(iter
, error
, DBUS_TYPE_UINT32
,
2842 if (wpa_supplicant_set_bss_expiration_age(wpa_s
, expire_age
)) {
2843 dbus_set_error_const(error
, DBUS_ERROR_FAILED
,
2844 "BSSExpireAge must be >= 10");
2852 * wpas_dbus_getter_bss_expire_count - Get BSS entry expiration scan count
2853 * @iter: Pointer to incoming dbus message iter
2854 * @error: Location to store error on failure
2855 * @user_data: Function specific data
2856 * Returns: TRUE on success, FALSE on failure
2858 * Getter function for "BSSExpireCount" property.
2860 dbus_bool_t
wpas_dbus_getter_bss_expire_count(DBusMessageIter
*iter
,
2864 struct wpa_supplicant
*wpa_s
= user_data
;
2865 dbus_uint32_t expire_count
= wpa_s
->conf
->bss_expiration_scan_count
;
2867 return wpas_dbus_simple_property_getter(iter
, DBUS_TYPE_UINT32
,
2868 &expire_count
, error
);
2873 * wpas_dbus_setter_bss_expire_count - Control BSS entry expiration scan count
2874 * @iter: Pointer to incoming dbus message iter
2875 * @error: Location to store error on failure
2876 * @user_data: Function specific data
2877 * Returns: TRUE on success, FALSE on failure
2879 * Setter function for "BSSExpireCount" property.
2881 dbus_bool_t
wpas_dbus_setter_bss_expire_count(DBusMessageIter
*iter
,
2885 struct wpa_supplicant
*wpa_s
= user_data
;
2886 dbus_uint32_t expire_count
;
2888 if (!wpas_dbus_simple_property_setter(iter
, error
, DBUS_TYPE_UINT32
,
2892 if (wpa_supplicant_set_bss_expiration_count(wpa_s
, expire_count
)) {
2893 dbus_set_error_const(error
, DBUS_ERROR_FAILED
,
2894 "BSSExpireCount must be > 0");
2902 * wpas_dbus_getter_country - Control country code
2903 * @iter: Pointer to incoming dbus message iter
2904 * @error: Location to store error on failure
2905 * @user_data: Function specific data
2906 * Returns: TRUE on success, FALSE on failure
2908 * Getter function for "Country" property.
2910 dbus_bool_t
wpas_dbus_getter_country(DBusMessageIter
*iter
, DBusError
*error
,
2913 struct wpa_supplicant
*wpa_s
= user_data
;
2915 char *str
= country
;
2917 country
[0] = wpa_s
->conf
->country
[0];
2918 country
[1] = wpa_s
->conf
->country
[1];
2921 return wpas_dbus_simple_property_getter(iter
, DBUS_TYPE_STRING
,
2927 * wpas_dbus_setter_country - Control country code
2928 * @iter: Pointer to incoming dbus message iter
2929 * @error: Location to store error on failure
2930 * @user_data: Function specific data
2931 * Returns: TRUE on success, FALSE on failure
2933 * Setter function for "Country" property.
2935 dbus_bool_t
wpas_dbus_setter_country(DBusMessageIter
*iter
, DBusError
*error
,
2938 struct wpa_supplicant
*wpa_s
= user_data
;
2939 const char *country
;
2941 if (!wpas_dbus_simple_property_setter(iter
, error
, DBUS_TYPE_STRING
,
2945 if (!country
[0] || !country
[1]) {
2946 dbus_set_error_const(error
, DBUS_ERROR_FAILED
,
2947 "invalid country code");
2951 if (wpa_s
->drv_priv
!= NULL
&& wpa_drv_set_country(wpa_s
, country
)) {
2952 wpa_printf(MSG_DEBUG
, "Failed to set country");
2953 dbus_set_error_const(error
, DBUS_ERROR_FAILED
,
2954 "failed to set country code");
2958 wpa_s
->conf
->country
[0] = country
[0];
2959 wpa_s
->conf
->country
[1] = country
[1];
2965 * wpas_dbus_getter_scan_interval - Get scan interval
2966 * @iter: Pointer to incoming dbus message iter
2967 * @error: Location to store error on failure
2968 * @user_data: Function specific data
2969 * Returns: TRUE on success, FALSE on failure
2971 * Getter function for "ScanInterval" property.
2973 dbus_bool_t
wpas_dbus_getter_scan_interval(DBusMessageIter
*iter
,
2977 struct wpa_supplicant
*wpa_s
= user_data
;
2978 dbus_int32_t scan_interval
= wpa_s
->scan_interval
;
2980 return wpas_dbus_simple_property_getter(iter
, DBUS_TYPE_INT32
,
2981 &scan_interval
, error
);
2986 * wpas_dbus_setter_scan_interval - Control scan interval
2987 * @iter: Pointer to incoming dbus message iter
2988 * @error: Location to store error on failure
2989 * @user_data: Function specific data
2990 * Returns: TRUE on success, FALSE on failure
2992 * Setter function for "ScanInterval" property.
2994 dbus_bool_t
wpas_dbus_setter_scan_interval(DBusMessageIter
*iter
,
2998 struct wpa_supplicant
*wpa_s
= user_data
;
2999 dbus_int32_t scan_interval
;
3001 if (!wpas_dbus_simple_property_setter(iter
, error
, DBUS_TYPE_INT32
,
3005 if (wpa_supplicant_set_scan_interval(wpa_s
, scan_interval
)) {
3006 dbus_set_error_const(error
, DBUS_ERROR_FAILED
,
3007 "scan_interval must be >= 0");
3015 * wpas_dbus_getter_ifname - Get interface name
3016 * @iter: Pointer to incoming dbus message iter
3017 * @error: Location to store error on failure
3018 * @user_data: Function specific data
3019 * Returns: TRUE on success, FALSE on failure
3021 * Getter for "Ifname" property.
3023 dbus_bool_t
wpas_dbus_getter_ifname(DBusMessageIter
*iter
, DBusError
*error
,
3026 struct wpa_supplicant
*wpa_s
= user_data
;
3027 const char *ifname
= wpa_s
->ifname
;
3029 return wpas_dbus_simple_property_getter(iter
, DBUS_TYPE_STRING
,
3035 * wpas_dbus_getter_driver - Get interface name
3036 * @iter: Pointer to incoming dbus message iter
3037 * @error: Location to store error on failure
3038 * @user_data: Function specific data
3039 * Returns: TRUE on success, FALSE on failure
3041 * Getter for "Driver" property.
3043 dbus_bool_t
wpas_dbus_getter_driver(DBusMessageIter
*iter
, DBusError
*error
,
3046 struct wpa_supplicant
*wpa_s
= user_data
;
3049 if (wpa_s
->driver
== NULL
|| wpa_s
->driver
->name
== NULL
) {
3050 wpa_printf(MSG_DEBUG
, "%s[dbus]: wpa_s has no driver set",
3052 dbus_set_error(error
, DBUS_ERROR_FAILED
, "%s: no driver set",
3057 driver
= wpa_s
->driver
->name
;
3058 return wpas_dbus_simple_property_getter(iter
, DBUS_TYPE_STRING
,
3064 * wpas_dbus_getter_current_bss - Get current bss object path
3065 * @iter: Pointer to incoming dbus message iter
3066 * @error: Location to store error on failure
3067 * @user_data: Function specific data
3068 * Returns: TRUE on success, FALSE on failure
3070 * Getter for "CurrentBSS" property.
3072 dbus_bool_t
wpas_dbus_getter_current_bss(DBusMessageIter
*iter
,
3076 struct wpa_supplicant
*wpa_s
= user_data
;
3077 char path_buf
[WPAS_DBUS_OBJECT_PATH_MAX
], *bss_obj_path
= path_buf
;
3079 if (wpa_s
->current_bss
&& wpa_s
->dbus_new_path
)
3080 os_snprintf(bss_obj_path
, WPAS_DBUS_OBJECT_PATH_MAX
,
3081 "%s/" WPAS_DBUS_NEW_BSSIDS_PART
"/%u",
3082 wpa_s
->dbus_new_path
, wpa_s
->current_bss
->id
);
3084 os_snprintf(bss_obj_path
, WPAS_DBUS_OBJECT_PATH_MAX
, "/");
3086 return wpas_dbus_simple_property_getter(iter
, DBUS_TYPE_OBJECT_PATH
,
3087 &bss_obj_path
, error
);
3092 * wpas_dbus_getter_current_network - Get current network object path
3093 * @iter: Pointer to incoming dbus message iter
3094 * @error: Location to store error on failure
3095 * @user_data: Function specific data
3096 * Returns: TRUE on success, FALSE on failure
3098 * Getter for "CurrentNetwork" property.
3100 dbus_bool_t
wpas_dbus_getter_current_network(DBusMessageIter
*iter
,
3104 struct wpa_supplicant
*wpa_s
= user_data
;
3105 char path_buf
[WPAS_DBUS_OBJECT_PATH_MAX
], *net_obj_path
= path_buf
;
3107 if (wpa_s
->current_ssid
&& wpa_s
->dbus_new_path
)
3108 os_snprintf(net_obj_path
, WPAS_DBUS_OBJECT_PATH_MAX
,
3109 "%s/" WPAS_DBUS_NEW_NETWORKS_PART
"/%u",
3110 wpa_s
->dbus_new_path
, wpa_s
->current_ssid
->id
);
3112 os_snprintf(net_obj_path
, WPAS_DBUS_OBJECT_PATH_MAX
, "/");
3114 return wpas_dbus_simple_property_getter(iter
, DBUS_TYPE_OBJECT_PATH
,
3115 &net_obj_path
, error
);
3120 * wpas_dbus_getter_current_auth_mode - Get current authentication type
3121 * @iter: Pointer to incoming dbus message iter
3122 * @error: Location to store error on failure
3123 * @user_data: Function specific data
3124 * Returns: TRUE on success, FALSE on failure
3126 * Getter for "CurrentAuthMode" property.
3128 dbus_bool_t
wpas_dbus_getter_current_auth_mode(DBusMessageIter
*iter
,
3132 struct wpa_supplicant
*wpa_s
= user_data
;
3133 const char *eap_mode
;
3134 const char *auth_mode
;
3135 char eap_mode_buf
[WPAS_DBUS_AUTH_MODE_MAX
];
3137 if (wpa_s
->wpa_state
!= WPA_COMPLETED
) {
3138 auth_mode
= "INACTIVE";
3139 } else if (wpa_s
->key_mgmt
== WPA_KEY_MGMT_IEEE8021X
||
3140 wpa_s
->key_mgmt
== WPA_KEY_MGMT_IEEE8021X_NO_WPA
) {
3141 eap_mode
= wpa_supplicant_get_eap_mode(wpa_s
);
3142 os_snprintf(eap_mode_buf
, WPAS_DBUS_AUTH_MODE_MAX
,
3143 "EAP-%s", eap_mode
);
3144 auth_mode
= eap_mode_buf
;
3147 auth_mode
= wpa_key_mgmt_txt(wpa_s
->key_mgmt
,
3148 wpa_s
->current_ssid
->proto
);
3151 return wpas_dbus_simple_property_getter(iter
, DBUS_TYPE_STRING
,
3157 * wpas_dbus_getter_bridge_ifname - Get interface name
3158 * @iter: Pointer to incoming dbus message iter
3159 * @error: Location to store error on failure
3160 * @user_data: Function specific data
3161 * Returns: TRUE on success, FALSE on failure
3163 * Getter for "BridgeIfname" property.
3165 dbus_bool_t
wpas_dbus_getter_bridge_ifname(DBusMessageIter
*iter
,
3169 struct wpa_supplicant
*wpa_s
= user_data
;
3170 const char *bridge_ifname
= wpa_s
->bridge_ifname
;
3172 return wpas_dbus_simple_property_getter(iter
, DBUS_TYPE_STRING
,
3173 &bridge_ifname
, error
);
3178 * wpas_dbus_getter_bsss - Get array of BSSs objects
3179 * @iter: Pointer to incoming dbus message iter
3180 * @error: Location to store error on failure
3181 * @user_data: Function specific data
3182 * Returns: TRUE on success, FALSE on failure
3184 * Getter for "BSSs" property.
3186 dbus_bool_t
wpas_dbus_getter_bsss(DBusMessageIter
*iter
, DBusError
*error
,
3189 struct wpa_supplicant
*wpa_s
= user_data
;
3190 struct wpa_bss
*bss
;
3193 dbus_bool_t success
= FALSE
;
3195 if (!wpa_s
->dbus_new_path
) {
3196 dbus_set_error(error
, DBUS_ERROR_FAILED
,
3197 "%s: no D-Bus interface", __func__
);
3201 paths
= os_calloc(wpa_s
->num_bss
, sizeof(char *));
3203 dbus_set_error_const(error
, DBUS_ERROR_NO_MEMORY
, "no memory");
3207 /* Loop through scan results and append each result's object path */
3208 dl_list_for_each(bss
, &wpa_s
->bss_id
, struct wpa_bss
, list_id
) {
3209 paths
[i
] = os_zalloc(WPAS_DBUS_OBJECT_PATH_MAX
);
3210 if (paths
[i
] == NULL
) {
3211 dbus_set_error_const(error
, DBUS_ERROR_NO_MEMORY
,
3215 /* Construct the object path for this BSS. */
3216 os_snprintf(paths
[i
++], WPAS_DBUS_OBJECT_PATH_MAX
,
3217 "%s/" WPAS_DBUS_NEW_BSSIDS_PART
"/%u",
3218 wpa_s
->dbus_new_path
, bss
->id
);
3221 success
= wpas_dbus_simple_array_property_getter(iter
,
3222 DBUS_TYPE_OBJECT_PATH
,
3223 paths
, wpa_s
->num_bss
,
3228 os_free(paths
[--i
]);
3235 * wpas_dbus_getter_networks - Get array of networks objects
3236 * @iter: Pointer to incoming dbus message iter
3237 * @error: Location to store error on failure
3238 * @user_data: Function specific data
3239 * Returns: TRUE on success, FALSE on failure
3241 * Getter for "Networks" property.
3243 dbus_bool_t
wpas_dbus_getter_networks(DBusMessageIter
*iter
, DBusError
*error
,
3246 struct wpa_supplicant
*wpa_s
= user_data
;
3247 struct wpa_ssid
*ssid
;
3249 unsigned int i
= 0, num
= 0;
3250 dbus_bool_t success
= FALSE
;
3252 if (!wpa_s
->dbus_new_path
) {
3253 dbus_set_error(error
, DBUS_ERROR_FAILED
,
3254 "%s: no D-Bus interface", __func__
);
3258 for (ssid
= wpa_s
->conf
->ssid
; ssid
; ssid
= ssid
->next
)
3259 if (!network_is_persistent_group(ssid
))
3262 paths
= os_calloc(num
, sizeof(char *));
3264 dbus_set_error(error
, DBUS_ERROR_NO_MEMORY
, "no memory");
3268 /* Loop through configured networks and append object path of each */
3269 for (ssid
= wpa_s
->conf
->ssid
; ssid
; ssid
= ssid
->next
) {
3270 if (network_is_persistent_group(ssid
))
3272 paths
[i
] = os_zalloc(WPAS_DBUS_OBJECT_PATH_MAX
);
3273 if (paths
[i
] == NULL
) {
3274 dbus_set_error(error
, DBUS_ERROR_NO_MEMORY
,
3279 /* Construct the object path for this network. */
3280 os_snprintf(paths
[i
++], WPAS_DBUS_OBJECT_PATH_MAX
,
3281 "%s/" WPAS_DBUS_NEW_NETWORKS_PART
"/%d",
3282 wpa_s
->dbus_new_path
, ssid
->id
);
3285 success
= wpas_dbus_simple_array_property_getter(iter
,
3286 DBUS_TYPE_OBJECT_PATH
,
3291 os_free(paths
[--i
]);
3298 * wpas_dbus_getter_pkcs11_engine_path - Get PKCS #11 engine path
3299 * @iter: Pointer to incoming dbus message iter
3300 * @error: Location to store error on failure
3301 * @user_data: Function specific data
3302 * Returns: A dbus message containing the PKCS #11 engine path
3304 * Getter for "PKCS11EnginePath" property.
3306 dbus_bool_t
wpas_dbus_getter_pkcs11_engine_path(DBusMessageIter
*iter
,
3310 struct wpa_supplicant
*wpa_s
= user_data
;
3311 const char *pkcs11_engine_path
;
3313 if (wpa_s
->conf
->pkcs11_engine_path
== NULL
)
3314 pkcs11_engine_path
= "";
3316 pkcs11_engine_path
= wpa_s
->conf
->pkcs11_engine_path
;
3317 return wpas_dbus_simple_property_getter(iter
, DBUS_TYPE_STRING
,
3318 &pkcs11_engine_path
, error
);
3323 * wpas_dbus_getter_pkcs11_module_path - Get PKCS #11 module path
3324 * @iter: Pointer to incoming dbus message iter
3325 * @error: Location to store error on failure
3326 * @user_data: Function specific data
3327 * Returns: A dbus message containing the PKCS #11 module path
3329 * Getter for "PKCS11ModulePath" property.
3331 dbus_bool_t
wpas_dbus_getter_pkcs11_module_path(DBusMessageIter
*iter
,
3335 struct wpa_supplicant
*wpa_s
= user_data
;
3336 const char *pkcs11_module_path
;
3338 if (wpa_s
->conf
->pkcs11_module_path
== NULL
)
3339 pkcs11_module_path
= "";
3341 pkcs11_module_path
= wpa_s
->conf
->pkcs11_module_path
;
3342 return wpas_dbus_simple_property_getter(iter
, DBUS_TYPE_STRING
,
3343 &pkcs11_module_path
, error
);
3348 * wpas_dbus_getter_blobs - Get all blobs defined for this interface
3349 * @iter: Pointer to incoming dbus message iter
3350 * @error: Location to store error on failure
3351 * @user_data: Function specific data
3352 * Returns: TRUE on success, FALSE on failure
3354 * Getter for "Blobs" property.
3356 dbus_bool_t
wpas_dbus_getter_blobs(DBusMessageIter
*iter
, DBusError
*error
,
3359 struct wpa_supplicant
*wpa_s
= user_data
;
3360 DBusMessageIter variant_iter
, dict_iter
, entry_iter
, array_iter
;
3361 struct wpa_config_blob
*blob
;
3363 if (!dbus_message_iter_open_container(iter
, DBUS_TYPE_VARIANT
,
3364 "a{say}", &variant_iter
) ||
3365 !dbus_message_iter_open_container(&variant_iter
, DBUS_TYPE_ARRAY
,
3366 "{say}", &dict_iter
)) {
3367 dbus_set_error_const(error
, DBUS_ERROR_NO_MEMORY
, "no memory");
3371 blob
= wpa_s
->conf
->blobs
;
3373 if (!dbus_message_iter_open_container(&dict_iter
,
3374 DBUS_TYPE_DICT_ENTRY
,
3375 NULL
, &entry_iter
) ||
3376 !dbus_message_iter_append_basic(&entry_iter
,
3379 !dbus_message_iter_open_container(&entry_iter
,
3381 DBUS_TYPE_BYTE_AS_STRING
,
3383 !dbus_message_iter_append_fixed_array(&array_iter
,
3387 !dbus_message_iter_close_container(&entry_iter
,
3389 !dbus_message_iter_close_container(&dict_iter
,
3391 dbus_set_error_const(error
, DBUS_ERROR_NO_MEMORY
,
3399 if (!dbus_message_iter_close_container(&variant_iter
, &dict_iter
) ||
3400 !dbus_message_iter_close_container(iter
, &variant_iter
)) {
3401 dbus_set_error_const(error
, DBUS_ERROR_NO_MEMORY
, "no memory");
3409 static struct wpa_bss
* get_bss_helper(struct bss_handler_args
*args
,
3410 DBusError
*error
, const char *func_name
)
3412 struct wpa_bss
*res
= wpa_bss_get_id(args
->wpa_s
, args
->id
);
3415 wpa_printf(MSG_ERROR
, "%s[dbus]: no bss with id %d found",
3416 func_name
, args
->id
);
3417 dbus_set_error(error
, DBUS_ERROR_FAILED
,
3418 "%s: BSS %d not found",
3419 func_name
, args
->id
);
3427 * wpas_dbus_getter_bss_bssid - Return the BSSID of a BSS
3428 * @iter: Pointer to incoming dbus message iter
3429 * @error: Location to store error on failure
3430 * @user_data: Function specific data
3431 * Returns: TRUE on success, FALSE on failure
3433 * Getter for "BSSID" property.
3435 dbus_bool_t
wpas_dbus_getter_bss_bssid(DBusMessageIter
*iter
, DBusError
*error
,
3438 struct bss_handler_args
*args
= user_data
;
3439 struct wpa_bss
*res
;
3441 res
= get_bss_helper(args
, error
, __func__
);
3445 return wpas_dbus_simple_array_property_getter(iter
, DBUS_TYPE_BYTE
,
3446 res
->bssid
, ETH_ALEN
,
3452 * wpas_dbus_getter_bss_ssid - Return the SSID of a BSS
3453 * @iter: Pointer to incoming dbus message iter
3454 * @error: Location to store error on failure
3455 * @user_data: Function specific data
3456 * Returns: TRUE on success, FALSE on failure
3458 * Getter for "SSID" property.
3460 dbus_bool_t
wpas_dbus_getter_bss_ssid(DBusMessageIter
*iter
, DBusError
*error
,
3463 struct bss_handler_args
*args
= user_data
;
3464 struct wpa_bss
*res
;
3466 res
= get_bss_helper(args
, error
, __func__
);
3470 return wpas_dbus_simple_array_property_getter(iter
, DBUS_TYPE_BYTE
,
3471 res
->ssid
, res
->ssid_len
,
3477 * wpas_dbus_getter_bss_privacy - Return the privacy flag of a BSS
3478 * @iter: Pointer to incoming dbus message iter
3479 * @error: Location to store error on failure
3480 * @user_data: Function specific data
3481 * Returns: TRUE on success, FALSE on failure
3483 * Getter for "Privacy" property.
3485 dbus_bool_t
wpas_dbus_getter_bss_privacy(DBusMessageIter
*iter
,
3486 DBusError
*error
, void *user_data
)
3488 struct bss_handler_args
*args
= user_data
;
3489 struct wpa_bss
*res
;
3490 dbus_bool_t privacy
;
3492 res
= get_bss_helper(args
, error
, __func__
);
3496 privacy
= (res
->caps
& IEEE80211_CAP_PRIVACY
) ? TRUE
: FALSE
;
3497 return wpas_dbus_simple_property_getter(iter
, DBUS_TYPE_BOOLEAN
,
3503 * wpas_dbus_getter_bss_mode - Return the mode of a BSS
3504 * @iter: Pointer to incoming dbus message iter
3505 * @error: Location to store error on failure
3506 * @user_data: Function specific data
3507 * Returns: TRUE on success, FALSE on failure
3509 * Getter for "Mode" property.
3511 dbus_bool_t
wpas_dbus_getter_bss_mode(DBusMessageIter
*iter
, DBusError
*error
,
3514 struct bss_handler_args
*args
= user_data
;
3515 struct wpa_bss
*res
;
3518 res
= get_bss_helper(args
, error
, __func__
);
3521 if (bss_is_dmg(res
)) {
3522 switch (res
->caps
& IEEE80211_CAP_DMG_MASK
) {
3523 case IEEE80211_CAP_DMG_PBSS
:
3524 case IEEE80211_CAP_DMG_IBSS
:
3527 case IEEE80211_CAP_DMG_AP
:
3528 mode
= "infrastructure";
3532 if (res
->caps
& IEEE80211_CAP_IBSS
)
3535 mode
= "infrastructure";
3538 return wpas_dbus_simple_property_getter(iter
, DBUS_TYPE_STRING
,
3544 * wpas_dbus_getter_bss_level - Return the signal strength of a BSS
3545 * @iter: Pointer to incoming dbus message iter
3546 * @error: Location to store error on failure
3547 * @user_data: Function specific data
3548 * Returns: TRUE on success, FALSE on failure
3550 * Getter for "Level" property.
3552 dbus_bool_t
wpas_dbus_getter_bss_signal(DBusMessageIter
*iter
,
3553 DBusError
*error
, void *user_data
)
3555 struct bss_handler_args
*args
= user_data
;
3556 struct wpa_bss
*res
;
3559 res
= get_bss_helper(args
, error
, __func__
);
3563 level
= (s16
) res
->level
;
3564 return wpas_dbus_simple_property_getter(iter
, DBUS_TYPE_INT16
,
3570 * wpas_dbus_getter_bss_frequency - Return the frequency of a BSS
3571 * @iter: Pointer to incoming dbus message iter
3572 * @error: Location to store error on failure
3573 * @user_data: Function specific data
3574 * Returns: TRUE on success, FALSE on failure
3576 * Getter for "Frequency" property.
3578 dbus_bool_t
wpas_dbus_getter_bss_frequency(DBusMessageIter
*iter
,
3579 DBusError
*error
, void *user_data
)
3581 struct bss_handler_args
*args
= user_data
;
3582 struct wpa_bss
*res
;
3585 res
= get_bss_helper(args
, error
, __func__
);
3589 freq
= (u16
) res
->freq
;
3590 return wpas_dbus_simple_property_getter(iter
, DBUS_TYPE_UINT16
,
3595 static int cmp_u8s_desc(const void *a
, const void *b
)
3597 return (*(u8
*) b
- *(u8
*) a
);
3602 * wpas_dbus_getter_bss_rates - Return available bit rates of a BSS
3603 * @iter: Pointer to incoming dbus message iter
3604 * @error: Location to store error on failure
3605 * @user_data: Function specific data
3606 * Returns: TRUE on success, FALSE on failure
3608 * Getter for "Rates" property.
3610 dbus_bool_t
wpas_dbus_getter_bss_rates(DBusMessageIter
*iter
,
3611 DBusError
*error
, void *user_data
)
3613 struct bss_handler_args
*args
= user_data
;
3614 struct wpa_bss
*res
;
3615 u8
*ie_rates
= NULL
;
3618 dbus_bool_t success
= FALSE
;
3620 res
= get_bss_helper(args
, error
, __func__
);
3624 rates_num
= wpa_bss_get_bit_rates(res
, &ie_rates
);
3628 qsort(ie_rates
, rates_num
, 1, cmp_u8s_desc
);
3630 real_rates
= os_malloc(sizeof(u32
) * rates_num
);
3633 dbus_set_error_const(error
, DBUS_ERROR_NO_MEMORY
, "no memory");
3637 for (i
= 0; i
< rates_num
; i
++)
3638 real_rates
[i
] = ie_rates
[i
] * 500000;
3640 success
= wpas_dbus_simple_array_property_getter(iter
, DBUS_TYPE_UINT32
,
3641 real_rates
, rates_num
,
3645 os_free(real_rates
);
3650 static dbus_bool_t
wpas_dbus_get_bss_security_prop(DBusMessageIter
*iter
,
3651 struct wpa_ie_data
*ie_data
,
3654 DBusMessageIter iter_dict
, variant_iter
;
3656 const char *pairwise
[5]; /* max 5 pairwise ciphers is supported */
3657 const char *key_mgmt
[9]; /* max 9 key managements may be supported */
3660 if (!dbus_message_iter_open_container(iter
, DBUS_TYPE_VARIANT
,
3661 "a{sv}", &variant_iter
))
3664 if (!wpa_dbus_dict_open_write(&variant_iter
, &iter_dict
))
3669 if (ie_data
->key_mgmt
& WPA_KEY_MGMT_PSK
)
3670 key_mgmt
[n
++] = "wpa-psk";
3671 if (ie_data
->key_mgmt
& WPA_KEY_MGMT_FT_PSK
)
3672 key_mgmt
[n
++] = "wpa-ft-psk";
3673 if (ie_data
->key_mgmt
& WPA_KEY_MGMT_PSK_SHA256
)
3674 key_mgmt
[n
++] = "wpa-psk-sha256";
3675 if (ie_data
->key_mgmt
& WPA_KEY_MGMT_IEEE8021X
)
3676 key_mgmt
[n
++] = "wpa-eap";
3677 if (ie_data
->key_mgmt
& WPA_KEY_MGMT_FT_IEEE8021X
)
3678 key_mgmt
[n
++] = "wpa-ft-eap";
3679 if (ie_data
->key_mgmt
& WPA_KEY_MGMT_IEEE8021X_SHA256
)
3680 key_mgmt
[n
++] = "wpa-eap-sha256";
3681 #ifdef CONFIG_SUITEB
3682 if (ie_data
->key_mgmt
& WPA_KEY_MGMT_IEEE8021X_SUITE_B
)
3683 key_mgmt
[n
++] = "wpa-eap-suite-b";
3684 #endif /* CONFIG_SUITEB */
3685 #ifdef CONFIG_SUITEB192
3686 if (ie_data
->key_mgmt
& WPA_KEY_MGMT_IEEE8021X_SUITE_B_192
)
3687 key_mgmt
[n
++] = "wpa-eap-suite-b-192";
3688 #endif /* CONFIG_SUITEB192 */
3689 if (ie_data
->key_mgmt
& WPA_KEY_MGMT_NONE
)
3690 key_mgmt
[n
++] = "wpa-none";
3692 if (!wpa_dbus_dict_append_string_array(&iter_dict
, "KeyMgmt",
3697 switch (ie_data
->group_cipher
) {
3698 case WPA_CIPHER_WEP40
:
3701 case WPA_CIPHER_TKIP
:
3704 case WPA_CIPHER_CCMP
:
3707 case WPA_CIPHER_GCMP
:
3710 case WPA_CIPHER_WEP104
:
3713 case WPA_CIPHER_CCMP_256
:
3716 case WPA_CIPHER_GCMP_256
:
3724 if (!wpa_dbus_dict_append_string(&iter_dict
, "Group", group
))
3729 if (ie_data
->pairwise_cipher
& WPA_CIPHER_TKIP
)
3730 pairwise
[n
++] = "tkip";
3731 if (ie_data
->pairwise_cipher
& WPA_CIPHER_CCMP
)
3732 pairwise
[n
++] = "ccmp";
3733 if (ie_data
->pairwise_cipher
& WPA_CIPHER_GCMP
)
3734 pairwise
[n
++] = "gcmp";
3735 if (ie_data
->pairwise_cipher
& WPA_CIPHER_CCMP_256
)
3736 pairwise
[n
++] = "ccmp-256";
3737 if (ie_data
->pairwise_cipher
& WPA_CIPHER_GCMP_256
)
3738 pairwise
[n
++] = "gcmp-256";
3740 if (!wpa_dbus_dict_append_string_array(&iter_dict
, "Pairwise",
3744 /* Management group (RSN only) */
3745 if (ie_data
->proto
== WPA_PROTO_RSN
) {
3746 switch (ie_data
->mgmt_group_cipher
) {
3747 #ifdef CONFIG_IEEE80211W
3748 case WPA_CIPHER_AES_128_CMAC
:
3749 group
= "aes128cmac";
3751 #endif /* CONFIG_IEEE80211W */
3757 if (!wpa_dbus_dict_append_string(&iter_dict
, "MgmtGroup",
3762 if (!wpa_dbus_dict_close_write(&variant_iter
, &iter_dict
) ||
3763 !dbus_message_iter_close_container(iter
, &variant_iter
))
3769 dbus_set_error_const(error
, DBUS_ERROR_NO_MEMORY
, "no memory");
3775 * wpas_dbus_getter_bss_wpa - Return the WPA options of a BSS
3776 * @iter: Pointer to incoming dbus message iter
3777 * @error: Location to store error on failure
3778 * @user_data: Function specific data
3779 * Returns: TRUE on success, FALSE on failure
3781 * Getter for "WPA" property.
3783 dbus_bool_t
wpas_dbus_getter_bss_wpa(DBusMessageIter
*iter
, DBusError
*error
,
3786 struct bss_handler_args
*args
= user_data
;
3787 struct wpa_bss
*res
;
3788 struct wpa_ie_data wpa_data
;
3791 res
= get_bss_helper(args
, error
, __func__
);
3795 os_memset(&wpa_data
, 0, sizeof(wpa_data
));
3796 ie
= wpa_bss_get_vendor_ie(res
, WPA_IE_VENDOR_TYPE
);
3797 if (ie
&& wpa_parse_wpa_ie(ie
, 2 + ie
[1], &wpa_data
) < 0) {
3798 dbus_set_error_const(error
, DBUS_ERROR_FAILED
,
3799 "failed to parse WPA IE");
3803 return wpas_dbus_get_bss_security_prop(iter
, &wpa_data
, error
);
3808 * wpas_dbus_getter_bss_rsn - Return the RSN options of a BSS
3809 * @iter: Pointer to incoming dbus message iter
3810 * @error: Location to store error on failure
3811 * @user_data: Function specific data
3812 * Returns: TRUE on success, FALSE on failure
3814 * Getter for "RSN" property.
3816 dbus_bool_t
wpas_dbus_getter_bss_rsn(DBusMessageIter
*iter
, DBusError
*error
,
3819 struct bss_handler_args
*args
= user_data
;
3820 struct wpa_bss
*res
;
3821 struct wpa_ie_data wpa_data
;
3824 res
= get_bss_helper(args
, error
, __func__
);
3828 os_memset(&wpa_data
, 0, sizeof(wpa_data
));
3829 ie
= wpa_bss_get_ie(res
, WLAN_EID_RSN
);
3830 if (ie
&& wpa_parse_wpa_ie(ie
, 2 + ie
[1], &wpa_data
) < 0) {
3831 dbus_set_error_const(error
, DBUS_ERROR_FAILED
,
3832 "failed to parse RSN IE");
3836 return wpas_dbus_get_bss_security_prop(iter
, &wpa_data
, error
);
3841 * wpas_dbus_getter_bss_wps - Return the WPS options of a BSS
3842 * @iter: Pointer to incoming dbus message iter
3843 * @error: Location to store error on failure
3844 * @user_data: Function specific data
3845 * Returns: TRUE on success, FALSE on failure
3847 * Getter for "WPS" property.
3849 dbus_bool_t
wpas_dbus_getter_bss_wps(DBusMessageIter
*iter
, DBusError
*error
,
3852 struct bss_handler_args
*args
= user_data
;
3853 struct wpa_bss
*res
;
3855 struct wpabuf
*wps_ie
;
3856 #endif /* CONFIG_WPS */
3857 DBusMessageIter iter_dict
, variant_iter
;
3858 int wps_support
= 0;
3859 const char *type
= "";
3861 res
= get_bss_helper(args
, error
, __func__
);
3865 if (!dbus_message_iter_open_container(iter
, DBUS_TYPE_VARIANT
,
3866 "a{sv}", &variant_iter
) ||
3867 !wpa_dbus_dict_open_write(&variant_iter
, &iter_dict
))
3871 wps_ie
= wpa_bss_get_vendor_ie_multi(res
, WPS_IE_VENDOR_TYPE
);
3874 if (wps_is_selected_pbc_registrar(wps_ie
))
3876 else if (wps_is_selected_pin_registrar(wps_ie
))
3879 wpabuf_free(wps_ie
);
3881 #endif /* CONFIG_WPS */
3883 if ((wps_support
&& !wpa_dbus_dict_append_string(&iter_dict
, "Type", type
)) ||
3884 !wpa_dbus_dict_close_write(&variant_iter
, &iter_dict
) ||
3885 !dbus_message_iter_close_container(iter
, &variant_iter
))
3891 dbus_set_error_const(error
, DBUS_ERROR_NO_MEMORY
, "no memory");
3897 * wpas_dbus_getter_bss_ies - Return all IEs of a BSS
3898 * @iter: Pointer to incoming dbus message iter
3899 * @error: Location to store error on failure
3900 * @user_data: Function specific data
3901 * Returns: TRUE on success, FALSE on failure
3903 * Getter for "IEs" property.
3905 dbus_bool_t
wpas_dbus_getter_bss_ies(DBusMessageIter
*iter
, DBusError
*error
,
3908 struct bss_handler_args
*args
= user_data
;
3909 struct wpa_bss
*res
;
3911 res
= get_bss_helper(args
, error
, __func__
);
3915 return wpas_dbus_simple_array_property_getter(iter
, DBUS_TYPE_BYTE
,
3916 res
+ 1, res
->ie_len
,
3922 * wpas_dbus_getter_bss_age - Return time in seconds since BSS was last seen
3923 * @iter: Pointer to incoming dbus message iter
3924 * @error: Location to store error on failure
3925 * @user_data: Function specific data
3926 * Returns: TRUE on success, FALSE on failure
3928 * Getter for BSS age
3930 dbus_bool_t
wpas_dbus_getter_bss_age(DBusMessageIter
*iter
, DBusError
*error
,
3933 struct bss_handler_args
*args
= user_data
;
3934 struct wpa_bss
*res
;
3935 struct os_reltime now
, diff
= { 0, 0 };
3938 res
= get_bss_helper(args
, error
, __func__
);
3942 os_get_reltime(&now
);
3943 os_reltime_sub(&now
, &res
->last_update
, &diff
);
3944 age
= diff
.sec
> 0 ? diff
.sec
: 0;
3945 return wpas_dbus_simple_property_getter(iter
, DBUS_TYPE_UINT32
, &age
,
3951 * wpas_dbus_getter_enabled - Check whether network is enabled or disabled
3952 * @iter: Pointer to incoming dbus message iter
3953 * @error: Location to store error on failure
3954 * @user_data: Function specific data
3955 * Returns: TRUE on success, FALSE on failure
3957 * Getter for "enabled" property of a configured network.
3959 dbus_bool_t
wpas_dbus_getter_enabled(DBusMessageIter
*iter
, DBusError
*error
,
3962 struct network_handler_args
*net
= user_data
;
3963 dbus_bool_t enabled
= net
->ssid
->disabled
? FALSE
: TRUE
;
3965 return wpas_dbus_simple_property_getter(iter
, DBUS_TYPE_BOOLEAN
,
3971 * wpas_dbus_setter_enabled - Mark a configured network as enabled or disabled
3972 * @iter: Pointer to incoming dbus message iter
3973 * @error: Location to store error on failure
3974 * @user_data: Function specific data
3975 * Returns: TRUE on success, FALSE on failure
3977 * Setter for "Enabled" property of a configured network.
3979 dbus_bool_t
wpas_dbus_setter_enabled(DBusMessageIter
*iter
, DBusError
*error
,
3982 struct network_handler_args
*net
= user_data
;
3983 struct wpa_supplicant
*wpa_s
;
3984 struct wpa_ssid
*ssid
;
3987 if (!wpas_dbus_simple_property_setter(iter
, error
, DBUS_TYPE_BOOLEAN
,
3995 wpa_supplicant_enable_network(wpa_s
, ssid
);
3997 wpa_supplicant_disable_network(wpa_s
, ssid
);
4004 * wpas_dbus_getter_network_properties - Get options for a configured network
4005 * @iter: Pointer to incoming dbus message iter
4006 * @error: Location to store error on failure
4007 * @user_data: Function specific data
4008 * Returns: TRUE on success, FALSE on failure
4010 * Getter for "Properties" property of a configured network.
4012 dbus_bool_t
wpas_dbus_getter_network_properties(DBusMessageIter
*iter
,
4016 struct network_handler_args
*net
= user_data
;
4017 DBusMessageIter variant_iter
, dict_iter
;
4019 char **props
= wpa_config_get_all(net
->ssid
, 1);
4020 dbus_bool_t success
= FALSE
;
4023 dbus_set_error_const(error
, DBUS_ERROR_NO_MEMORY
, "no memory");
4027 if (!dbus_message_iter_open_container(iter
, DBUS_TYPE_VARIANT
, "a{sv}",
4029 !wpa_dbus_dict_open_write(&variant_iter
, &dict_iter
)) {
4030 dbus_set_error_const(error
, DBUS_ERROR_NO_MEMORY
, "no memory");
4036 if (!wpa_dbus_dict_append_string(&dict_iter
, *iterator
,
4038 dbus_set_error_const(error
, DBUS_ERROR_NO_MEMORY
,
4046 if (!wpa_dbus_dict_close_write(&variant_iter
, &dict_iter
) ||
4047 !dbus_message_iter_close_container(iter
, &variant_iter
)) {
4048 dbus_set_error_const(error
, DBUS_ERROR_NO_MEMORY
, "no memory");
4066 * wpas_dbus_setter_network_properties - Set options for a configured network
4067 * @iter: Pointer to incoming dbus message iter
4068 * @error: Location to store error on failure
4069 * @user_data: Function specific data
4070 * Returns: TRUE on success, FALSE on failure
4072 * Setter for "Properties" property of a configured network.
4074 dbus_bool_t
wpas_dbus_setter_network_properties(DBusMessageIter
*iter
,
4078 struct network_handler_args
*net
= user_data
;
4079 struct wpa_ssid
*ssid
= net
->ssid
;
4080 DBusMessageIter variant_iter
;
4082 dbus_message_iter_recurse(iter
, &variant_iter
);
4083 return set_network_properties(net
->wpa_s
, ssid
, &variant_iter
, error
);
4089 DBusMessage
* wpas_dbus_handler_subscribe_preq(
4090 DBusMessage
*message
, struct wpa_supplicant
*wpa_s
)
4092 struct wpas_dbus_priv
*priv
= wpa_s
->global
->dbus
;
4095 if (wpa_s
->preq_notify_peer
!= NULL
) {
4096 if (os_strcmp(dbus_message_get_sender(message
),
4097 wpa_s
->preq_notify_peer
) == 0)
4100 return dbus_message_new_error(message
,
4101 WPAS_DBUS_ERROR_SUBSCRIPTION_IN_USE
,
4102 "Another application is already subscribed");
4105 name
= os_strdup(dbus_message_get_sender(message
));
4107 return wpas_dbus_error_no_memory(message
);
4109 wpa_s
->preq_notify_peer
= name
;
4111 /* Subscribe to clean up if application closes socket */
4112 wpas_dbus_subscribe_noc(priv
);
4115 * Double-check it's still alive to make sure that we didn't
4116 * miss the NameOwnerChanged signal, e.g. while strdup'ing.
4118 if (!dbus_bus_name_has_owner(priv
->con
, name
, NULL
)) {
4120 * Application no longer exists, clean up.
4121 * The return value is irrelevant now.
4123 * Need to check if the NameOwnerChanged handling
4124 * already cleaned up because we have processed
4125 * DBus messages while checking if the name still
4128 if (!wpa_s
->preq_notify_peer
)
4130 os_free(wpa_s
->preq_notify_peer
);
4131 wpa_s
->preq_notify_peer
= NULL
;
4132 wpas_dbus_unsubscribe_noc(priv
);
4139 DBusMessage
* wpas_dbus_handler_unsubscribe_preq(
4140 DBusMessage
*message
, struct wpa_supplicant
*wpa_s
)
4142 struct wpas_dbus_priv
*priv
= wpa_s
->global
->dbus
;
4144 if (!wpa_s
->preq_notify_peer
)
4145 return dbus_message_new_error(message
,
4146 WPAS_DBUS_ERROR_NO_SUBSCRIPTION
,
4149 if (os_strcmp(wpa_s
->preq_notify_peer
,
4150 dbus_message_get_sender(message
)))
4151 return dbus_message_new_error(message
,
4152 WPAS_DBUS_ERROR_SUBSCRIPTION_EPERM
,
4153 "Can't unsubscribe others");
4155 os_free(wpa_s
->preq_notify_peer
);
4156 wpa_s
->preq_notify_peer
= NULL
;
4157 wpas_dbus_unsubscribe_noc(priv
);
4162 void wpas_dbus_signal_preq(struct wpa_supplicant
*wpa_s
,
4163 const u8
*addr
, const u8
*dst
, const u8
*bssid
,
4164 const u8
*ie
, size_t ie_len
, u32 ssi_signal
)
4167 DBusMessageIter iter
, dict_iter
;
4168 struct wpas_dbus_priv
*priv
= wpa_s
->global
->dbus
;
4170 /* Do nothing if the control interface is not turned on */
4171 if (priv
== NULL
|| !wpa_s
->dbus_new_path
)
4174 if (wpa_s
->preq_notify_peer
== NULL
)
4177 msg
= dbus_message_new_signal(wpa_s
->dbus_new_path
,
4178 WPAS_DBUS_NEW_IFACE_INTERFACE
,
4183 dbus_message_set_destination(msg
, wpa_s
->preq_notify_peer
);
4185 dbus_message_iter_init_append(msg
, &iter
);
4187 if (!wpa_dbus_dict_open_write(&iter
, &dict_iter
) ||
4188 (addr
&& !wpa_dbus_dict_append_byte_array(&dict_iter
, "addr",
4189 (const char *) addr
,
4191 (dst
&& !wpa_dbus_dict_append_byte_array(&dict_iter
, "dst",
4194 (bssid
&& !wpa_dbus_dict_append_byte_array(&dict_iter
, "bssid",
4195 (const char *) bssid
,
4197 (ie
&& ie_len
&& !wpa_dbus_dict_append_byte_array(&dict_iter
, "ies",
4200 (ssi_signal
&& !wpa_dbus_dict_append_int32(&dict_iter
, "signal",
4202 !wpa_dbus_dict_close_write(&iter
, &dict_iter
))
4205 dbus_connection_send(priv
->con
, msg
, NULL
);
4208 wpa_printf(MSG_ERROR
, "dbus: Failed to construct signal");
4210 dbus_message_unref(msg
);
4213 #endif /* CONFIG_AP */