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 (const char *) array
+
440 dbus_set_error(error
, DBUS_ERROR_FAILED
,
441 "%s: failed to construct message 2.5",
447 if (!dbus_message_iter_close_container(&variant_iter
, &array_iter
) ||
448 !dbus_message_iter_close_container(iter
, &variant_iter
)) {
449 dbus_set_error(error
, DBUS_ERROR_FAILED
,
450 "%s: failed to construct message 3", __func__
);
459 * wpas_dbus_simple_array_array_property_getter - Get array array type property
460 * @iter: Pointer to incoming dbus message iterator
461 * @type: DBus type of property array elements (must be basic type)
462 * @array: pointer to array of elements to put into response message
463 * @array_len: length of above array
464 * @error: a pointer to an error to fill on failure
465 * Returns: TRUE if the request succeeded, FALSE if it failed
467 * Generic getter for array type properties. Array elements type is
468 * required to be basic.
470 dbus_bool_t
wpas_dbus_simple_array_array_property_getter(DBusMessageIter
*iter
,
472 struct wpabuf
**array
,
476 DBusMessageIter variant_iter
, array_iter
;
477 char type_str
[] = "aa?";
478 char inner_type_str
[] = "a?";
479 const char *sub_type_str
;
482 if (!dbus_type_is_basic(type
)) {
483 dbus_set_error(error
, DBUS_ERROR_FAILED
,
484 "%s: given type is not basic", __func__
);
488 sub_type_str
= wpa_dbus_type_as_string(type
);
489 type_str
[2] = sub_type_str
[0];
490 inner_type_str
[1] = sub_type_str
[0];
492 if (!dbus_message_iter_open_container(iter
, DBUS_TYPE_VARIANT
,
493 type_str
, &variant_iter
) ||
494 !dbus_message_iter_open_container(&variant_iter
, DBUS_TYPE_ARRAY
,
495 inner_type_str
, &array_iter
)) {
496 dbus_set_error(error
, DBUS_ERROR_FAILED
,
497 "%s: failed to construct message", __func__
);
501 for (i
= 0; i
< array_len
&& array
[i
]; i
++) {
502 wpa_dbus_dict_bin_array_add_element(&array_iter
,
503 wpabuf_head(array
[i
]),
504 wpabuf_len(array
[i
]));
508 if (!dbus_message_iter_close_container(&variant_iter
, &array_iter
) ||
509 !dbus_message_iter_close_container(iter
, &variant_iter
)) {
510 dbus_set_error(error
, DBUS_ERROR_FAILED
,
511 "%s: failed to close message", __func__
);
520 * wpas_dbus_string_property_getter - Get string type property
521 * @iter: Message iter to use when appending arguments
522 * @val: Pointer to place holding property value, can be %NULL
523 * @error: On failure an error describing the failure
524 * Returns: TRUE if the request was successful, FALSE if it failed
526 * Generic getter for string type properties. %NULL is converted to an empty
529 dbus_bool_t
wpas_dbus_string_property_getter(DBusMessageIter
*iter
,
535 return wpas_dbus_simple_property_getter(iter
, DBUS_TYPE_STRING
,
541 * wpas_dbus_handler_create_interface - Request registration of a network iface
542 * @message: Pointer to incoming dbus message
543 * @global: %wpa_supplicant global data structure
544 * Returns: The object path of the new interface object,
545 * or a dbus error message with more information
547 * Handler function for "CreateInterface" method call. Handles requests
548 * by dbus clients to register a network interface that wpa_supplicant
551 DBusMessage
* wpas_dbus_handler_create_interface(DBusMessage
*message
,
552 struct wpa_global
*global
)
554 DBusMessageIter iter_dict
;
555 DBusMessage
*reply
= NULL
;
556 DBusMessageIter iter
;
557 struct wpa_dbus_dict_entry entry
;
560 char *confname
= NULL
;
561 char *bridge_ifname
= NULL
;
563 dbus_message_iter_init(message
, &iter
);
565 if (!wpa_dbus_dict_open_read(&iter
, &iter_dict
, NULL
))
567 while (wpa_dbus_dict_has_dict_entry(&iter_dict
)) {
568 if (!wpa_dbus_dict_get_entry(&iter_dict
, &entry
))
570 if (os_strcmp(entry
.key
, "Driver") == 0 &&
571 entry
.type
== DBUS_TYPE_STRING
) {
573 driver
= os_strdup(entry
.str_value
);
574 wpa_dbus_dict_entry_clear(&entry
);
577 } else if (os_strcmp(entry
.key
, "Ifname") == 0 &&
578 entry
.type
== DBUS_TYPE_STRING
) {
580 ifname
= os_strdup(entry
.str_value
);
581 wpa_dbus_dict_entry_clear(&entry
);
584 } else if (os_strcmp(entry
.key
, "ConfigFile") == 0 &&
585 entry
.type
== DBUS_TYPE_STRING
) {
587 confname
= os_strdup(entry
.str_value
);
588 wpa_dbus_dict_entry_clear(&entry
);
589 if (confname
== NULL
)
591 } else if (os_strcmp(entry
.key
, "BridgeIfname") == 0 &&
592 entry
.type
== DBUS_TYPE_STRING
) {
593 os_free(bridge_ifname
);
594 bridge_ifname
= os_strdup(entry
.str_value
);
595 wpa_dbus_dict_entry_clear(&entry
);
596 if (bridge_ifname
== NULL
)
599 wpa_dbus_dict_entry_clear(&entry
);
605 goto error
; /* Required Ifname argument missing */
608 * Try to get the wpa_supplicant record for this iface, return
609 * an error if we already control it.
611 if (wpa_supplicant_get_iface(global
, ifname
) != NULL
) {
612 reply
= dbus_message_new_error(
613 message
, WPAS_DBUS_ERROR_IFACE_EXISTS
,
614 "wpa_supplicant already controls this interface.");
616 struct wpa_supplicant
*wpa_s
;
617 struct wpa_interface iface
;
619 os_memset(&iface
, 0, sizeof(iface
));
620 iface
.driver
= driver
;
621 iface
.ifname
= ifname
;
622 iface
.confname
= confname
;
623 iface
.bridge_ifname
= bridge_ifname
;
624 /* Otherwise, have wpa_supplicant attach to it. */
625 wpa_s
= wpa_supplicant_add_iface(global
, &iface
, NULL
);
626 if (wpa_s
&& wpa_s
->dbus_new_path
) {
627 const char *path
= wpa_s
->dbus_new_path
;
629 reply
= dbus_message_new_method_return(message
);
630 dbus_message_append_args(reply
, DBUS_TYPE_OBJECT_PATH
,
631 &path
, DBUS_TYPE_INVALID
);
633 reply
= wpas_dbus_error_unknown_error(
635 "wpa_supplicant couldn't grab this interface.");
643 os_free(bridge_ifname
);
647 reply
= wpas_dbus_error_invalid_args(message
, NULL
);
650 reply
= wpas_dbus_error_no_memory(message
);
656 * wpas_dbus_handler_remove_interface - Request deregistration of an interface
657 * @message: Pointer to incoming dbus message
658 * @global: wpa_supplicant global data structure
659 * Returns: a dbus message containing a UINT32 indicating success (1) or
660 * failure (0), or returns a dbus error message with more information
662 * Handler function for "removeInterface" method call. Handles requests
663 * by dbus clients to deregister a network interface that wpa_supplicant
666 DBusMessage
* wpas_dbus_handler_remove_interface(DBusMessage
*message
,
667 struct wpa_global
*global
)
669 struct wpa_supplicant
*wpa_s
;
671 DBusMessage
*reply
= NULL
;
673 dbus_message_get_args(message
, NULL
, DBUS_TYPE_OBJECT_PATH
, &path
,
676 wpa_s
= get_iface_by_dbus_path(global
, path
);
678 reply
= wpas_dbus_error_iface_unknown(message
);
679 else if (wpa_supplicant_remove_iface(global
, wpa_s
, 0)) {
680 reply
= wpas_dbus_error_unknown_error(
682 "wpa_supplicant couldn't remove this interface.");
690 * wpas_dbus_handler_get_interface - Get the object path for an interface name
691 * @message: Pointer to incoming dbus message
692 * @global: %wpa_supplicant global data structure
693 * Returns: The object path of the interface object,
694 * or a dbus error message with more information
696 * Handler function for "getInterface" method call.
698 DBusMessage
* wpas_dbus_handler_get_interface(DBusMessage
*message
,
699 struct wpa_global
*global
)
701 DBusMessage
*reply
= NULL
;
704 struct wpa_supplicant
*wpa_s
;
706 dbus_message_get_args(message
, NULL
, DBUS_TYPE_STRING
, &ifname
,
709 wpa_s
= wpa_supplicant_get_iface(global
, ifname
);
710 if (wpa_s
== NULL
|| wpa_s
->dbus_new_path
== NULL
)
711 return wpas_dbus_error_iface_unknown(message
);
713 path
= wpa_s
->dbus_new_path
;
714 reply
= dbus_message_new_method_return(message
);
716 return wpas_dbus_error_no_memory(message
);
717 if (!dbus_message_append_args(reply
, DBUS_TYPE_OBJECT_PATH
, &path
,
718 DBUS_TYPE_INVALID
)) {
719 dbus_message_unref(reply
);
720 return wpas_dbus_error_no_memory(message
);
728 * wpas_dbus_getter_debug_level - Get debug level
729 * @iter: Pointer to incoming dbus message iter
730 * @error: Location to store error on failure
731 * @user_data: Function specific data
732 * Returns: TRUE on success, FALSE on failure
734 * Getter for "DebugLevel" property.
736 dbus_bool_t
wpas_dbus_getter_debug_level(
737 const struct wpa_dbus_property_desc
*property_desc
,
738 DBusMessageIter
*iter
, DBusError
*error
, void *user_data
)
741 int idx
= wpa_debug_level
;
747 str
= debug_strings
[idx
];
748 return wpas_dbus_simple_property_getter(iter
, DBUS_TYPE_STRING
,
754 * wpas_dbus_getter_debug_timestamp - Get debug timestamp
755 * @iter: Pointer to incoming dbus message iter
756 * @error: Location to store error on failure
757 * @user_data: Function specific data
758 * Returns: TRUE on success, FALSE on failure
760 * Getter for "DebugTimestamp" property.
762 dbus_bool_t
wpas_dbus_getter_debug_timestamp(
763 const struct wpa_dbus_property_desc
*property_desc
,
764 DBusMessageIter
*iter
, DBusError
*error
, void *user_data
)
766 return wpas_dbus_simple_property_getter(iter
, DBUS_TYPE_BOOLEAN
,
767 &wpa_debug_timestamp
, error
);
773 * wpas_dbus_getter_debug_show_keys - Get debug show keys
774 * @iter: Pointer to incoming dbus message iter
775 * @error: Location to store error on failure
776 * @user_data: Function specific data
777 * Returns: TRUE on success, FALSE on failure
779 * Getter for "DebugShowKeys" property.
781 dbus_bool_t
wpas_dbus_getter_debug_show_keys(
782 const struct wpa_dbus_property_desc
*property_desc
,
783 DBusMessageIter
*iter
, DBusError
*error
, void *user_data
)
785 return wpas_dbus_simple_property_getter(iter
, DBUS_TYPE_BOOLEAN
,
786 &wpa_debug_show_keys
, error
);
791 * wpas_dbus_setter_debug_level - Set debug level
792 * @iter: Pointer to incoming dbus message iter
793 * @error: Location to store error on failure
794 * @user_data: Function specific data
795 * Returns: TRUE on success, FALSE on failure
797 * Setter for "DebugLevel" property.
799 dbus_bool_t
wpas_dbus_setter_debug_level(
800 const struct wpa_dbus_property_desc
*property_desc
,
801 DBusMessageIter
*iter
, DBusError
*error
, void *user_data
)
803 struct wpa_global
*global
= user_data
;
804 const char *str
= NULL
;
807 if (!wpas_dbus_simple_property_setter(iter
, error
, DBUS_TYPE_STRING
,
811 for (i
= 0; debug_strings
[i
]; i
++)
812 if (os_strcmp(debug_strings
[i
], str
) == 0) {
818 wpa_supplicant_set_debug_params(global
, val
, wpa_debug_timestamp
,
819 wpa_debug_show_keys
)) {
820 dbus_set_error_const(error
, DBUS_ERROR_FAILED
,
821 "wrong debug level value");
830 * wpas_dbus_setter_debug_timestamp - Set debug timestamp
831 * @iter: Pointer to incoming dbus message iter
832 * @error: Location to store error on failure
833 * @user_data: Function specific data
834 * Returns: TRUE on success, FALSE on failure
836 * Setter for "DebugTimestamp" property.
838 dbus_bool_t
wpas_dbus_setter_debug_timestamp(
839 const struct wpa_dbus_property_desc
*property_desc
,
840 DBusMessageIter
*iter
, DBusError
*error
, void *user_data
)
842 struct wpa_global
*global
= user_data
;
845 if (!wpas_dbus_simple_property_setter(iter
, error
, DBUS_TYPE_BOOLEAN
,
849 wpa_supplicant_set_debug_params(global
, wpa_debug_level
, val
? 1 : 0,
850 wpa_debug_show_keys
);
856 * wpas_dbus_setter_debug_show_keys - Set debug show keys
857 * @iter: Pointer to incoming dbus message iter
858 * @error: Location to store error on failure
859 * @user_data: Function specific data
860 * Returns: TRUE on success, FALSE on failure
862 * Setter for "DebugShowKeys" property.
864 dbus_bool_t
wpas_dbus_setter_debug_show_keys(
865 const struct wpa_dbus_property_desc
*property_desc
,
866 DBusMessageIter
*iter
, DBusError
*error
, void *user_data
)
868 struct wpa_global
*global
= user_data
;
871 if (!wpas_dbus_simple_property_setter(iter
, error
, DBUS_TYPE_BOOLEAN
,
875 wpa_supplicant_set_debug_params(global
, wpa_debug_level
,
883 * wpas_dbus_getter_interfaces - Request registered interfaces list
884 * @iter: Pointer to incoming dbus message iter
885 * @error: Location to store error on failure
886 * @user_data: Function specific data
887 * Returns: TRUE on success, FALSE on failure
889 * Getter for "Interfaces" property. Handles requests
890 * by dbus clients to return list of registered interfaces objects
893 dbus_bool_t
wpas_dbus_getter_interfaces(
894 const struct wpa_dbus_property_desc
*property_desc
,
895 DBusMessageIter
*iter
, DBusError
*error
, void *user_data
)
897 struct wpa_global
*global
= user_data
;
898 struct wpa_supplicant
*wpa_s
;
900 unsigned int i
= 0, num
= 0;
903 for (wpa_s
= global
->ifaces
; wpa_s
; wpa_s
= wpa_s
->next
) {
904 if (wpa_s
->dbus_new_path
)
908 paths
= os_calloc(num
, sizeof(char *));
910 dbus_set_error_const(error
, DBUS_ERROR_NO_MEMORY
, "no memory");
914 for (wpa_s
= global
->ifaces
; wpa_s
; wpa_s
= wpa_s
->next
) {
915 if (wpa_s
->dbus_new_path
)
916 paths
[i
++] = wpa_s
->dbus_new_path
;
919 success
= wpas_dbus_simple_array_property_getter(iter
,
920 DBUS_TYPE_OBJECT_PATH
,
929 * wpas_dbus_getter_eap_methods - Request supported EAP methods list
930 * @iter: Pointer to incoming dbus message iter
931 * @error: Location to store error on failure
932 * @user_data: Function specific data
933 * Returns: TRUE on success, FALSE on failure
935 * Getter for "EapMethods" property. Handles requests
936 * by dbus clients to return list of strings with supported EAP methods
938 dbus_bool_t
wpas_dbus_getter_eap_methods(
939 const struct wpa_dbus_property_desc
*property_desc
,
940 DBusMessageIter
*iter
, DBusError
*error
, void *user_data
)
943 size_t num_items
= 0;
946 eap_methods
= eap_get_names_as_string_array(&num_items
);
948 dbus_set_error_const(error
, DBUS_ERROR_NO_MEMORY
, "no memory");
952 success
= wpas_dbus_simple_array_property_getter(iter
,
958 os_free(eap_methods
[--num_items
]);
959 os_free(eap_methods
);
965 * wpas_dbus_getter_global_capabilities - Request supported global capabilities
966 * @iter: Pointer to incoming dbus message iter
967 * @error: Location to store error on failure
968 * @user_data: Function specific data
969 * Returns: TRUE on success, FALSE on failure
971 * Getter for "Capabilities" property. Handles requests by dbus clients to
972 * return a list of strings with supported capabilities like AP, RSN IBSS,
973 * and P2P that are determined at compile time.
975 dbus_bool_t
wpas_dbus_getter_global_capabilities(
976 const struct wpa_dbus_property_desc
*property_desc
,
977 DBusMessageIter
*iter
, DBusError
*error
, void *user_data
)
979 const char *capabilities
[5] = { NULL
, NULL
, NULL
, NULL
, NULL
};
980 size_t num_items
= 0;
983 capabilities
[num_items
++] = "ap";
984 #endif /* CONFIG_AP */
985 #ifdef CONFIG_IBSS_RSN
986 capabilities
[num_items
++] = "ibss-rsn";
987 #endif /* CONFIG_IBSS_RSN */
989 capabilities
[num_items
++] = "p2p";
990 #endif /* CONFIG_P2P */
991 #ifdef CONFIG_INTERWORKING
992 capabilities
[num_items
++] = "interworking";
993 #endif /* CONFIG_INTERWORKING */
994 #ifdef CONFIG_IEEE80211W
995 capabilities
[num_items
++] = "pmf";
996 #endif /* CONFIG_IEEE80211W */
998 return wpas_dbus_simple_array_property_getter(iter
,
1005 static int wpas_dbus_get_scan_type(DBusMessage
*message
, DBusMessageIter
*var
,
1006 char **type
, DBusMessage
**reply
)
1008 if (dbus_message_iter_get_arg_type(var
) != DBUS_TYPE_STRING
) {
1009 wpa_printf(MSG_DEBUG
, "%s[dbus]: Type must be a string",
1011 *reply
= wpas_dbus_error_invalid_args(
1012 message
, "Wrong Type value type. String required");
1015 dbus_message_iter_get_basic(var
, type
);
1020 static int wpas_dbus_get_scan_ssids(DBusMessage
*message
, DBusMessageIter
*var
,
1021 struct wpa_driver_scan_params
*params
,
1022 DBusMessage
**reply
)
1024 struct wpa_driver_scan_ssid
*ssids
= params
->ssids
;
1025 size_t ssids_num
= 0;
1027 DBusMessageIter array_iter
, sub_array_iter
;
1031 if (dbus_message_iter_get_arg_type(var
) != DBUS_TYPE_ARRAY
) {
1032 wpa_printf(MSG_DEBUG
,
1033 "%s[dbus]: ssids must be an array of arrays of bytes",
1035 *reply
= wpas_dbus_error_invalid_args(
1037 "Wrong SSIDs value type. Array of arrays of bytes required");
1041 dbus_message_iter_recurse(var
, &array_iter
);
1043 if (dbus_message_iter_get_arg_type(&array_iter
) != DBUS_TYPE_ARRAY
||
1044 dbus_message_iter_get_element_type(&array_iter
) != DBUS_TYPE_BYTE
) {
1045 wpa_printf(MSG_DEBUG
,
1046 "%s[dbus]: ssids must be an array of arrays of bytes",
1048 *reply
= wpas_dbus_error_invalid_args(
1050 "Wrong SSIDs value type. Array of arrays of bytes required");
1054 while (dbus_message_iter_get_arg_type(&array_iter
) == DBUS_TYPE_ARRAY
) {
1055 if (ssids_num
>= WPAS_MAX_SCAN_SSIDS
) {
1056 wpa_printf(MSG_DEBUG
,
1057 "%s[dbus]: Too many ssids specified on scan dbus call",
1059 *reply
= wpas_dbus_error_invalid_args(
1061 "Too many ssids specified. Specify at most four");
1065 dbus_message_iter_recurse(&array_iter
, &sub_array_iter
);
1067 dbus_message_iter_get_fixed_array(&sub_array_iter
, &val
, &len
);
1069 if (len
> SSID_MAX_LEN
) {
1070 wpa_printf(MSG_DEBUG
,
1071 "%s[dbus]: SSID too long (len=%d max_len=%d)",
1072 __func__
, len
, SSID_MAX_LEN
);
1073 *reply
= wpas_dbus_error_invalid_args(
1074 message
, "Invalid SSID: too long");
1079 ssid
= os_malloc(len
);
1081 *reply
= wpas_dbus_error_no_memory(message
);
1084 os_memcpy(ssid
, val
, len
);
1086 /* Allow zero-length SSIDs */
1090 ssids
[ssids_num
].ssid
= ssid
;
1091 ssids
[ssids_num
].ssid_len
= len
;
1093 dbus_message_iter_next(&array_iter
);
1097 params
->num_ssids
= ssids_num
;
1102 static int wpas_dbus_get_scan_ies(DBusMessage
*message
, DBusMessageIter
*var
,
1103 struct wpa_driver_scan_params
*params
,
1104 DBusMessage
**reply
)
1106 u8
*ies
= NULL
, *nies
;
1108 DBusMessageIter array_iter
, sub_array_iter
;
1112 if (dbus_message_iter_get_arg_type(var
) != DBUS_TYPE_ARRAY
) {
1113 wpa_printf(MSG_DEBUG
,
1114 "%s[dbus]: ies must be an array of arrays of bytes",
1116 *reply
= wpas_dbus_error_invalid_args(
1118 "Wrong IEs value type. Array of arrays of bytes required");
1122 dbus_message_iter_recurse(var
, &array_iter
);
1124 if (dbus_message_iter_get_arg_type(&array_iter
) != DBUS_TYPE_ARRAY
||
1125 dbus_message_iter_get_element_type(&array_iter
) != DBUS_TYPE_BYTE
) {
1126 wpa_printf(MSG_DEBUG
,
1127 "%s[dbus]: ies must be an array of arrays of bytes",
1129 *reply
= wpas_dbus_error_invalid_args(
1130 message
, "Wrong IEs value type. Array required");
1134 while (dbus_message_iter_get_arg_type(&array_iter
) == DBUS_TYPE_ARRAY
) {
1135 dbus_message_iter_recurse(&array_iter
, &sub_array_iter
);
1137 dbus_message_iter_get_fixed_array(&sub_array_iter
, &val
, &len
);
1139 dbus_message_iter_next(&array_iter
);
1143 nies
= os_realloc(ies
, ies_len
+ len
);
1146 *reply
= wpas_dbus_error_no_memory(message
);
1150 os_memcpy(ies
+ ies_len
, val
, len
);
1153 dbus_message_iter_next(&array_iter
);
1156 params
->extra_ies
= ies
;
1157 params
->extra_ies_len
= ies_len
;
1162 static int wpas_dbus_get_scan_channels(DBusMessage
*message
,
1163 DBusMessageIter
*var
,
1164 struct wpa_driver_scan_params
*params
,
1165 DBusMessage
**reply
)
1167 DBusMessageIter array_iter
, sub_array_iter
;
1168 int *freqs
= NULL
, *nfreqs
;
1171 if (dbus_message_iter_get_arg_type(var
) != DBUS_TYPE_ARRAY
) {
1172 wpa_printf(MSG_DEBUG
,
1173 "%s[dbus]: Channels must be an array of structs",
1175 *reply
= wpas_dbus_error_invalid_args(
1177 "Wrong Channels value type. Array of structs required");
1181 dbus_message_iter_recurse(var
, &array_iter
);
1183 if (dbus_message_iter_get_arg_type(&array_iter
) != DBUS_TYPE_STRUCT
) {
1184 wpa_printf(MSG_DEBUG
,
1185 "%s[dbus]: Channels must be an array of structs",
1187 *reply
= wpas_dbus_error_invalid_args(
1189 "Wrong Channels value type. Array of structs required");
1193 while (dbus_message_iter_get_arg_type(&array_iter
) == DBUS_TYPE_STRUCT
)
1197 dbus_message_iter_recurse(&array_iter
, &sub_array_iter
);
1199 if (dbus_message_iter_get_arg_type(&sub_array_iter
) !=
1201 wpa_printf(MSG_DEBUG
,
1202 "%s[dbus]: Channel must by specified by struct of two UINT32s %c",
1204 dbus_message_iter_get_arg_type(
1206 *reply
= wpas_dbus_error_invalid_args(
1208 "Wrong Channel struct. Two UINT32s required");
1212 dbus_message_iter_get_basic(&sub_array_iter
, &freq
);
1214 if (!dbus_message_iter_next(&sub_array_iter
) ||
1215 dbus_message_iter_get_arg_type(&sub_array_iter
) !=
1217 wpa_printf(MSG_DEBUG
,
1218 "%s[dbus]: Channel must by specified by struct of two UINT32s",
1220 *reply
= wpas_dbus_error_invalid_args(
1222 "Wrong Channel struct. Two UINT32s required");
1227 dbus_message_iter_get_basic(&sub_array_iter
, &width
);
1229 #define FREQS_ALLOC_CHUNK 32
1230 if (freqs_num
% FREQS_ALLOC_CHUNK
== 0) {
1231 nfreqs
= os_realloc_array(
1232 freqs
, freqs_num
+ FREQS_ALLOC_CHUNK
,
1238 if (freqs
== NULL
) {
1239 *reply
= wpas_dbus_error_no_memory(message
);
1243 freqs
[freqs_num
] = freq
;
1246 dbus_message_iter_next(&array_iter
);
1249 nfreqs
= os_realloc_array(freqs
, freqs_num
+ 1, sizeof(int));
1253 if (freqs
== NULL
) {
1254 *reply
= wpas_dbus_error_no_memory(message
);
1257 freqs
[freqs_num
] = 0;
1259 params
->freqs
= freqs
;
1264 static int wpas_dbus_get_scan_allow_roam(DBusMessage
*message
,
1265 DBusMessageIter
*var
,
1267 DBusMessage
**reply
)
1269 if (dbus_message_iter_get_arg_type(var
) != DBUS_TYPE_BOOLEAN
) {
1270 wpa_printf(MSG_DEBUG
, "%s[dbus]: Type must be a boolean",
1272 *reply
= wpas_dbus_error_invalid_args(
1273 message
, "Wrong Type value type. Boolean required");
1276 dbus_message_iter_get_basic(var
, allow
);
1282 * wpas_dbus_handler_scan - Request a wireless scan on an interface
1283 * @message: Pointer to incoming dbus message
1284 * @wpa_s: wpa_supplicant structure for a network interface
1285 * Returns: NULL indicating success or DBus error message on failure
1287 * Handler function for "Scan" method call of a network device. Requests
1288 * that wpa_supplicant perform a wireless scan as soon as possible
1289 * on a particular wireless interface.
1291 DBusMessage
* wpas_dbus_handler_scan(DBusMessage
*message
,
1292 struct wpa_supplicant
*wpa_s
)
1294 DBusMessage
*reply
= NULL
;
1295 DBusMessageIter iter
, dict_iter
, entry_iter
, variant_iter
;
1296 char *key
= NULL
, *type
= NULL
;
1297 struct wpa_driver_scan_params params
;
1299 dbus_bool_t allow_roam
= 1;
1301 os_memset(¶ms
, 0, sizeof(params
));
1303 dbus_message_iter_init(message
, &iter
);
1305 dbus_message_iter_recurse(&iter
, &dict_iter
);
1307 while (dbus_message_iter_get_arg_type(&dict_iter
) ==
1308 DBUS_TYPE_DICT_ENTRY
) {
1309 dbus_message_iter_recurse(&dict_iter
, &entry_iter
);
1310 dbus_message_iter_get_basic(&entry_iter
, &key
);
1311 dbus_message_iter_next(&entry_iter
);
1312 dbus_message_iter_recurse(&entry_iter
, &variant_iter
);
1314 if (os_strcmp(key
, "Type") == 0) {
1315 if (wpas_dbus_get_scan_type(message
, &variant_iter
,
1318 } else if (os_strcmp(key
, "SSIDs") == 0) {
1319 if (wpas_dbus_get_scan_ssids(message
, &variant_iter
,
1320 ¶ms
, &reply
) < 0)
1322 } else if (os_strcmp(key
, "IEs") == 0) {
1323 if (wpas_dbus_get_scan_ies(message
, &variant_iter
,
1324 ¶ms
, &reply
) < 0)
1326 } else if (os_strcmp(key
, "Channels") == 0) {
1327 if (wpas_dbus_get_scan_channels(message
, &variant_iter
,
1328 ¶ms
, &reply
) < 0)
1330 } else if (os_strcmp(key
, "AllowRoam") == 0) {
1331 if (wpas_dbus_get_scan_allow_roam(message
,
1337 wpa_printf(MSG_DEBUG
, "%s[dbus]: Unknown argument %s",
1339 reply
= wpas_dbus_error_invalid_args(message
, key
);
1343 dbus_message_iter_next(&dict_iter
);
1347 wpa_printf(MSG_DEBUG
, "%s[dbus]: Scan type not specified",
1349 reply
= wpas_dbus_error_invalid_args(message
, key
);
1353 if (os_strcmp(type
, "passive") == 0) {
1354 if (params
.num_ssids
|| params
.extra_ies_len
) {
1355 wpa_printf(MSG_DEBUG
,
1356 "%s[dbus]: SSIDs or IEs specified for passive scan.",
1358 reply
= wpas_dbus_error_invalid_args(
1360 "You can specify only Channels in passive scan");
1363 if (wpa_s
->sched_scanning
) {
1364 wpa_printf(MSG_DEBUG
,
1365 "%s[dbus]: Stop ongoing sched_scan to allow requested scan to proceed",
1367 wpa_supplicant_cancel_sched_scan(wpa_s
);
1370 if (params
.freqs
&& params
.freqs
[0]) {
1371 wpa_s
->last_scan_req
= MANUAL_SCAN_REQ
;
1372 if (wpa_supplicant_trigger_scan(wpa_s
,
1374 reply
= wpas_dbus_error_scan_error(
1376 "Scan request rejected");
1379 wpa_s
->scan_req
= MANUAL_SCAN_REQ
;
1380 wpa_supplicant_req_scan(wpa_s
, 0, 0);
1383 } else if (os_strcmp(type
, "active") == 0) {
1384 if (!params
.num_ssids
) {
1385 /* Add wildcard ssid */
1388 #ifdef CONFIG_AUTOSCAN
1389 autoscan_deinit(wpa_s
);
1390 #endif /* CONFIG_AUTOSCAN */
1391 if (wpa_s
->sched_scanning
) {
1392 wpa_printf(MSG_DEBUG
,
1393 "%s[dbus]: Stop ongoing sched_scan to allow requested scan to proceed",
1395 wpa_supplicant_cancel_sched_scan(wpa_s
);
1398 wpa_s
->last_scan_req
= MANUAL_SCAN_REQ
;
1399 if (wpa_supplicant_trigger_scan(wpa_s
, ¶ms
)) {
1400 reply
= wpas_dbus_error_scan_error(
1401 message
, "Scan request rejected");
1404 wpa_printf(MSG_DEBUG
, "%s[dbus]: Unknown scan type: %s",
1406 reply
= wpas_dbus_error_invalid_args(message
,
1412 wpa_s
->scan_res_handler
= scan_only_handler
;
1415 for (i
= 0; i
< WPAS_MAX_SCAN_SSIDS
; i
++)
1416 os_free((u8
*) params
.ssids
[i
].ssid
);
1417 os_free((u8
*) params
.extra_ies
);
1418 os_free(params
.freqs
);
1424 * wpas_dbus_handler_signal_poll - Request immediate signal properties
1425 * @message: Pointer to incoming dbus message
1426 * @wpa_s: wpa_supplicant structure for a network interface
1427 * Returns: NULL indicating success or DBus error message on failure
1429 * Handler function for "SignalPoll" method call of a network device. Requests
1430 * that wpa_supplicant read signal properties like RSSI, noise, and link
1431 * speed and return them.
1433 DBusMessage
* wpas_dbus_handler_signal_poll(DBusMessage
*message
,
1434 struct wpa_supplicant
*wpa_s
)
1436 struct wpa_signal_info si
;
1437 DBusMessage
*reply
= NULL
;
1438 DBusMessageIter iter
, iter_dict
, variant_iter
;
1441 ret
= wpa_drv_signal_poll(wpa_s
, &si
);
1443 return dbus_message_new_error(message
, DBUS_ERROR_FAILED
,
1444 "Failed to read signal");
1447 reply
= dbus_message_new_method_return(message
);
1451 dbus_message_iter_init_append(reply
, &iter
);
1453 if (!dbus_message_iter_open_container(&iter
, DBUS_TYPE_VARIANT
,
1454 "a{sv}", &variant_iter
) ||
1455 !wpa_dbus_dict_open_write(&variant_iter
, &iter_dict
) ||
1456 !wpa_dbus_dict_append_int32(&iter_dict
, "rssi",
1457 si
.current_signal
) ||
1458 !wpa_dbus_dict_append_int32(&iter_dict
, "linkspeed",
1459 si
.current_txrate
/ 1000) ||
1460 !wpa_dbus_dict_append_int32(&iter_dict
, "noise",
1461 si
.current_noise
) ||
1462 !wpa_dbus_dict_append_uint32(&iter_dict
, "frequency",
1464 (si
.chanwidth
!= CHAN_WIDTH_UNKNOWN
&&
1465 !wpa_dbus_dict_append_string(
1466 &iter_dict
, "width",
1467 channel_width_to_string(si
.chanwidth
))) ||
1468 (si
.center_frq1
> 0 && si
.center_frq2
> 0 &&
1469 (!wpa_dbus_dict_append_int32(&iter_dict
, "center-frq1",
1471 !wpa_dbus_dict_append_int32(&iter_dict
, "center-frq2",
1472 si
.center_frq2
))) ||
1474 !wpa_dbus_dict_append_int32(&iter_dict
, "avg-rssi",
1476 !wpa_dbus_dict_close_write(&variant_iter
, &iter_dict
) ||
1477 !dbus_message_iter_close_container(&iter
, &variant_iter
))
1484 dbus_message_unref(reply
);
1485 return wpas_dbus_error_no_memory(message
);
1490 * wpas_dbus_handler_disconnect - Terminate the current connection
1491 * @message: Pointer to incoming dbus message
1492 * @wpa_s: wpa_supplicant structure for a network interface
1493 * Returns: NotConnected DBus error message if already not connected
1494 * or NULL otherwise.
1496 * Handler function for "Disconnect" method call of network interface.
1498 DBusMessage
* wpas_dbus_handler_disconnect(DBusMessage
*message
,
1499 struct wpa_supplicant
*wpa_s
)
1501 if (wpa_s
->current_ssid
!= NULL
) {
1502 wpas_request_disconnection(wpa_s
);
1506 return dbus_message_new_error(message
, WPAS_DBUS_ERROR_NOT_CONNECTED
,
1507 "This interface is not connected");
1512 * wpas_dbus_new_iface_add_network - Add a new configured network
1513 * @message: Pointer to incoming dbus message
1514 * @wpa_s: wpa_supplicant structure for a network interface
1515 * Returns: A dbus message containing the object path of the new network
1517 * Handler function for "AddNetwork" method call of a network interface.
1519 DBusMessage
* wpas_dbus_handler_add_network(DBusMessage
*message
,
1520 struct wpa_supplicant
*wpa_s
)
1522 DBusMessage
*reply
= NULL
;
1523 DBusMessageIter iter
;
1524 struct wpa_ssid
*ssid
= NULL
;
1525 char path_buf
[WPAS_DBUS_OBJECT_PATH_MAX
], *path
= path_buf
;
1528 dbus_message_iter_init(message
, &iter
);
1530 if (wpa_s
->dbus_new_path
)
1531 ssid
= wpa_supplicant_add_network(wpa_s
);
1533 wpa_printf(MSG_ERROR
, "%s[dbus]: can't add new interface.",
1535 reply
= wpas_dbus_error_unknown_error(
1537 "wpa_supplicant could not add a network on this interface.");
1541 dbus_error_init(&error
);
1542 if (!set_network_properties(wpa_s
, ssid
, &iter
, &error
)) {
1543 wpa_printf(MSG_DEBUG
,
1544 "%s[dbus]: control interface couldn't set network properties",
1546 reply
= wpas_dbus_reply_new_from_error(message
, &error
,
1547 DBUS_ERROR_INVALID_ARGS
,
1548 "Failed to add network");
1549 dbus_error_free(&error
);
1553 /* Construct the object path for this network. */
1554 os_snprintf(path
, WPAS_DBUS_OBJECT_PATH_MAX
,
1555 "%s/" WPAS_DBUS_NEW_NETWORKS_PART
"/%d",
1556 wpa_s
->dbus_new_path
, ssid
->id
);
1558 reply
= dbus_message_new_method_return(message
);
1559 if (reply
== NULL
) {
1560 reply
= wpas_dbus_error_no_memory(message
);
1563 if (!dbus_message_append_args(reply
, DBUS_TYPE_OBJECT_PATH
, &path
,
1564 DBUS_TYPE_INVALID
)) {
1565 dbus_message_unref(reply
);
1566 reply
= wpas_dbus_error_no_memory(message
);
1574 wpas_notify_network_removed(wpa_s
, ssid
);
1575 wpa_config_remove_network(wpa_s
->conf
, ssid
->id
);
1582 * wpas_dbus_handler_reassociate - Reassociate
1583 * @message: Pointer to incoming dbus message
1584 * @wpa_s: wpa_supplicant structure for a network interface
1585 * Returns: InterfaceDisabled DBus error message if disabled
1586 * or NULL otherwise.
1588 * Handler function for "Reassociate" method call of network interface.
1590 DBusMessage
* wpas_dbus_handler_reassociate(DBusMessage
*message
,
1591 struct wpa_supplicant
*wpa_s
)
1593 if (wpa_s
->wpa_state
!= WPA_INTERFACE_DISABLED
) {
1594 wpas_request_connection(wpa_s
);
1598 return dbus_message_new_error(message
, WPAS_DBUS_ERROR_IFACE_DISABLED
,
1599 "This interface is disabled");
1604 * wpas_dbus_handler_expect_disconnect - ExpectDisconnect
1605 * @message: Pointer to incoming dbus message
1606 * @global: %wpa_supplicant global data structure
1609 * Handler function for notifying system there will be a expected disconnect.
1610 * This will prevent wpa_supplicant from adding blacklists upon next disconnect..
1612 DBusMessage
* wpas_dbus_handler_expect_disconnect(DBusMessage
*message
,
1613 struct wpa_global
*global
)
1615 struct wpa_supplicant
*wpa_s
= global
->ifaces
;
1617 for (; wpa_s
; wpa_s
= wpa_s
->next
)
1618 if (wpa_s
->wpa_state
>= WPA_ASSOCIATED
)
1619 wpa_s
->own_disconnect_req
= 1;
1625 * wpas_dbus_handler_reattach - Reattach to current AP
1626 * @message: Pointer to incoming dbus message
1627 * @wpa_s: wpa_supplicant structure for a network interface
1628 * Returns: NotConnected DBus error message if not connected
1629 * or NULL otherwise.
1631 * Handler function for "Reattach" method call of network interface.
1633 DBusMessage
* wpas_dbus_handler_reattach(DBusMessage
*message
,
1634 struct wpa_supplicant
*wpa_s
)
1636 if (wpa_s
->current_ssid
!= NULL
) {
1637 wpa_s
->reattach
= 1;
1638 wpas_request_connection(wpa_s
);
1642 return dbus_message_new_error(message
, WPAS_DBUS_ERROR_NOT_CONNECTED
,
1643 "This interface is not connected");
1648 * wpas_dbus_handler_reconnect - Reconnect if disconnected
1649 * @message: Pointer to incoming dbus message
1650 * @wpa_s: wpa_supplicant structure for a network interface
1651 * Returns: InterfaceDisabled DBus error message if disabled
1652 * or NULL otherwise.
1654 * Handler function for "Reconnect" method call of network interface.
1656 DBusMessage
* wpas_dbus_handler_reconnect(DBusMessage
*message
,
1657 struct wpa_supplicant
*wpa_s
)
1659 if (wpa_s
->wpa_state
== WPA_INTERFACE_DISABLED
) {
1660 return dbus_message_new_error(message
,
1661 WPAS_DBUS_ERROR_IFACE_DISABLED
,
1662 "This interface is disabled");
1665 if (wpa_s
->disconnected
)
1666 wpas_request_connection(wpa_s
);
1672 * wpas_dbus_handler_remove_network - Remove a configured network
1673 * @message: Pointer to incoming dbus message
1674 * @wpa_s: wpa_supplicant structure for a network interface
1675 * Returns: NULL on success or dbus error on failure
1677 * Handler function for "RemoveNetwork" method call of a network interface.
1679 DBusMessage
* wpas_dbus_handler_remove_network(DBusMessage
*message
,
1680 struct wpa_supplicant
*wpa_s
)
1682 DBusMessage
*reply
= NULL
;
1684 char *iface
, *net_id
;
1688 dbus_message_get_args(message
, NULL
, DBUS_TYPE_OBJECT_PATH
, &op
,
1691 /* Extract the network ID and ensure the network */
1692 /* is actually a child of this interface */
1693 iface
= wpas_dbus_new_decompose_object_path(op
,
1694 WPAS_DBUS_NEW_NETWORKS_PART
,
1696 if (iface
== NULL
|| net_id
== NULL
|| !wpa_s
->dbus_new_path
||
1697 os_strcmp(iface
, wpa_s
->dbus_new_path
) != 0) {
1698 reply
= wpas_dbus_error_invalid_args(message
, op
);
1703 id
= strtoul(net_id
, NULL
, 10);
1705 reply
= wpas_dbus_error_invalid_args(message
, op
);
1709 result
= wpa_supplicant_remove_network(wpa_s
, id
);
1711 reply
= wpas_dbus_error_network_unknown(message
);
1715 wpa_printf(MSG_ERROR
,
1716 "%s[dbus]: error occurred when removing network %d",
1718 reply
= wpas_dbus_error_unknown_error(
1720 "error removing the specified network on is interface.");
1730 static void remove_network(void *arg
, struct wpa_ssid
*ssid
)
1732 struct wpa_supplicant
*wpa_s
= arg
;
1734 wpas_notify_network_removed(wpa_s
, ssid
);
1736 if (wpa_config_remove_network(wpa_s
->conf
, ssid
->id
) < 0) {
1737 wpa_printf(MSG_ERROR
,
1738 "%s[dbus]: error occurred when removing network %d",
1739 __func__
, ssid
->id
);
1743 if (ssid
== wpa_s
->current_ssid
)
1744 wpa_supplicant_deauthenticate(wpa_s
,
1745 WLAN_REASON_DEAUTH_LEAVING
);
1750 * wpas_dbus_handler_remove_all_networks - Remove all configured networks
1751 * @message: Pointer to incoming dbus message
1752 * @wpa_s: wpa_supplicant structure for a network interface
1753 * Returns: NULL on success or dbus error on failure
1755 * Handler function for "RemoveAllNetworks" method call of a network interface.
1757 DBusMessage
* wpas_dbus_handler_remove_all_networks(
1758 DBusMessage
*message
, struct wpa_supplicant
*wpa_s
)
1760 if (wpa_s
->sched_scanning
)
1761 wpa_supplicant_cancel_sched_scan(wpa_s
);
1763 /* NB: could check for failure and return an error */
1764 wpa_config_foreach_network(wpa_s
->conf
, remove_network
, wpa_s
);
1770 * wpas_dbus_handler_select_network - Attempt association with a network
1771 * @message: Pointer to incoming dbus message
1772 * @wpa_s: wpa_supplicant structure for a network interface
1773 * Returns: NULL on success or dbus error on failure
1775 * Handler function for "SelectNetwork" method call of network interface.
1777 DBusMessage
* wpas_dbus_handler_select_network(DBusMessage
*message
,
1778 struct wpa_supplicant
*wpa_s
)
1780 DBusMessage
*reply
= NULL
;
1782 char *iface
, *net_id
;
1784 struct wpa_ssid
*ssid
;
1786 dbus_message_get_args(message
, NULL
, DBUS_TYPE_OBJECT_PATH
, &op
,
1789 /* Extract the network ID and ensure the network */
1790 /* is actually a child of this interface */
1791 iface
= wpas_dbus_new_decompose_object_path(op
,
1792 WPAS_DBUS_NEW_NETWORKS_PART
,
1794 if (iface
== NULL
|| net_id
== NULL
|| !wpa_s
->dbus_new_path
||
1795 os_strcmp(iface
, wpa_s
->dbus_new_path
) != 0) {
1796 reply
= wpas_dbus_error_invalid_args(message
, op
);
1801 id
= strtoul(net_id
, NULL
, 10);
1803 reply
= wpas_dbus_error_invalid_args(message
, op
);
1807 ssid
= wpa_config_get_network(wpa_s
->conf
, id
);
1809 reply
= wpas_dbus_error_network_unknown(message
);
1813 /* Finally, associate with the network */
1814 wpa_supplicant_select_network(wpa_s
, ssid
);
1823 * wpas_dbus_handler_network_reply - Reply to a NetworkRequest signal
1824 * @message: Pointer to incoming dbus message
1825 * @wpa_s: wpa_supplicant structure for a network interface
1826 * Returns: NULL on success or dbus error on failure
1828 * Handler function for "NetworkReply" method call of network interface.
1830 DBusMessage
* wpas_dbus_handler_network_reply(DBusMessage
*message
,
1831 struct wpa_supplicant
*wpa_s
)
1833 #ifdef IEEE8021X_EAPOL
1834 DBusMessage
*reply
= NULL
;
1835 const char *op
, *field
, *value
;
1836 char *iface
, *net_id
;
1838 struct wpa_ssid
*ssid
;
1840 if (!dbus_message_get_args(message
, NULL
,
1841 DBUS_TYPE_OBJECT_PATH
, &op
,
1842 DBUS_TYPE_STRING
, &field
,
1843 DBUS_TYPE_STRING
, &value
,
1845 return wpas_dbus_error_invalid_args(message
, NULL
);
1847 /* Extract the network ID and ensure the network */
1848 /* is actually a child of this interface */
1849 iface
= wpas_dbus_new_decompose_object_path(op
,
1850 WPAS_DBUS_NEW_NETWORKS_PART
,
1852 if (iface
== NULL
|| net_id
== NULL
|| !wpa_s
->dbus_new_path
||
1853 os_strcmp(iface
, wpa_s
->dbus_new_path
) != 0) {
1854 reply
= wpas_dbus_error_invalid_args(message
, op
);
1859 id
= strtoul(net_id
, NULL
, 10);
1861 reply
= wpas_dbus_error_invalid_args(message
, net_id
);
1865 ssid
= wpa_config_get_network(wpa_s
->conf
, id
);
1867 reply
= wpas_dbus_error_network_unknown(message
);
1871 if (wpa_supplicant_ctrl_iface_ctrl_rsp_handle(wpa_s
, ssid
,
1873 reply
= wpas_dbus_error_invalid_args(message
, field
);
1875 /* Tell EAP to retry immediately */
1876 eapol_sm_notify_ctrl_response(wpa_s
->eapol
);
1882 #else /* IEEE8021X_EAPOL */
1883 wpa_printf(MSG_DEBUG
, "dbus: 802.1X not included");
1884 return wpas_dbus_error_unknown_error(message
, "802.1X not included");
1885 #endif /* IEEE8021X_EAPOL */
1889 #ifndef CONFIG_NO_CONFIG_BLOBS
1892 * wpas_dbus_handler_add_blob - Store named binary blob (ie, for certificates)
1893 * @message: Pointer to incoming dbus message
1894 * @wpa_s: %wpa_supplicant data structure
1895 * Returns: A dbus message containing an error on failure or NULL on success
1897 * Asks wpa_supplicant to internally store a binary blobs.
1899 DBusMessage
* wpas_dbus_handler_add_blob(DBusMessage
*message
,
1900 struct wpa_supplicant
*wpa_s
)
1902 DBusMessage
*reply
= NULL
;
1903 DBusMessageIter iter
, array_iter
;
1908 struct wpa_config_blob
*blob
= NULL
;
1910 dbus_message_iter_init(message
, &iter
);
1911 dbus_message_iter_get_basic(&iter
, &blob_name
);
1913 if (wpa_config_get_blob(wpa_s
->conf
, blob_name
)) {
1914 return dbus_message_new_error(message
,
1915 WPAS_DBUS_ERROR_BLOB_EXISTS
,
1919 dbus_message_iter_next(&iter
);
1920 dbus_message_iter_recurse(&iter
, &array_iter
);
1922 dbus_message_iter_get_fixed_array(&array_iter
, &blob_data
, &blob_len
);
1924 blob
= os_zalloc(sizeof(*blob
));
1926 reply
= wpas_dbus_error_no_memory(message
);
1930 blob
->data
= os_malloc(blob_len
);
1931 blob
->name
= os_strdup(blob_name
);
1932 if (!blob
->data
|| !blob
->name
) {
1933 reply
= wpas_dbus_error_no_memory(message
);
1936 os_memcpy(blob
->data
, blob_data
, blob_len
);
1937 blob
->len
= blob_len
;
1939 wpa_config_set_blob(wpa_s
->conf
, blob
);
1940 wpas_notify_blob_added(wpa_s
, blob
->name
);
1946 os_free(blob
->name
);
1947 os_free(blob
->data
);
1955 * wpas_dbus_handler_get_blob - Get named binary blob (ie, for certificates)
1956 * @message: Pointer to incoming dbus message
1957 * @wpa_s: %wpa_supplicant data structure
1958 * Returns: A dbus message containing array of bytes (blob)
1960 * Gets one wpa_supplicant's binary blobs.
1962 DBusMessage
* wpas_dbus_handler_get_blob(DBusMessage
*message
,
1963 struct wpa_supplicant
*wpa_s
)
1965 DBusMessage
*reply
= NULL
;
1966 DBusMessageIter iter
, array_iter
;
1969 const struct wpa_config_blob
*blob
;
1971 dbus_message_get_args(message
, NULL
, DBUS_TYPE_STRING
, &blob_name
,
1974 blob
= wpa_config_get_blob(wpa_s
->conf
, blob_name
);
1976 return dbus_message_new_error(message
,
1977 WPAS_DBUS_ERROR_BLOB_UNKNOWN
,
1981 reply
= dbus_message_new_method_return(message
);
1983 return wpas_dbus_error_no_memory(message
);
1985 dbus_message_iter_init_append(reply
, &iter
);
1987 if (!dbus_message_iter_open_container(&iter
, DBUS_TYPE_ARRAY
,
1988 DBUS_TYPE_BYTE_AS_STRING
,
1990 !dbus_message_iter_append_fixed_array(&array_iter
, DBUS_TYPE_BYTE
,
1991 &(blob
->data
), blob
->len
) ||
1992 !dbus_message_iter_close_container(&iter
, &array_iter
)) {
1993 dbus_message_unref(reply
);
1994 reply
= wpas_dbus_error_no_memory(message
);
2002 * wpas_remove_handler_remove_blob - Remove named binary blob
2003 * @message: Pointer to incoming dbus message
2004 * @wpa_s: %wpa_supplicant data structure
2005 * Returns: NULL on success or dbus error
2007 * Asks wpa_supplicant to internally remove a binary blobs.
2009 DBusMessage
* wpas_dbus_handler_remove_blob(DBusMessage
*message
,
2010 struct wpa_supplicant
*wpa_s
)
2012 DBusMessage
*reply
= NULL
;
2015 dbus_message_get_args(message
, NULL
, DBUS_TYPE_STRING
, &blob_name
,
2018 if (wpa_config_remove_blob(wpa_s
->conf
, blob_name
)) {
2019 return dbus_message_new_error(message
,
2020 WPAS_DBUS_ERROR_BLOB_UNKNOWN
,
2023 wpas_notify_blob_removed(wpa_s
, blob_name
);
2029 #endif /* CONFIG_NO_CONFIG_BLOBS */
2033 * wpas_dbus_handler_flush_bss - Flush the BSS cache
2034 * @message: Pointer to incoming dbus message
2035 * @wpa_s: wpa_supplicant structure for a network interface
2038 * Handler function for "FlushBSS" method call of network interface.
2040 DBusMessage
* wpas_dbus_handler_flush_bss(DBusMessage
*message
,
2041 struct wpa_supplicant
*wpa_s
)
2045 dbus_message_get_args(message
, NULL
, DBUS_TYPE_UINT32
, &age
,
2049 wpa_bss_flush(wpa_s
);
2051 wpa_bss_flush_by_age(wpa_s
, age
);
2057 #ifdef CONFIG_AUTOSCAN
2059 * wpas_dbus_handler_autoscan - Set autoscan parameters for the interface
2060 * @message: Pointer to incoming dbus message
2061 * @wpa_s: wpa_supplicant structure for a network interface
2064 * Handler function for "AutoScan" method call of network interface.
2066 DBusMessage
* wpas_dbus_handler_autoscan(DBusMessage
*message
,
2067 struct wpa_supplicant
*wpa_s
)
2069 DBusMessage
*reply
= NULL
;
2070 enum wpa_states state
= wpa_s
->wpa_state
;
2073 dbus_message_get_args(message
, NULL
, DBUS_TYPE_STRING
, &arg
,
2076 if (arg
!= NULL
&& os_strlen(arg
) > 0) {
2079 tmp
= os_strdup(arg
);
2081 reply
= wpas_dbus_error_no_memory(message
);
2083 os_free(wpa_s
->conf
->autoscan
);
2084 wpa_s
->conf
->autoscan
= tmp
;
2085 if (state
== WPA_DISCONNECTED
|| state
== WPA_INACTIVE
)
2086 autoscan_init(wpa_s
, 1);
2087 else if (state
== WPA_SCANNING
)
2088 wpa_supplicant_reinit_autoscan(wpa_s
);
2090 } else if (arg
!= NULL
&& os_strlen(arg
) == 0) {
2091 os_free(wpa_s
->conf
->autoscan
);
2092 wpa_s
->conf
->autoscan
= NULL
;
2093 autoscan_deinit(wpa_s
);
2095 reply
= dbus_message_new_error(message
,
2096 DBUS_ERROR_INVALID_ARGS
,
2101 #endif /* CONFIG_AUTOSCAN */
2105 * wpas_dbus_handler_eap_logoff - IEEE 802.1X EAPOL state machine logoff
2106 * @message: Pointer to incoming dbus message
2107 * @wpa_s: wpa_supplicant structure for a network interface
2110 * Handler function for "EAPLogoff" method call of network interface.
2112 DBusMessage
* wpas_dbus_handler_eap_logoff(DBusMessage
*message
,
2113 struct wpa_supplicant
*wpa_s
)
2115 eapol_sm_notify_logoff(wpa_s
->eapol
, TRUE
);
2121 * wpas_dbus_handler_eap_logon - IEEE 802.1X EAPOL state machine logon
2122 * @message: Pointer to incoming dbus message
2123 * @wpa_s: wpa_supplicant structure for a network interface
2126 * Handler function for "EAPLogin" method call of network interface.
2128 DBusMessage
* wpas_dbus_handler_eap_logon(DBusMessage
*message
,
2129 struct wpa_supplicant
*wpa_s
)
2131 eapol_sm_notify_logoff(wpa_s
->eapol
, FALSE
);
2138 static int get_peer_hwaddr_helper(DBusMessage
*message
, const char *func_name
,
2139 u8
*peer_address
, DBusMessage
**error
)
2141 const char *peer_string
;
2145 if (!dbus_message_get_args(message
, NULL
,
2146 DBUS_TYPE_STRING
, &peer_string
,
2147 DBUS_TYPE_INVALID
)) {
2148 *error
= wpas_dbus_error_invalid_args(message
, NULL
);
2152 if (hwaddr_aton(peer_string
, peer_address
)) {
2153 wpa_printf(MSG_DEBUG
, "%s: invalid address '%s'",
2154 func_name
, peer_string
);
2155 *error
= wpas_dbus_error_invalid_args(
2156 message
, "Invalid hardware address format");
2165 * wpas_dbus_handler_tdls_discover - Discover TDLS peer
2166 * @message: Pointer to incoming dbus message
2167 * @wpa_s: wpa_supplicant structure for a network interface
2168 * Returns: NULL indicating success or DBus error message on failure
2170 * Handler function for "TDLSDiscover" method call of network interface.
2172 DBusMessage
* wpas_dbus_handler_tdls_discover(DBusMessage
*message
,
2173 struct wpa_supplicant
*wpa_s
)
2176 DBusMessage
*error_reply
;
2179 if (get_peer_hwaddr_helper(message
, __func__
, peer
, &error_reply
) < 0)
2182 wpa_printf(MSG_DEBUG
, "DBUS TDLS_DISCOVER " MACSTR
, MAC2STR(peer
));
2184 if (wpa_tdls_is_external_setup(wpa_s
->wpa
))
2185 ret
= wpa_tdls_send_discovery_request(wpa_s
->wpa
, peer
);
2187 ret
= wpa_drv_tdls_oper(wpa_s
, TDLS_DISCOVERY_REQ
, peer
);
2190 return wpas_dbus_error_unknown_error(
2191 message
, "error performing TDLS discovery");
2199 * wpas_dbus_handler_tdls_setup - Setup TDLS session
2200 * @message: Pointer to incoming dbus message
2201 * @wpa_s: wpa_supplicant structure for a network interface
2202 * Returns: NULL indicating success or DBus error message on failure
2204 * Handler function for "TDLSSetup" method call of network interface.
2206 DBusMessage
* wpas_dbus_handler_tdls_setup(DBusMessage
*message
,
2207 struct wpa_supplicant
*wpa_s
)
2210 DBusMessage
*error_reply
;
2213 if (get_peer_hwaddr_helper(message
, __func__
, peer
, &error_reply
) < 0)
2216 wpa_printf(MSG_DEBUG
, "DBUS TDLS_SETUP " MACSTR
, MAC2STR(peer
));
2218 wpa_tdls_remove(wpa_s
->wpa
, peer
);
2219 if (wpa_tdls_is_external_setup(wpa_s
->wpa
))
2220 ret
= wpa_tdls_start(wpa_s
->wpa
, peer
);
2222 ret
= wpa_drv_tdls_oper(wpa_s
, TDLS_SETUP
, peer
);
2225 return wpas_dbus_error_unknown_error(
2226 message
, "error performing TDLS setup");
2234 * wpas_dbus_handler_tdls_status - Return TDLS session status
2235 * @message: Pointer to incoming dbus message
2236 * @wpa_s: wpa_supplicant structure for a network interface
2237 * Returns: A string representing the state of the link to this TDLS peer
2239 * Handler function for "TDLSStatus" method call of network interface.
2241 DBusMessage
* wpas_dbus_handler_tdls_status(DBusMessage
*message
,
2242 struct wpa_supplicant
*wpa_s
)
2246 const char *tdls_status
;
2248 if (get_peer_hwaddr_helper(message
, __func__
, peer
, &reply
) < 0)
2251 wpa_printf(MSG_DEBUG
, "DBUS TDLS_STATUS " MACSTR
, MAC2STR(peer
));
2253 tdls_status
= wpa_tdls_get_link_status(wpa_s
->wpa
, peer
);
2255 reply
= dbus_message_new_method_return(message
);
2256 dbus_message_append_args(reply
, DBUS_TYPE_STRING
,
2257 &tdls_status
, DBUS_TYPE_INVALID
);
2263 * wpas_dbus_handler_tdls_teardown - Teardown TDLS session
2264 * @message: Pointer to incoming dbus message
2265 * @wpa_s: wpa_supplicant structure for a network interface
2266 * Returns: NULL indicating success or DBus error message on failure
2268 * Handler function for "TDLSTeardown" method call of network interface.
2270 DBusMessage
* wpas_dbus_handler_tdls_teardown(DBusMessage
*message
,
2271 struct wpa_supplicant
*wpa_s
)
2274 DBusMessage
*error_reply
;
2277 if (get_peer_hwaddr_helper(message
, __func__
, peer
, &error_reply
) < 0)
2280 wpa_printf(MSG_DEBUG
, "DBUS TDLS_TEARDOWN " MACSTR
, MAC2STR(peer
));
2282 if (wpa_tdls_is_external_setup(wpa_s
->wpa
))
2283 ret
= wpa_tdls_teardown_link(
2285 WLAN_REASON_TDLS_TEARDOWN_UNSPECIFIED
);
2287 ret
= wpa_drv_tdls_oper(wpa_s
, TDLS_TEARDOWN
, peer
);
2290 return wpas_dbus_error_unknown_error(
2291 message
, "error performing TDLS teardown");
2297 #endif /* CONFIG_TDLS */
2300 #ifndef CONFIG_NO_CONFIG_WRITE
2302 * wpas_dbus_handler_save_config - Save configuration to configuration file
2303 * @message: Pointer to incoming dbus message
2304 * @wpa_s: wpa_supplicant structure for a network interface
2305 * Returns: NULL on Success, Otherwise errror message
2307 * Handler function for "SaveConfig" method call of network interface.
2309 DBusMessage
* wpas_dbus_handler_save_config(DBusMessage
*message
,
2310 struct wpa_supplicant
*wpa_s
)
2314 if (!wpa_s
->conf
->update_config
) {
2315 return wpas_dbus_error_unknown_error(
2317 "Not allowed to update configuration (update_config=0)");
2320 ret
= wpa_config_write(wpa_s
->confname
, wpa_s
->conf
);
2322 return wpas_dbus_error_unknown_error(
2323 message
, "Failed to update configuration");
2326 #endif /* CONFIG_NO_CONFIG_WRITE */
2330 * wpas_dbus_handler_set_pkcs11_engine_and_module_path - Set PKCS #11 engine and module path
2331 * @message: Pointer to incoming dbus message
2332 * @wpa_s: %wpa_supplicant data structure
2333 * Returns: A dbus message containing an error on failure or NULL on success
2335 * Sets the PKCS #11 engine and module path.
2337 DBusMessage
* wpas_dbus_handler_set_pkcs11_engine_and_module_path(
2338 DBusMessage
*message
, struct wpa_supplicant
*wpa_s
)
2340 DBusMessageIter iter
;
2342 char *pkcs11_engine_path
= NULL
;
2343 char *pkcs11_module_path
= NULL
;
2345 dbus_message_iter_init(message
, &iter
);
2346 dbus_message_iter_get_basic(&iter
, &value
);
2347 if (value
== NULL
) {
2348 return dbus_message_new_error(
2349 message
, DBUS_ERROR_INVALID_ARGS
,
2350 "Invalid pkcs11_engine_path argument");
2352 /* Empty path defaults to NULL */
2353 if (os_strlen(value
))
2354 pkcs11_engine_path
= value
;
2356 dbus_message_iter_next(&iter
);
2357 dbus_message_iter_get_basic(&iter
, &value
);
2358 if (value
== NULL
) {
2359 os_free(pkcs11_engine_path
);
2360 return dbus_message_new_error(
2361 message
, DBUS_ERROR_INVALID_ARGS
,
2362 "Invalid pkcs11_module_path argument");
2364 /* Empty path defaults to NULL */
2365 if (os_strlen(value
))
2366 pkcs11_module_path
= value
;
2368 if (wpas_set_pkcs11_engine_and_module_path(wpa_s
, pkcs11_engine_path
,
2369 pkcs11_module_path
))
2370 return dbus_message_new_error(
2371 message
, DBUS_ERROR_FAILED
,
2372 "Reinit of the EAPOL state machine with the new PKCS #11 engine and module path failed.");
2374 if (wpa_s
->dbus_new_path
) {
2375 wpa_dbus_mark_property_changed(
2376 wpa_s
->global
->dbus
, wpa_s
->dbus_new_path
,
2377 WPAS_DBUS_NEW_IFACE_INTERFACE
, "PKCS11EnginePath");
2378 wpa_dbus_mark_property_changed(
2379 wpa_s
->global
->dbus
, wpa_s
->dbus_new_path
,
2380 WPAS_DBUS_NEW_IFACE_INTERFACE
, "PKCS11ModulePath");
2388 * wpas_dbus_getter_capabilities - Return interface capabilities
2389 * @iter: Pointer to incoming dbus message iter
2390 * @error: Location to store error on failure
2391 * @user_data: Function specific data
2392 * Returns: TRUE on success, FALSE on failure
2394 * Getter for "Capabilities" property of an interface.
2396 dbus_bool_t
wpas_dbus_getter_capabilities(
2397 const struct wpa_dbus_property_desc
*property_desc
,
2398 DBusMessageIter
*iter
, DBusError
*error
, void *user_data
)
2400 struct wpa_supplicant
*wpa_s
= user_data
;
2401 struct wpa_driver_capa capa
;
2403 DBusMessageIter iter_dict
, iter_dict_entry
, iter_dict_val
, iter_array
,
2405 const char *scans
[] = { "active", "passive", "ssid" };
2407 if (!dbus_message_iter_open_container(iter
, DBUS_TYPE_VARIANT
,
2408 "a{sv}", &variant_iter
) ||
2409 !wpa_dbus_dict_open_write(&variant_iter
, &iter_dict
))
2412 res
= wpa_drv_get_capa(wpa_s
, &capa
);
2414 /***** pairwise cipher */
2416 const char *args
[] = {"ccmp", "tkip", "none"};
2418 if (!wpa_dbus_dict_append_string_array(
2419 &iter_dict
, "Pairwise", args
,
2423 if (!wpa_dbus_dict_begin_string_array(&iter_dict
, "Pairwise",
2427 ((capa
.enc
& WPA_DRIVER_CAPA_ENC_CCMP_256
) &&
2428 !wpa_dbus_dict_string_array_add_element(
2429 &iter_array
, "ccmp-256")) ||
2430 ((capa
.enc
& WPA_DRIVER_CAPA_ENC_GCMP_256
) &&
2431 !wpa_dbus_dict_string_array_add_element(
2432 &iter_array
, "gcmp-256")) ||
2433 ((capa
.enc
& WPA_DRIVER_CAPA_ENC_CCMP
) &&
2434 !wpa_dbus_dict_string_array_add_element(
2435 &iter_array
, "ccmp")) ||
2436 ((capa
.enc
& WPA_DRIVER_CAPA_ENC_GCMP
) &&
2437 !wpa_dbus_dict_string_array_add_element(
2438 &iter_array
, "gcmp")) ||
2439 ((capa
.enc
& WPA_DRIVER_CAPA_ENC_TKIP
) &&
2440 !wpa_dbus_dict_string_array_add_element(
2441 &iter_array
, "tkip")) ||
2442 ((capa
.key_mgmt
& WPA_DRIVER_CAPA_KEY_MGMT_WPA_NONE
) &&
2443 !wpa_dbus_dict_string_array_add_element(
2444 &iter_array
, "none")) ||
2445 !wpa_dbus_dict_end_string_array(&iter_dict
,
2452 /***** group cipher */
2454 const char *args
[] = {
2455 "ccmp", "tkip", "wep104", "wep40"
2458 if (!wpa_dbus_dict_append_string_array(
2459 &iter_dict
, "Group", args
,
2463 if (!wpa_dbus_dict_begin_string_array(&iter_dict
, "Group",
2467 ((capa
.enc
& WPA_DRIVER_CAPA_ENC_CCMP_256
) &&
2468 !wpa_dbus_dict_string_array_add_element(
2469 &iter_array
, "ccmp-256")) ||
2470 ((capa
.enc
& WPA_DRIVER_CAPA_ENC_GCMP_256
) &&
2471 !wpa_dbus_dict_string_array_add_element(
2472 &iter_array
, "gcmp-256")) ||
2473 ((capa
.enc
& WPA_DRIVER_CAPA_ENC_CCMP
) &&
2474 !wpa_dbus_dict_string_array_add_element(
2475 &iter_array
, "ccmp")) ||
2476 ((capa
.enc
& WPA_DRIVER_CAPA_ENC_GCMP
) &&
2477 !wpa_dbus_dict_string_array_add_element(
2478 &iter_array
, "gcmp")) ||
2479 ((capa
.enc
& WPA_DRIVER_CAPA_ENC_TKIP
) &&
2480 !wpa_dbus_dict_string_array_add_element(
2481 &iter_array
, "tkip")) ||
2482 ((capa
.enc
& WPA_DRIVER_CAPA_ENC_WEP104
) &&
2483 !wpa_dbus_dict_string_array_add_element(
2484 &iter_array
, "wep104")) ||
2485 ((capa
.enc
& WPA_DRIVER_CAPA_ENC_WEP40
) &&
2486 !wpa_dbus_dict_string_array_add_element(
2487 &iter_array
, "wep40")) ||
2488 !wpa_dbus_dict_end_string_array(&iter_dict
,
2495 if (!wpa_dbus_dict_begin_string_array(&iter_dict
, "GroupMgmt",
2499 (res
== 0 && (capa
.enc
& WPA_DRIVER_CAPA_ENC_BIP
) &&
2500 !wpa_dbus_dict_string_array_add_element(
2501 &iter_array
, "aes-128-cmac")) ||
2502 (res
== 0 && (capa
.enc
& WPA_DRIVER_CAPA_ENC_BIP_GMAC_128
) &&
2503 !wpa_dbus_dict_string_array_add_element(
2504 &iter_array
, "bip-gmac-128")) ||
2505 (res
== 0 && (capa
.enc
& WPA_DRIVER_CAPA_ENC_BIP_GMAC_256
) &&
2506 !wpa_dbus_dict_string_array_add_element(
2507 &iter_array
, "bip-gmac-256")) ||
2508 (res
== 0 && (capa
.enc
& WPA_DRIVER_CAPA_ENC_BIP_CMAC_256
) &&
2509 !wpa_dbus_dict_string_array_add_element(
2510 &iter_array
, "bip-cmac-256")) ||
2511 !wpa_dbus_dict_end_string_array(&iter_dict
,
2517 /***** key management */
2519 const char *args
[] = {
2520 "wpa-psk", "wpa-eap", "ieee8021x", "wpa-none",
2523 #endif /* CONFIG_WPS */
2526 if (!wpa_dbus_dict_append_string_array(
2527 &iter_dict
, "KeyMgmt", args
,
2531 if (!wpa_dbus_dict_begin_string_array(&iter_dict
, "KeyMgmt",
2535 !wpa_dbus_dict_string_array_add_element(&iter_array
,
2537 !wpa_dbus_dict_string_array_add_element(&iter_array
,
2541 if (capa
.key_mgmt
& (WPA_DRIVER_CAPA_KEY_MGMT_WPA
|
2542 WPA_DRIVER_CAPA_KEY_MGMT_WPA2
)) {
2543 if (!wpa_dbus_dict_string_array_add_element(
2544 &iter_array
, "wpa-eap") ||
2545 ((capa
.key_mgmt
& WPA_DRIVER_CAPA_KEY_MGMT_FT
) &&
2546 !wpa_dbus_dict_string_array_add_element(
2547 &iter_array
, "wpa-ft-eap")))
2550 /* TODO: Ensure that driver actually supports sha256 encryption. */
2551 #ifdef CONFIG_IEEE80211W
2552 if (!wpa_dbus_dict_string_array_add_element(
2553 &iter_array
, "wpa-eap-sha256"))
2555 #endif /* CONFIG_IEEE80211W */
2558 if (capa
.key_mgmt
& (WPA_DRIVER_CAPA_KEY_MGMT_WPA_PSK
|
2559 WPA_DRIVER_CAPA_KEY_MGMT_WPA2_PSK
)) {
2560 if (!wpa_dbus_dict_string_array_add_element(
2561 &iter_array
, "wpa-psk") ||
2563 WPA_DRIVER_CAPA_KEY_MGMT_FT_PSK
) &&
2564 !wpa_dbus_dict_string_array_add_element(
2565 &iter_array
, "wpa-ft-psk")))
2568 /* TODO: Ensure that driver actually supports sha256 encryption. */
2569 #ifdef CONFIG_IEEE80211W
2570 if (!wpa_dbus_dict_string_array_add_element(
2571 &iter_array
, "wpa-psk-sha256"))
2573 #endif /* CONFIG_IEEE80211W */
2576 if ((capa
.key_mgmt
& WPA_DRIVER_CAPA_KEY_MGMT_WPA_NONE
) &&
2577 !wpa_dbus_dict_string_array_add_element(&iter_array
,
2583 if (!wpa_dbus_dict_string_array_add_element(&iter_array
,
2586 #endif /* CONFIG_WPS */
2588 if (!wpa_dbus_dict_end_string_array(&iter_dict
,
2595 /***** WPA protocol */
2597 const char *args
[] = { "rsn", "wpa" };
2599 if (!wpa_dbus_dict_append_string_array(
2600 &iter_dict
, "Protocol", args
,
2604 if (!wpa_dbus_dict_begin_string_array(&iter_dict
, "Protocol",
2608 ((capa
.key_mgmt
& (WPA_DRIVER_CAPA_KEY_MGMT_WPA2
|
2609 WPA_DRIVER_CAPA_KEY_MGMT_WPA2_PSK
)) &&
2610 !wpa_dbus_dict_string_array_add_element(
2611 &iter_array
, "rsn")) ||
2612 ((capa
.key_mgmt
& (WPA_DRIVER_CAPA_KEY_MGMT_WPA
|
2613 WPA_DRIVER_CAPA_KEY_MGMT_WPA_PSK
)) &&
2614 !wpa_dbus_dict_string_array_add_element(
2615 &iter_array
, "wpa")) ||
2616 !wpa_dbus_dict_end_string_array(&iter_dict
,
2625 const char *args
[] = { "open", "shared", "leap" };
2627 if (!wpa_dbus_dict_append_string_array(
2628 &iter_dict
, "AuthAlg", args
,
2632 if (!wpa_dbus_dict_begin_string_array(&iter_dict
, "AuthAlg",
2638 if (((capa
.auth
& WPA_DRIVER_AUTH_OPEN
) &&
2639 !wpa_dbus_dict_string_array_add_element(
2640 &iter_array
, "open")) ||
2641 ((capa
.auth
& WPA_DRIVER_AUTH_SHARED
) &&
2642 !wpa_dbus_dict_string_array_add_element(
2643 &iter_array
, "shared")) ||
2644 ((capa
.auth
& WPA_DRIVER_AUTH_LEAP
) &&
2645 !wpa_dbus_dict_string_array_add_element(
2646 &iter_array
, "leap")) ||
2647 !wpa_dbus_dict_end_string_array(&iter_dict
,
2655 if (!wpa_dbus_dict_append_string_array(&iter_dict
, "Scan", scans
,
2660 if (!wpa_dbus_dict_begin_string_array(&iter_dict
, "Modes",
2664 !wpa_dbus_dict_string_array_add_element(
2665 &iter_array
, "infrastructure") ||
2666 (res
>= 0 && (capa
.flags
& WPA_DRIVER_FLAGS_IBSS
) &&
2667 !wpa_dbus_dict_string_array_add_element(
2668 &iter_array
, "ad-hoc")) ||
2669 (res
>= 0 && (capa
.flags
& WPA_DRIVER_FLAGS_AP
) &&
2670 !wpa_dbus_dict_string_array_add_element(
2671 &iter_array
, "ap")) ||
2672 (res
>= 0 && (capa
.flags
& WPA_DRIVER_FLAGS_P2P_CAPABLE
) &&
2673 !wpa_s
->conf
->p2p_disabled
&&
2674 !wpa_dbus_dict_string_array_add_element(
2675 &iter_array
, "p2p")) ||
2677 (res
>= 0 && (capa
.flags
& WPA_DRIVER_FLAGS_MESH
) &&
2678 !wpa_dbus_dict_string_array_add_element(
2679 &iter_array
, "mesh")) ||
2680 #endif /* CONFIG_MESH */
2681 !wpa_dbus_dict_end_string_array(&iter_dict
,
2689 dbus_int32_t max_scan_ssid
= capa
.max_scan_ssids
;
2691 if (!wpa_dbus_dict_append_int32(&iter_dict
, "MaxScanSSID",
2696 if (!wpa_dbus_dict_close_write(&variant_iter
, &iter_dict
) ||
2697 !dbus_message_iter_close_container(iter
, &variant_iter
))
2703 dbus_set_error_const(error
, DBUS_ERROR_NO_MEMORY
, "no memory");
2709 * wpas_dbus_getter_state - Get interface state
2710 * @iter: Pointer to incoming dbus message iter
2711 * @error: Location to store error on failure
2712 * @user_data: Function specific data
2713 * Returns: TRUE on success, FALSE on failure
2715 * Getter for "State" property.
2717 dbus_bool_t
wpas_dbus_getter_state(
2718 const struct wpa_dbus_property_desc
*property_desc
,
2719 DBusMessageIter
*iter
, DBusError
*error
, void *user_data
)
2721 struct wpa_supplicant
*wpa_s
= user_data
;
2722 const char *str_state
;
2723 char *state_ls
, *tmp
;
2724 dbus_bool_t success
= FALSE
;
2726 str_state
= wpa_supplicant_state_txt(wpa_s
->wpa_state
);
2728 /* make state string lowercase to fit new DBus API convention
2730 state_ls
= tmp
= os_strdup(str_state
);
2732 dbus_set_error_const(error
, DBUS_ERROR_NO_MEMORY
, "no memory");
2736 *tmp
= tolower(*tmp
);
2740 success
= wpas_dbus_simple_property_getter(iter
, DBUS_TYPE_STRING
,
2750 * wpas_dbus_new_iface_get_scanning - Get interface scanning state
2751 * @iter: Pointer to incoming dbus message iter
2752 * @error: Location to store error on failure
2753 * @user_data: Function specific data
2754 * Returns: TRUE on success, FALSE on failure
2756 * Getter for "scanning" property.
2758 dbus_bool_t
wpas_dbus_getter_scanning(
2759 const struct wpa_dbus_property_desc
*property_desc
,
2760 DBusMessageIter
*iter
, DBusError
*error
, void *user_data
)
2762 struct wpa_supplicant
*wpa_s
= user_data
;
2763 dbus_bool_t scanning
= wpa_s
->scanning
? TRUE
: FALSE
;
2765 return wpas_dbus_simple_property_getter(iter
, DBUS_TYPE_BOOLEAN
,
2771 * wpas_dbus_getter_ap_scan - Control roaming mode
2772 * @iter: Pointer to incoming dbus message iter
2773 * @error: Location to store error on failure
2774 * @user_data: Function specific data
2775 * Returns: TRUE on success, FALSE on failure
2777 * Getter function for "ApScan" property.
2779 dbus_bool_t
wpas_dbus_getter_ap_scan(
2780 const struct wpa_dbus_property_desc
*property_desc
,
2781 DBusMessageIter
*iter
, DBusError
*error
, void *user_data
)
2783 struct wpa_supplicant
*wpa_s
= user_data
;
2784 dbus_uint32_t ap_scan
= wpa_s
->conf
->ap_scan
;
2786 return wpas_dbus_simple_property_getter(iter
, DBUS_TYPE_UINT32
,
2792 * wpas_dbus_setter_ap_scan - Control roaming mode
2793 * @iter: Pointer to incoming dbus message iter
2794 * @error: Location to store error on failure
2795 * @user_data: Function specific data
2796 * Returns: TRUE on success, FALSE on failure
2798 * Setter function for "ApScan" property.
2800 dbus_bool_t
wpas_dbus_setter_ap_scan(
2801 const struct wpa_dbus_property_desc
*property_desc
,
2802 DBusMessageIter
*iter
, DBusError
*error
, void *user_data
)
2804 struct wpa_supplicant
*wpa_s
= user_data
;
2805 dbus_uint32_t ap_scan
;
2807 if (!wpas_dbus_simple_property_setter(iter
, error
, DBUS_TYPE_UINT32
,
2811 if (wpa_supplicant_set_ap_scan(wpa_s
, ap_scan
)) {
2812 dbus_set_error_const(error
, DBUS_ERROR_FAILED
,
2813 "ap_scan must be 0, 1, or 2");
2820 #ifdef CONFIG_IEEE80211W
2823 * wpas_dbus_getter_pmf - Control PMF default
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 * Getter function for "Pmf" property.
2831 dbus_bool_t
wpas_dbus_getter_pmf(
2832 const struct wpa_dbus_property_desc
*property_desc
,
2833 DBusMessageIter
*iter
, DBusError
*error
, void *user_data
)
2835 struct wpa_supplicant
*wpa_s
= user_data
;
2836 dbus_uint32_t pmf
= wpa_s
->conf
->pmf
;
2838 return wpas_dbus_simple_property_getter(iter
, DBUS_TYPE_UINT32
,
2844 * wpas_dbus_setter_pmf - Control PMF default
2845 * @iter: Pointer to incoming dbus message iter
2846 * @error: Location to store error on failure
2847 * @user_data: Function specific data
2848 * Returns: TRUE on success, FALSE on failure
2850 * Setter function for "Pmf" property.
2852 dbus_bool_t
wpas_dbus_setter_pmf(
2853 const struct wpa_dbus_property_desc
*property_desc
,
2854 DBusMessageIter
*iter
, DBusError
*error
, void *user_data
)
2856 struct wpa_supplicant
*wpa_s
= user_data
;
2859 if (!wpas_dbus_simple_property_setter(iter
, error
, DBUS_TYPE_UINT32
,
2864 dbus_set_error_const(error
, DBUS_ERROR_FAILED
,
2865 "Pmf must be 0, 1, or 2");
2868 wpa_s
->conf
->pmf
= pmf
;
2872 #endif /* CONFIG_IEEE80211W */
2876 * wpas_dbus_getter_fast_reauth - Control fast
2877 * reauthentication (TLS session resumption)
2878 * @iter: Pointer to incoming dbus message iter
2879 * @error: Location to store error on failure
2880 * @user_data: Function specific data
2881 * Returns: TRUE on success, FALSE on failure
2883 * Getter function for "FastReauth" property.
2885 dbus_bool_t
wpas_dbus_getter_fast_reauth(
2886 const struct wpa_dbus_property_desc
*property_desc
,
2887 DBusMessageIter
*iter
, DBusError
*error
, void *user_data
)
2889 struct wpa_supplicant
*wpa_s
= user_data
;
2890 dbus_bool_t fast_reauth
= wpa_s
->conf
->fast_reauth
? TRUE
: FALSE
;
2892 return wpas_dbus_simple_property_getter(iter
, DBUS_TYPE_BOOLEAN
,
2893 &fast_reauth
, error
);
2898 * wpas_dbus_setter_fast_reauth - Control fast
2899 * reauthentication (TLS session resumption)
2900 * @iter: Pointer to incoming dbus message iter
2901 * @error: Location to store error on failure
2902 * @user_data: Function specific data
2903 * Returns: TRUE on success, FALSE on failure
2905 * Setter function for "FastReauth" property.
2907 dbus_bool_t
wpas_dbus_setter_fast_reauth(
2908 const struct wpa_dbus_property_desc
*property_desc
,
2909 DBusMessageIter
*iter
, DBusError
*error
, void *user_data
)
2911 struct wpa_supplicant
*wpa_s
= user_data
;
2912 dbus_bool_t fast_reauth
;
2914 if (!wpas_dbus_simple_property_setter(iter
, error
, DBUS_TYPE_BOOLEAN
,
2918 wpa_s
->conf
->fast_reauth
= fast_reauth
;
2924 * wpas_dbus_getter_disconnect_reason - Get most recent reason for disconnect
2925 * @iter: Pointer to incoming dbus message iter
2926 * @error: Location to store error on failure
2927 * @user_data: Function specific data
2928 * Returns: TRUE on success, FALSE on failure
2930 * Getter for "DisconnectReason" property. The reason is negative if it is
2931 * locally generated.
2933 dbus_bool_t
wpas_dbus_getter_disconnect_reason(
2934 const struct wpa_dbus_property_desc
*property_desc
,
2935 DBusMessageIter
*iter
, DBusError
*error
, void *user_data
)
2937 struct wpa_supplicant
*wpa_s
= user_data
;
2938 dbus_int32_t reason
= wpa_s
->disconnect_reason
;
2940 return wpas_dbus_simple_property_getter(iter
, DBUS_TYPE_INT32
,
2946 * wpas_dbus_getter_assoc_status_code - Get most recent failed assoc status code
2947 * @iter: Pointer to incoming dbus message iter
2948 * @error: Location to store error on failure
2949 * @user_data: Function specific data
2950 * Returns: TRUE on success, FALSE on failure
2952 * Getter for "AssocStatusCode" property.
2954 dbus_bool_t
wpas_dbus_getter_assoc_status_code(
2955 const struct wpa_dbus_property_desc
*property_desc
,
2956 DBusMessageIter
*iter
, DBusError
*error
, void *user_data
)
2958 struct wpa_supplicant
*wpa_s
= user_data
;
2959 dbus_int32_t status_code
= wpa_s
->assoc_status_code
;
2961 return wpas_dbus_simple_property_getter(iter
, DBUS_TYPE_INT32
,
2962 &status_code
, error
);
2967 * wpas_dbus_getter_bss_expire_age - Get BSS entry expiration age
2968 * @iter: Pointer to incoming dbus message iter
2969 * @error: Location to store error on failure
2970 * @user_data: Function specific data
2971 * Returns: TRUE on success, FALSE on failure
2973 * Getter function for "BSSExpireAge" property.
2975 dbus_bool_t
wpas_dbus_getter_bss_expire_age(
2976 const struct wpa_dbus_property_desc
*property_desc
,
2977 DBusMessageIter
*iter
, DBusError
*error
, void *user_data
)
2979 struct wpa_supplicant
*wpa_s
= user_data
;
2980 dbus_uint32_t expire_age
= wpa_s
->conf
->bss_expiration_age
;
2982 return wpas_dbus_simple_property_getter(iter
, DBUS_TYPE_UINT32
,
2983 &expire_age
, error
);
2988 * wpas_dbus_setter_bss_expire_age - Control BSS entry expiration age
2989 * @iter: Pointer to incoming dbus message iter
2990 * @error: Location to store error on failure
2991 * @user_data: Function specific data
2992 * Returns: TRUE on success, FALSE on failure
2994 * Setter function for "BSSExpireAge" property.
2996 dbus_bool_t
wpas_dbus_setter_bss_expire_age(
2997 const struct wpa_dbus_property_desc
*property_desc
,
2998 DBusMessageIter
*iter
, DBusError
*error
, void *user_data
)
3000 struct wpa_supplicant
*wpa_s
= user_data
;
3001 dbus_uint32_t expire_age
;
3003 if (!wpas_dbus_simple_property_setter(iter
, error
, DBUS_TYPE_UINT32
,
3007 if (wpa_supplicant_set_bss_expiration_age(wpa_s
, expire_age
)) {
3008 dbus_set_error_const(error
, DBUS_ERROR_FAILED
,
3009 "BSSExpireAge must be >= 10");
3017 * wpas_dbus_getter_bss_expire_count - Get BSS entry expiration scan count
3018 * @iter: Pointer to incoming dbus message iter
3019 * @error: Location to store error on failure
3020 * @user_data: Function specific data
3021 * Returns: TRUE on success, FALSE on failure
3023 * Getter function for "BSSExpireCount" property.
3025 dbus_bool_t
wpas_dbus_getter_bss_expire_count(
3026 const struct wpa_dbus_property_desc
*property_desc
,
3027 DBusMessageIter
*iter
, DBusError
*error
, void *user_data
)
3029 struct wpa_supplicant
*wpa_s
= user_data
;
3030 dbus_uint32_t expire_count
= wpa_s
->conf
->bss_expiration_scan_count
;
3032 return wpas_dbus_simple_property_getter(iter
, DBUS_TYPE_UINT32
,
3033 &expire_count
, error
);
3038 * wpas_dbus_setter_bss_expire_count - Control BSS entry expiration scan count
3039 * @iter: Pointer to incoming dbus message iter
3040 * @error: Location to store error on failure
3041 * @user_data: Function specific data
3042 * Returns: TRUE on success, FALSE on failure
3044 * Setter function for "BSSExpireCount" property.
3046 dbus_bool_t
wpas_dbus_setter_bss_expire_count(
3047 const struct wpa_dbus_property_desc
*property_desc
,
3048 DBusMessageIter
*iter
, DBusError
*error
, void *user_data
)
3050 struct wpa_supplicant
*wpa_s
= user_data
;
3051 dbus_uint32_t expire_count
;
3053 if (!wpas_dbus_simple_property_setter(iter
, error
, DBUS_TYPE_UINT32
,
3057 if (wpa_supplicant_set_bss_expiration_count(wpa_s
, expire_count
)) {
3058 dbus_set_error_const(error
, DBUS_ERROR_FAILED
,
3059 "BSSExpireCount must be > 0");
3067 * wpas_dbus_getter_country - Control country code
3068 * @iter: Pointer to incoming dbus message iter
3069 * @error: Location to store error on failure
3070 * @user_data: Function specific data
3071 * Returns: TRUE on success, FALSE on failure
3073 * Getter function for "Country" property.
3075 dbus_bool_t
wpas_dbus_getter_country(
3076 const struct wpa_dbus_property_desc
*property_desc
,
3077 DBusMessageIter
*iter
, DBusError
*error
, void *user_data
)
3079 struct wpa_supplicant
*wpa_s
= user_data
;
3081 char *str
= country
;
3083 country
[0] = wpa_s
->conf
->country
[0];
3084 country
[1] = wpa_s
->conf
->country
[1];
3087 return wpas_dbus_simple_property_getter(iter
, DBUS_TYPE_STRING
,
3093 * wpas_dbus_setter_country - Control country code
3094 * @iter: Pointer to incoming dbus message iter
3095 * @error: Location to store error on failure
3096 * @user_data: Function specific data
3097 * Returns: TRUE on success, FALSE on failure
3099 * Setter function for "Country" property.
3101 dbus_bool_t
wpas_dbus_setter_country(
3102 const struct wpa_dbus_property_desc
*property_desc
,
3103 DBusMessageIter
*iter
, DBusError
*error
, void *user_data
)
3105 struct wpa_supplicant
*wpa_s
= user_data
;
3106 const char *country
;
3108 if (!wpas_dbus_simple_property_setter(iter
, error
, DBUS_TYPE_STRING
,
3112 if (!country
[0] || !country
[1]) {
3113 dbus_set_error_const(error
, DBUS_ERROR_FAILED
,
3114 "invalid country code");
3118 if (wpa_s
->drv_priv
!= NULL
&& wpa_drv_set_country(wpa_s
, country
)) {
3119 wpa_printf(MSG_DEBUG
, "Failed to set country");
3120 dbus_set_error_const(error
, DBUS_ERROR_FAILED
,
3121 "failed to set country code");
3125 wpa_s
->conf
->country
[0] = country
[0];
3126 wpa_s
->conf
->country
[1] = country
[1];
3132 * wpas_dbus_getter_scan_interval - Get scan interval
3133 * @iter: Pointer to incoming dbus message iter
3134 * @error: Location to store error on failure
3135 * @user_data: Function specific data
3136 * Returns: TRUE on success, FALSE on failure
3138 * Getter function for "ScanInterval" property.
3140 dbus_bool_t
wpas_dbus_getter_scan_interval(
3141 const struct wpa_dbus_property_desc
*property_desc
,
3142 DBusMessageIter
*iter
, DBusError
*error
, void *user_data
)
3144 struct wpa_supplicant
*wpa_s
= user_data
;
3145 dbus_int32_t scan_interval
= wpa_s
->scan_interval
;
3147 return wpas_dbus_simple_property_getter(iter
, DBUS_TYPE_INT32
,
3148 &scan_interval
, error
);
3153 * wpas_dbus_setter_scan_interval - Control scan interval
3154 * @iter: Pointer to incoming dbus message iter
3155 * @error: Location to store error on failure
3156 * @user_data: Function specific data
3157 * Returns: TRUE on success, FALSE on failure
3159 * Setter function for "ScanInterval" property.
3161 dbus_bool_t
wpas_dbus_setter_scan_interval(
3162 const struct wpa_dbus_property_desc
*property_desc
,
3163 DBusMessageIter
*iter
, DBusError
*error
, void *user_data
)
3165 struct wpa_supplicant
*wpa_s
= user_data
;
3166 dbus_int32_t scan_interval
;
3168 if (!wpas_dbus_simple_property_setter(iter
, error
, DBUS_TYPE_INT32
,
3172 if (wpa_supplicant_set_scan_interval(wpa_s
, scan_interval
)) {
3173 dbus_set_error_const(error
, DBUS_ERROR_FAILED
,
3174 "scan_interval must be >= 0");
3182 * wpas_dbus_getter_ifname - Get interface name
3183 * @iter: Pointer to incoming dbus message iter
3184 * @error: Location to store error on failure
3185 * @user_data: Function specific data
3186 * Returns: TRUE on success, FALSE on failure
3188 * Getter for "Ifname" property.
3190 dbus_bool_t
wpas_dbus_getter_ifname(
3191 const struct wpa_dbus_property_desc
*property_desc
,
3192 DBusMessageIter
*iter
, DBusError
*error
, void *user_data
)
3194 struct wpa_supplicant
*wpa_s
= user_data
;
3196 return wpas_dbus_string_property_getter(iter
, wpa_s
->ifname
, error
);
3201 * wpas_dbus_getter_driver - Get interface name
3202 * @iter: Pointer to incoming dbus message iter
3203 * @error: Location to store error on failure
3204 * @user_data: Function specific data
3205 * Returns: TRUE on success, FALSE on failure
3207 * Getter for "Driver" property.
3209 dbus_bool_t
wpas_dbus_getter_driver(
3210 const struct wpa_dbus_property_desc
*property_desc
,
3211 DBusMessageIter
*iter
, DBusError
*error
, void *user_data
)
3213 struct wpa_supplicant
*wpa_s
= user_data
;
3215 if (wpa_s
->driver
== NULL
|| wpa_s
->driver
->name
== NULL
) {
3216 wpa_printf(MSG_DEBUG
, "%s[dbus]: wpa_s has no driver set",
3218 dbus_set_error(error
, DBUS_ERROR_FAILED
, "%s: no driver set",
3223 return wpas_dbus_string_property_getter(iter
, wpa_s
->driver
->name
,
3229 * wpas_dbus_getter_current_bss - Get current bss object path
3230 * @iter: Pointer to incoming dbus message iter
3231 * @error: Location to store error on failure
3232 * @user_data: Function specific data
3233 * Returns: TRUE on success, FALSE on failure
3235 * Getter for "CurrentBSS" property.
3237 dbus_bool_t
wpas_dbus_getter_current_bss(
3238 const struct wpa_dbus_property_desc
*property_desc
,
3239 DBusMessageIter
*iter
, DBusError
*error
, void *user_data
)
3241 struct wpa_supplicant
*wpa_s
= user_data
;
3242 char path_buf
[WPAS_DBUS_OBJECT_PATH_MAX
], *bss_obj_path
= path_buf
;
3244 if (wpa_s
->current_bss
&& wpa_s
->dbus_new_path
)
3245 os_snprintf(bss_obj_path
, WPAS_DBUS_OBJECT_PATH_MAX
,
3246 "%s/" WPAS_DBUS_NEW_BSSIDS_PART
"/%u",
3247 wpa_s
->dbus_new_path
, wpa_s
->current_bss
->id
);
3249 os_snprintf(bss_obj_path
, WPAS_DBUS_OBJECT_PATH_MAX
, "/");
3251 return wpas_dbus_simple_property_getter(iter
, DBUS_TYPE_OBJECT_PATH
,
3252 &bss_obj_path
, error
);
3257 * wpas_dbus_getter_current_network - Get current network object path
3258 * @iter: Pointer to incoming dbus message iter
3259 * @error: Location to store error on failure
3260 * @user_data: Function specific data
3261 * Returns: TRUE on success, FALSE on failure
3263 * Getter for "CurrentNetwork" property.
3265 dbus_bool_t
wpas_dbus_getter_current_network(
3266 const struct wpa_dbus_property_desc
*property_desc
,
3267 DBusMessageIter
*iter
, DBusError
*error
, void *user_data
)
3269 struct wpa_supplicant
*wpa_s
= user_data
;
3270 char path_buf
[WPAS_DBUS_OBJECT_PATH_MAX
], *net_obj_path
= path_buf
;
3272 if (wpa_s
->current_ssid
&& wpa_s
->dbus_new_path
)
3273 os_snprintf(net_obj_path
, WPAS_DBUS_OBJECT_PATH_MAX
,
3274 "%s/" WPAS_DBUS_NEW_NETWORKS_PART
"/%u",
3275 wpa_s
->dbus_new_path
, wpa_s
->current_ssid
->id
);
3277 os_snprintf(net_obj_path
, WPAS_DBUS_OBJECT_PATH_MAX
, "/");
3279 return wpas_dbus_simple_property_getter(iter
, DBUS_TYPE_OBJECT_PATH
,
3280 &net_obj_path
, error
);
3285 * wpas_dbus_getter_current_auth_mode - Get current authentication type
3286 * @iter: Pointer to incoming dbus message iter
3287 * @error: Location to store error on failure
3288 * @user_data: Function specific data
3289 * Returns: TRUE on success, FALSE on failure
3291 * Getter for "CurrentAuthMode" property.
3293 dbus_bool_t
wpas_dbus_getter_current_auth_mode(
3294 const struct wpa_dbus_property_desc
*property_desc
,
3295 DBusMessageIter
*iter
, DBusError
*error
, void *user_data
)
3297 struct wpa_supplicant
*wpa_s
= user_data
;
3298 const char *eap_mode
;
3299 const char *auth_mode
;
3300 char eap_mode_buf
[WPAS_DBUS_AUTH_MODE_MAX
];
3302 if (wpa_s
->wpa_state
!= WPA_COMPLETED
) {
3303 auth_mode
= "INACTIVE";
3304 } else if (wpa_s
->key_mgmt
== WPA_KEY_MGMT_IEEE8021X
||
3305 wpa_s
->key_mgmt
== WPA_KEY_MGMT_IEEE8021X_NO_WPA
) {
3306 eap_mode
= wpa_supplicant_get_eap_mode(wpa_s
);
3307 os_snprintf(eap_mode_buf
, WPAS_DBUS_AUTH_MODE_MAX
,
3308 "EAP-%s", eap_mode
);
3309 auth_mode
= eap_mode_buf
;
3311 } else if (wpa_s
->current_ssid
) {
3312 auth_mode
= wpa_key_mgmt_txt(wpa_s
->key_mgmt
,
3313 wpa_s
->current_ssid
->proto
);
3315 auth_mode
= "UNKNOWN";
3318 return wpas_dbus_simple_property_getter(iter
, DBUS_TYPE_STRING
,
3324 * wpas_dbus_getter_bridge_ifname - Get interface name
3325 * @iter: Pointer to incoming dbus message iter
3326 * @error: Location to store error on failure
3327 * @user_data: Function specific data
3328 * Returns: TRUE on success, FALSE on failure
3330 * Getter for "BridgeIfname" property.
3332 dbus_bool_t
wpas_dbus_getter_bridge_ifname(
3333 const struct wpa_dbus_property_desc
*property_desc
,
3334 DBusMessageIter
*iter
, DBusError
*error
, void *user_data
)
3336 struct wpa_supplicant
*wpa_s
= user_data
;
3338 return wpas_dbus_string_property_getter(iter
, wpa_s
->bridge_ifname
,
3344 * wpas_dbus_getter_config_file - Get interface configuration file path
3345 * @iter: Pointer to incoming dbus message iter
3346 * @error: Location to store error on failure
3347 * @user_data: Function specific data
3348 * Returns: TRUE on success, FALSE on failure
3350 * Getter for "ConfigFile" property.
3352 dbus_bool_t
wpas_dbus_getter_config_file(
3353 const struct wpa_dbus_property_desc
*property_desc
,
3354 DBusMessageIter
*iter
, DBusError
*error
, void *user_data
)
3356 struct wpa_supplicant
*wpa_s
= user_data
;
3358 return wpas_dbus_string_property_getter(iter
, wpa_s
->confname
, error
);
3363 * wpas_dbus_getter_bsss - Get array of BSSs objects
3364 * @iter: Pointer to incoming dbus message iter
3365 * @error: Location to store error on failure
3366 * @user_data: Function specific data
3367 * Returns: TRUE on success, FALSE on failure
3369 * Getter for "BSSs" property.
3371 dbus_bool_t
wpas_dbus_getter_bsss(
3372 const struct wpa_dbus_property_desc
*property_desc
,
3373 DBusMessageIter
*iter
, DBusError
*error
, void *user_data
)
3375 struct wpa_supplicant
*wpa_s
= user_data
;
3376 struct wpa_bss
*bss
;
3379 dbus_bool_t success
= FALSE
;
3381 if (!wpa_s
->dbus_new_path
) {
3382 dbus_set_error(error
, DBUS_ERROR_FAILED
,
3383 "%s: no D-Bus interface", __func__
);
3387 paths
= os_calloc(wpa_s
->num_bss
, sizeof(char *));
3389 dbus_set_error_const(error
, DBUS_ERROR_NO_MEMORY
, "no memory");
3393 /* Loop through scan results and append each result's object path */
3394 dl_list_for_each(bss
, &wpa_s
->bss_id
, struct wpa_bss
, list_id
) {
3395 paths
[i
] = os_zalloc(WPAS_DBUS_OBJECT_PATH_MAX
);
3396 if (paths
[i
] == NULL
) {
3397 dbus_set_error_const(error
, DBUS_ERROR_NO_MEMORY
,
3401 /* Construct the object path for this BSS. */
3402 os_snprintf(paths
[i
++], WPAS_DBUS_OBJECT_PATH_MAX
,
3403 "%s/" WPAS_DBUS_NEW_BSSIDS_PART
"/%u",
3404 wpa_s
->dbus_new_path
, bss
->id
);
3407 success
= wpas_dbus_simple_array_property_getter(iter
,
3408 DBUS_TYPE_OBJECT_PATH
,
3409 paths
, wpa_s
->num_bss
,
3414 os_free(paths
[--i
]);
3421 * wpas_dbus_getter_networks - Get array of networks objects
3422 * @iter: Pointer to incoming dbus message iter
3423 * @error: Location to store error on failure
3424 * @user_data: Function specific data
3425 * Returns: TRUE on success, FALSE on failure
3427 * Getter for "Networks" property.
3429 dbus_bool_t
wpas_dbus_getter_networks(
3430 const struct wpa_dbus_property_desc
*property_desc
,
3431 DBusMessageIter
*iter
, DBusError
*error
, void *user_data
)
3433 struct wpa_supplicant
*wpa_s
= user_data
;
3434 struct wpa_ssid
*ssid
;
3436 unsigned int i
= 0, num
= 0;
3437 dbus_bool_t success
= FALSE
;
3439 if (!wpa_s
->dbus_new_path
) {
3440 dbus_set_error(error
, DBUS_ERROR_FAILED
,
3441 "%s: no D-Bus interface", __func__
);
3445 for (ssid
= wpa_s
->conf
->ssid
; ssid
; ssid
= ssid
->next
)
3446 if (!network_is_persistent_group(ssid
))
3449 paths
= os_calloc(num
, sizeof(char *));
3451 dbus_set_error(error
, DBUS_ERROR_NO_MEMORY
, "no memory");
3455 /* Loop through configured networks and append object path of each */
3456 for (ssid
= wpa_s
->conf
->ssid
; ssid
; ssid
= ssid
->next
) {
3457 if (network_is_persistent_group(ssid
))
3459 paths
[i
] = os_zalloc(WPAS_DBUS_OBJECT_PATH_MAX
);
3460 if (paths
[i
] == NULL
) {
3461 dbus_set_error(error
, DBUS_ERROR_NO_MEMORY
,
3466 /* Construct the object path for this network. */
3467 os_snprintf(paths
[i
++], WPAS_DBUS_OBJECT_PATH_MAX
,
3468 "%s/" WPAS_DBUS_NEW_NETWORKS_PART
"/%d",
3469 wpa_s
->dbus_new_path
, ssid
->id
);
3472 success
= wpas_dbus_simple_array_property_getter(iter
,
3473 DBUS_TYPE_OBJECT_PATH
,
3478 os_free(paths
[--i
]);
3485 * wpas_dbus_getter_pkcs11_engine_path - Get PKCS #11 engine path
3486 * @iter: Pointer to incoming dbus message iter
3487 * @error: Location to store error on failure
3488 * @user_data: Function specific data
3489 * Returns: A dbus message containing the PKCS #11 engine path
3491 * Getter for "PKCS11EnginePath" property.
3493 dbus_bool_t
wpas_dbus_getter_pkcs11_engine_path(
3494 const struct wpa_dbus_property_desc
*property_desc
,
3495 DBusMessageIter
*iter
, DBusError
*error
, void *user_data
)
3497 struct wpa_supplicant
*wpa_s
= user_data
;
3499 return wpas_dbus_string_property_getter(iter
,
3500 wpa_s
->conf
->pkcs11_engine_path
,
3506 * wpas_dbus_getter_pkcs11_module_path - Get PKCS #11 module path
3507 * @iter: Pointer to incoming dbus message iter
3508 * @error: Location to store error on failure
3509 * @user_data: Function specific data
3510 * Returns: A dbus message containing the PKCS #11 module path
3512 * Getter for "PKCS11ModulePath" property.
3514 dbus_bool_t
wpas_dbus_getter_pkcs11_module_path(
3515 const struct wpa_dbus_property_desc
*property_desc
,
3516 DBusMessageIter
*iter
, DBusError
*error
, void *user_data
)
3518 struct wpa_supplicant
*wpa_s
= user_data
;
3520 return wpas_dbus_string_property_getter(iter
,
3521 wpa_s
->conf
->pkcs11_module_path
,
3527 * wpas_dbus_getter_blobs - Get all blobs defined for this interface
3528 * @iter: Pointer to incoming dbus message iter
3529 * @error: Location to store error on failure
3530 * @user_data: Function specific data
3531 * Returns: TRUE on success, FALSE on failure
3533 * Getter for "Blobs" property.
3535 dbus_bool_t
wpas_dbus_getter_blobs(
3536 const struct wpa_dbus_property_desc
*property_desc
,
3537 DBusMessageIter
*iter
, DBusError
*error
, void *user_data
)
3539 struct wpa_supplicant
*wpa_s
= user_data
;
3540 DBusMessageIter variant_iter
, dict_iter
, entry_iter
, array_iter
;
3541 struct wpa_config_blob
*blob
;
3543 if (!dbus_message_iter_open_container(iter
, DBUS_TYPE_VARIANT
,
3544 "a{say}", &variant_iter
) ||
3545 !dbus_message_iter_open_container(&variant_iter
, DBUS_TYPE_ARRAY
,
3546 "{say}", &dict_iter
)) {
3547 dbus_set_error_const(error
, DBUS_ERROR_NO_MEMORY
, "no memory");
3551 blob
= wpa_s
->conf
->blobs
;
3553 if (!dbus_message_iter_open_container(&dict_iter
,
3554 DBUS_TYPE_DICT_ENTRY
,
3555 NULL
, &entry_iter
) ||
3556 !dbus_message_iter_append_basic(&entry_iter
,
3559 !dbus_message_iter_open_container(&entry_iter
,
3561 DBUS_TYPE_BYTE_AS_STRING
,
3563 !dbus_message_iter_append_fixed_array(&array_iter
,
3567 !dbus_message_iter_close_container(&entry_iter
,
3569 !dbus_message_iter_close_container(&dict_iter
,
3571 dbus_set_error_const(error
, DBUS_ERROR_NO_MEMORY
,
3579 if (!dbus_message_iter_close_container(&variant_iter
, &dict_iter
) ||
3580 !dbus_message_iter_close_container(iter
, &variant_iter
)) {
3581 dbus_set_error_const(error
, DBUS_ERROR_NO_MEMORY
, "no memory");
3589 dbus_bool_t
wpas_dbus_getter_iface_global(
3590 const struct wpa_dbus_property_desc
*property_desc
,
3591 DBusMessageIter
*iter
, DBusError
*error
, void *user_data
)
3593 struct wpa_supplicant
*wpa_s
= user_data
;
3598 if (!property_desc
->data
) {
3599 dbus_set_error(error
, DBUS_ERROR_INVALID_ARGS
,
3600 "Unhandled interface property %s",
3601 property_desc
->dbus_property
);
3605 ret
= wpa_config_get_value(property_desc
->data
, wpa_s
->conf
, buf
,
3610 return wpas_dbus_simple_property_getter(iter
, DBUS_TYPE_STRING
, &p
,
3615 dbus_bool_t
wpas_dbus_setter_iface_global(
3616 const struct wpa_dbus_property_desc
*property_desc
,
3617 DBusMessageIter
*iter
, DBusError
*error
, void *user_data
)
3619 struct wpa_supplicant
*wpa_s
= user_data
;
3620 const char *new_value
= NULL
;
3622 size_t combined_len
;
3625 if (!wpas_dbus_simple_property_setter(iter
, error
, DBUS_TYPE_STRING
,
3629 combined_len
= os_strlen(property_desc
->data
) + os_strlen(new_value
) +
3631 if (combined_len
>= sizeof(buf
)) {
3632 dbus_set_error(error
, DBUS_ERROR_INVALID_ARGS
,
3633 "Interface property %s value too large",
3634 property_desc
->dbus_property
);
3641 ret
= os_snprintf(buf
, combined_len
, "%s=%s", property_desc
->data
,
3643 if (os_snprintf_error(combined_len
, ret
)) {
3644 dbus_set_error(error
, WPAS_DBUS_ERROR_UNKNOWN_ERROR
,
3645 "Failed to construct new interface property %s",
3646 property_desc
->dbus_property
);
3650 if (wpa_config_process_global(wpa_s
->conf
, buf
, -1)) {
3651 dbus_set_error(error
, DBUS_ERROR_INVALID_ARGS
,
3652 "Failed to set interface property %s",
3653 property_desc
->dbus_property
);
3657 wpa_supplicant_update_config(wpa_s
);
3662 static struct wpa_bss
* get_bss_helper(struct bss_handler_args
*args
,
3663 DBusError
*error
, const char *func_name
)
3665 struct wpa_bss
*res
= wpa_bss_get_id(args
->wpa_s
, args
->id
);
3668 wpa_printf(MSG_ERROR
, "%s[dbus]: no bss with id %d found",
3669 func_name
, args
->id
);
3670 dbus_set_error(error
, DBUS_ERROR_FAILED
,
3671 "%s: BSS %d not found",
3672 func_name
, args
->id
);
3680 * wpas_dbus_getter_bss_bssid - Return the BSSID of a BSS
3681 * @iter: Pointer to incoming dbus message iter
3682 * @error: Location to store error on failure
3683 * @user_data: Function specific data
3684 * Returns: TRUE on success, FALSE on failure
3686 * Getter for "BSSID" property.
3688 dbus_bool_t
wpas_dbus_getter_bss_bssid(
3689 const struct wpa_dbus_property_desc
*property_desc
,
3690 DBusMessageIter
*iter
, DBusError
*error
, void *user_data
)
3692 struct bss_handler_args
*args
= user_data
;
3693 struct wpa_bss
*res
;
3695 res
= get_bss_helper(args
, error
, __func__
);
3699 return wpas_dbus_simple_array_property_getter(iter
, DBUS_TYPE_BYTE
,
3700 res
->bssid
, ETH_ALEN
,
3706 * wpas_dbus_getter_bss_ssid - Return the SSID of a BSS
3707 * @iter: Pointer to incoming dbus message iter
3708 * @error: Location to store error on failure
3709 * @user_data: Function specific data
3710 * Returns: TRUE on success, FALSE on failure
3712 * Getter for "SSID" property.
3714 dbus_bool_t
wpas_dbus_getter_bss_ssid(
3715 const struct wpa_dbus_property_desc
*property_desc
,
3716 DBusMessageIter
*iter
, DBusError
*error
, void *user_data
)
3718 struct bss_handler_args
*args
= user_data
;
3719 struct wpa_bss
*res
;
3721 res
= get_bss_helper(args
, error
, __func__
);
3725 return wpas_dbus_simple_array_property_getter(iter
, DBUS_TYPE_BYTE
,
3726 res
->ssid
, res
->ssid_len
,
3732 * wpas_dbus_getter_bss_privacy - Return the privacy flag of a BSS
3733 * @iter: Pointer to incoming dbus message iter
3734 * @error: Location to store error on failure
3735 * @user_data: Function specific data
3736 * Returns: TRUE on success, FALSE on failure
3738 * Getter for "Privacy" property.
3740 dbus_bool_t
wpas_dbus_getter_bss_privacy(
3741 const struct wpa_dbus_property_desc
*property_desc
,
3742 DBusMessageIter
*iter
, DBusError
*error
, void *user_data
)
3744 struct bss_handler_args
*args
= user_data
;
3745 struct wpa_bss
*res
;
3746 dbus_bool_t privacy
;
3748 res
= get_bss_helper(args
, error
, __func__
);
3752 privacy
= (res
->caps
& IEEE80211_CAP_PRIVACY
) ? TRUE
: FALSE
;
3753 return wpas_dbus_simple_property_getter(iter
, DBUS_TYPE_BOOLEAN
,
3759 * wpas_dbus_getter_bss_mode - Return the mode of a BSS
3760 * @iter: Pointer to incoming dbus message iter
3761 * @error: Location to store error on failure
3762 * @user_data: Function specific data
3763 * Returns: TRUE on success, FALSE on failure
3765 * Getter for "Mode" property.
3767 dbus_bool_t
wpas_dbus_getter_bss_mode(
3768 const struct wpa_dbus_property_desc
*property_desc
,
3769 DBusMessageIter
*iter
, DBusError
*error
, void *user_data
)
3771 struct bss_handler_args
*args
= user_data
;
3772 struct wpa_bss
*res
;
3776 res
= get_bss_helper(args
, error
, __func__
);
3779 if (bss_is_dmg(res
)) {
3780 switch (res
->caps
& IEEE80211_CAP_DMG_MASK
) {
3781 case IEEE80211_CAP_DMG_PBSS
:
3782 case IEEE80211_CAP_DMG_IBSS
:
3785 case IEEE80211_CAP_DMG_AP
:
3786 mode
= "infrastructure";
3793 mesh
= wpa_bss_get_ie(res
, WLAN_EID_MESH_ID
);
3796 else if (res
->caps
& IEEE80211_CAP_IBSS
)
3799 mode
= "infrastructure";
3802 return wpas_dbus_simple_property_getter(iter
, DBUS_TYPE_STRING
,
3808 * wpas_dbus_getter_bss_level - Return the signal strength 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 "Level" property.
3816 dbus_bool_t
wpas_dbus_getter_bss_signal(
3817 const struct wpa_dbus_property_desc
*property_desc
,
3818 DBusMessageIter
*iter
, DBusError
*error
, void *user_data
)
3820 struct bss_handler_args
*args
= user_data
;
3821 struct wpa_bss
*res
;
3824 res
= get_bss_helper(args
, error
, __func__
);
3828 level
= (s16
) res
->level
;
3829 return wpas_dbus_simple_property_getter(iter
, DBUS_TYPE_INT16
,
3835 * wpas_dbus_getter_bss_frequency - Return the frequency of a BSS
3836 * @iter: Pointer to incoming dbus message iter
3837 * @error: Location to store error on failure
3838 * @user_data: Function specific data
3839 * Returns: TRUE on success, FALSE on failure
3841 * Getter for "Frequency" property.
3843 dbus_bool_t
wpas_dbus_getter_bss_frequency(
3844 const struct wpa_dbus_property_desc
*property_desc
,
3845 DBusMessageIter
*iter
, DBusError
*error
, void *user_data
)
3847 struct bss_handler_args
*args
= user_data
;
3848 struct wpa_bss
*res
;
3851 res
= get_bss_helper(args
, error
, __func__
);
3855 freq
= (u16
) res
->freq
;
3856 return wpas_dbus_simple_property_getter(iter
, DBUS_TYPE_UINT16
,
3861 static int cmp_u8s_desc(const void *a
, const void *b
)
3863 return (*(u8
*) b
- *(u8
*) a
);
3868 * wpas_dbus_getter_bss_rates - Return available bit rates of a BSS
3869 * @iter: Pointer to incoming dbus message iter
3870 * @error: Location to store error on failure
3871 * @user_data: Function specific data
3872 * Returns: TRUE on success, FALSE on failure
3874 * Getter for "Rates" property.
3876 dbus_bool_t
wpas_dbus_getter_bss_rates(
3877 const struct wpa_dbus_property_desc
*property_desc
,
3878 DBusMessageIter
*iter
, DBusError
*error
, void *user_data
)
3880 struct bss_handler_args
*args
= user_data
;
3881 struct wpa_bss
*res
;
3882 u8
*ie_rates
= NULL
;
3885 dbus_bool_t success
= FALSE
;
3887 res
= get_bss_helper(args
, error
, __func__
);
3891 rates_num
= wpa_bss_get_bit_rates(res
, &ie_rates
);
3895 qsort(ie_rates
, rates_num
, 1, cmp_u8s_desc
);
3897 real_rates
= os_malloc(sizeof(u32
) * rates_num
);
3900 dbus_set_error_const(error
, DBUS_ERROR_NO_MEMORY
, "no memory");
3904 for (i
= 0; i
< rates_num
; i
++)
3905 real_rates
[i
] = ie_rates
[i
] * 500000;
3907 success
= wpas_dbus_simple_array_property_getter(iter
, DBUS_TYPE_UINT32
,
3908 real_rates
, rates_num
,
3912 os_free(real_rates
);
3917 static dbus_bool_t
wpas_dbus_get_bss_security_prop(
3918 const struct wpa_dbus_property_desc
*property_desc
,
3919 DBusMessageIter
*iter
, struct wpa_ie_data
*ie_data
, DBusError
*error
)
3921 DBusMessageIter iter_dict
, variant_iter
;
3923 const char *pairwise
[5]; /* max 5 pairwise ciphers is supported */
3924 const char *key_mgmt
[9]; /* max 9 key managements may be supported */
3927 if (!dbus_message_iter_open_container(iter
, DBUS_TYPE_VARIANT
,
3928 "a{sv}", &variant_iter
))
3931 if (!wpa_dbus_dict_open_write(&variant_iter
, &iter_dict
))
3936 if (ie_data
->key_mgmt
& WPA_KEY_MGMT_PSK
)
3937 key_mgmt
[n
++] = "wpa-psk";
3938 if (ie_data
->key_mgmt
& WPA_KEY_MGMT_FT_PSK
)
3939 key_mgmt
[n
++] = "wpa-ft-psk";
3940 if (ie_data
->key_mgmt
& WPA_KEY_MGMT_PSK_SHA256
)
3941 key_mgmt
[n
++] = "wpa-psk-sha256";
3942 if (ie_data
->key_mgmt
& WPA_KEY_MGMT_IEEE8021X
)
3943 key_mgmt
[n
++] = "wpa-eap";
3944 if (ie_data
->key_mgmt
& WPA_KEY_MGMT_FT_IEEE8021X
)
3945 key_mgmt
[n
++] = "wpa-ft-eap";
3946 if (ie_data
->key_mgmt
& WPA_KEY_MGMT_IEEE8021X_SHA256
)
3947 key_mgmt
[n
++] = "wpa-eap-sha256";
3948 #ifdef CONFIG_SUITEB
3949 if (ie_data
->key_mgmt
& WPA_KEY_MGMT_IEEE8021X_SUITE_B
)
3950 key_mgmt
[n
++] = "wpa-eap-suite-b";
3951 #endif /* CONFIG_SUITEB */
3952 #ifdef CONFIG_SUITEB192
3953 if (ie_data
->key_mgmt
& WPA_KEY_MGMT_IEEE8021X_SUITE_B_192
)
3954 key_mgmt
[n
++] = "wpa-eap-suite-b-192";
3955 #endif /* CONFIG_SUITEB192 */
3956 if (ie_data
->key_mgmt
& WPA_KEY_MGMT_NONE
)
3957 key_mgmt
[n
++] = "wpa-none";
3959 if (!wpa_dbus_dict_append_string_array(&iter_dict
, "KeyMgmt",
3964 switch (ie_data
->group_cipher
) {
3965 case WPA_CIPHER_WEP40
:
3968 case WPA_CIPHER_TKIP
:
3971 case WPA_CIPHER_CCMP
:
3974 case WPA_CIPHER_GCMP
:
3977 case WPA_CIPHER_WEP104
:
3980 case WPA_CIPHER_CCMP_256
:
3983 case WPA_CIPHER_GCMP_256
:
3991 if (!wpa_dbus_dict_append_string(&iter_dict
, "Group", group
))
3996 if (ie_data
->pairwise_cipher
& WPA_CIPHER_TKIP
)
3997 pairwise
[n
++] = "tkip";
3998 if (ie_data
->pairwise_cipher
& WPA_CIPHER_CCMP
)
3999 pairwise
[n
++] = "ccmp";
4000 if (ie_data
->pairwise_cipher
& WPA_CIPHER_GCMP
)
4001 pairwise
[n
++] = "gcmp";
4002 if (ie_data
->pairwise_cipher
& WPA_CIPHER_CCMP_256
)
4003 pairwise
[n
++] = "ccmp-256";
4004 if (ie_data
->pairwise_cipher
& WPA_CIPHER_GCMP_256
)
4005 pairwise
[n
++] = "gcmp-256";
4007 if (!wpa_dbus_dict_append_string_array(&iter_dict
, "Pairwise",
4011 /* Management group (RSN only) */
4012 if (ie_data
->proto
== WPA_PROTO_RSN
) {
4013 switch (ie_data
->mgmt_group_cipher
) {
4014 #ifdef CONFIG_IEEE80211W
4015 case WPA_CIPHER_AES_128_CMAC
:
4016 group
= "aes128cmac";
4018 #endif /* CONFIG_IEEE80211W */
4024 if (!wpa_dbus_dict_append_string(&iter_dict
, "MgmtGroup",
4029 if (!wpa_dbus_dict_close_write(&variant_iter
, &iter_dict
) ||
4030 !dbus_message_iter_close_container(iter
, &variant_iter
))
4036 dbus_set_error_const(error
, DBUS_ERROR_NO_MEMORY
, "no memory");
4042 * wpas_dbus_getter_bss_wpa - Return the WPA options of a BSS
4043 * @iter: Pointer to incoming dbus message iter
4044 * @error: Location to store error on failure
4045 * @user_data: Function specific data
4046 * Returns: TRUE on success, FALSE on failure
4048 * Getter for "WPA" property.
4050 dbus_bool_t
wpas_dbus_getter_bss_wpa(
4051 const struct wpa_dbus_property_desc
*property_desc
,
4052 DBusMessageIter
*iter
, DBusError
*error
, void *user_data
)
4054 struct bss_handler_args
*args
= user_data
;
4055 struct wpa_bss
*res
;
4056 struct wpa_ie_data wpa_data
;
4059 res
= get_bss_helper(args
, error
, __func__
);
4063 os_memset(&wpa_data
, 0, sizeof(wpa_data
));
4064 ie
= wpa_bss_get_vendor_ie(res
, WPA_IE_VENDOR_TYPE
);
4065 if (ie
&& wpa_parse_wpa_ie(ie
, 2 + ie
[1], &wpa_data
) < 0) {
4066 dbus_set_error_const(error
, DBUS_ERROR_FAILED
,
4067 "failed to parse WPA IE");
4071 return wpas_dbus_get_bss_security_prop(property_desc
, iter
, &wpa_data
, error
);
4076 * wpas_dbus_getter_bss_rsn - Return the RSN options of a BSS
4077 * @iter: Pointer to incoming dbus message iter
4078 * @error: Location to store error on failure
4079 * @user_data: Function specific data
4080 * Returns: TRUE on success, FALSE on failure
4082 * Getter for "RSN" property.
4084 dbus_bool_t
wpas_dbus_getter_bss_rsn(
4085 const struct wpa_dbus_property_desc
*property_desc
,
4086 DBusMessageIter
*iter
, DBusError
*error
, void *user_data
)
4088 struct bss_handler_args
*args
= user_data
;
4089 struct wpa_bss
*res
;
4090 struct wpa_ie_data wpa_data
;
4093 res
= get_bss_helper(args
, error
, __func__
);
4097 os_memset(&wpa_data
, 0, sizeof(wpa_data
));
4098 ie
= wpa_bss_get_ie(res
, WLAN_EID_RSN
);
4099 if (ie
&& wpa_parse_wpa_ie(ie
, 2 + ie
[1], &wpa_data
) < 0) {
4100 dbus_set_error_const(error
, DBUS_ERROR_FAILED
,
4101 "failed to parse RSN IE");
4105 return wpas_dbus_get_bss_security_prop(property_desc
, iter
, &wpa_data
, error
);
4110 * wpas_dbus_getter_bss_wps - Return the WPS options of a BSS
4111 * @iter: Pointer to incoming dbus message iter
4112 * @error: Location to store error on failure
4113 * @user_data: Function specific data
4114 * Returns: TRUE on success, FALSE on failure
4116 * Getter for "WPS" property.
4118 dbus_bool_t
wpas_dbus_getter_bss_wps(
4119 const struct wpa_dbus_property_desc
*property_desc
,
4120 DBusMessageIter
*iter
, DBusError
*error
, void *user_data
)
4122 struct bss_handler_args
*args
= user_data
;
4123 struct wpa_bss
*res
;
4125 struct wpabuf
*wps_ie
;
4126 #endif /* CONFIG_WPS */
4127 DBusMessageIter iter_dict
, variant_iter
;
4128 int wps_support
= 0;
4129 const char *type
= "";
4131 res
= get_bss_helper(args
, error
, __func__
);
4135 if (!dbus_message_iter_open_container(iter
, DBUS_TYPE_VARIANT
,
4136 "a{sv}", &variant_iter
) ||
4137 !wpa_dbus_dict_open_write(&variant_iter
, &iter_dict
))
4141 wps_ie
= wpa_bss_get_vendor_ie_multi(res
, WPS_IE_VENDOR_TYPE
);
4144 if (wps_is_selected_pbc_registrar(wps_ie
))
4146 else if (wps_is_selected_pin_registrar(wps_ie
))
4149 wpabuf_free(wps_ie
);
4151 #endif /* CONFIG_WPS */
4153 if ((wps_support
&& !wpa_dbus_dict_append_string(&iter_dict
, "Type", type
)) ||
4154 !wpa_dbus_dict_close_write(&variant_iter
, &iter_dict
) ||
4155 !dbus_message_iter_close_container(iter
, &variant_iter
))
4161 dbus_set_error_const(error
, DBUS_ERROR_NO_MEMORY
, "no memory");
4167 * wpas_dbus_getter_bss_ies - Return all IEs of a BSS
4168 * @iter: Pointer to incoming dbus message iter
4169 * @error: Location to store error on failure
4170 * @user_data: Function specific data
4171 * Returns: TRUE on success, FALSE on failure
4173 * Getter for "IEs" property.
4175 dbus_bool_t
wpas_dbus_getter_bss_ies(
4176 const struct wpa_dbus_property_desc
*property_desc
,
4177 DBusMessageIter
*iter
, DBusError
*error
, void *user_data
)
4179 struct bss_handler_args
*args
= user_data
;
4180 struct wpa_bss
*res
;
4182 res
= get_bss_helper(args
, error
, __func__
);
4186 return wpas_dbus_simple_array_property_getter(iter
, DBUS_TYPE_BYTE
,
4187 res
+ 1, res
->ie_len
,
4193 * wpas_dbus_getter_bss_age - Return time in seconds since BSS was last seen
4194 * @iter: Pointer to incoming dbus message iter
4195 * @error: Location to store error on failure
4196 * @user_data: Function specific data
4197 * Returns: TRUE on success, FALSE on failure
4199 * Getter for BSS age
4201 dbus_bool_t
wpas_dbus_getter_bss_age(
4202 const struct wpa_dbus_property_desc
*property_desc
,
4203 DBusMessageIter
*iter
, DBusError
*error
, void *user_data
)
4205 struct bss_handler_args
*args
= user_data
;
4206 struct wpa_bss
*res
;
4207 struct os_reltime now
, diff
= { 0, 0 };
4210 res
= get_bss_helper(args
, error
, __func__
);
4214 os_get_reltime(&now
);
4215 os_reltime_sub(&now
, &res
->last_update
, &diff
);
4216 age
= diff
.sec
> 0 ? diff
.sec
: 0;
4217 return wpas_dbus_simple_property_getter(iter
, DBUS_TYPE_UINT32
, &age
,
4223 * wpas_dbus_getter_enabled - Check whether network is enabled or disabled
4224 * @iter: Pointer to incoming dbus message iter
4225 * @error: Location to store error on failure
4226 * @user_data: Function specific data
4227 * Returns: TRUE on success, FALSE on failure
4229 * Getter for "enabled" property of a configured network.
4231 dbus_bool_t
wpas_dbus_getter_enabled(
4232 const struct wpa_dbus_property_desc
*property_desc
,
4233 DBusMessageIter
*iter
, DBusError
*error
, void *user_data
)
4235 struct network_handler_args
*net
= user_data
;
4236 dbus_bool_t enabled
= net
->ssid
->disabled
? FALSE
: TRUE
;
4238 return wpas_dbus_simple_property_getter(iter
, DBUS_TYPE_BOOLEAN
,
4244 * wpas_dbus_setter_enabled - Mark a configured network as enabled or disabled
4245 * @iter: Pointer to incoming dbus message iter
4246 * @error: Location to store error on failure
4247 * @user_data: Function specific data
4248 * Returns: TRUE on success, FALSE on failure
4250 * Setter for "Enabled" property of a configured network.
4252 dbus_bool_t
wpas_dbus_setter_enabled(
4253 const struct wpa_dbus_property_desc
*property_desc
,
4254 DBusMessageIter
*iter
, DBusError
*error
, void *user_data
)
4256 struct network_handler_args
*net
= user_data
;
4257 struct wpa_supplicant
*wpa_s
;
4258 struct wpa_ssid
*ssid
;
4261 if (!wpas_dbus_simple_property_setter(iter
, error
, DBUS_TYPE_BOOLEAN
,
4269 wpa_supplicant_enable_network(wpa_s
, ssid
);
4271 wpa_supplicant_disable_network(wpa_s
, ssid
);
4278 * wpas_dbus_getter_network_properties - Get options for a configured network
4279 * @iter: Pointer to incoming dbus message iter
4280 * @error: Location to store error on failure
4281 * @user_data: Function specific data
4282 * Returns: TRUE on success, FALSE on failure
4284 * Getter for "Properties" property of a configured network.
4286 dbus_bool_t
wpas_dbus_getter_network_properties(
4287 const struct wpa_dbus_property_desc
*property_desc
,
4288 DBusMessageIter
*iter
, DBusError
*error
, void *user_data
)
4290 struct network_handler_args
*net
= user_data
;
4291 DBusMessageIter variant_iter
, dict_iter
;
4293 char **props
= wpa_config_get_all(net
->ssid
, 1);
4294 dbus_bool_t success
= FALSE
;
4297 dbus_set_error_const(error
, DBUS_ERROR_NO_MEMORY
, "no memory");
4301 if (!dbus_message_iter_open_container(iter
, DBUS_TYPE_VARIANT
, "a{sv}",
4303 !wpa_dbus_dict_open_write(&variant_iter
, &dict_iter
)) {
4304 dbus_set_error_const(error
, DBUS_ERROR_NO_MEMORY
, "no memory");
4310 if (!wpa_dbus_dict_append_string(&dict_iter
, *iterator
,
4312 dbus_set_error_const(error
, DBUS_ERROR_NO_MEMORY
,
4320 if (!wpa_dbus_dict_close_write(&variant_iter
, &dict_iter
) ||
4321 !dbus_message_iter_close_container(iter
, &variant_iter
)) {
4322 dbus_set_error_const(error
, DBUS_ERROR_NO_MEMORY
, "no memory");
4340 * wpas_dbus_setter_network_properties - Set options for a configured network
4341 * @iter: Pointer to incoming dbus message iter
4342 * @error: Location to store error on failure
4343 * @user_data: Function specific data
4344 * Returns: TRUE on success, FALSE on failure
4346 * Setter for "Properties" property of a configured network.
4348 dbus_bool_t
wpas_dbus_setter_network_properties(
4349 const struct wpa_dbus_property_desc
*property_desc
,
4350 DBusMessageIter
*iter
, DBusError
*error
, void *user_data
)
4352 struct network_handler_args
*net
= user_data
;
4353 struct wpa_ssid
*ssid
= net
->ssid
;
4354 DBusMessageIter variant_iter
;
4356 dbus_message_iter_recurse(iter
, &variant_iter
);
4357 return set_network_properties(net
->wpa_s
, ssid
, &variant_iter
, error
);
4363 DBusMessage
* wpas_dbus_handler_subscribe_preq(
4364 DBusMessage
*message
, struct wpa_supplicant
*wpa_s
)
4366 struct wpas_dbus_priv
*priv
= wpa_s
->global
->dbus
;
4369 if (wpa_s
->preq_notify_peer
!= NULL
) {
4370 if (os_strcmp(dbus_message_get_sender(message
),
4371 wpa_s
->preq_notify_peer
) == 0)
4374 return dbus_message_new_error(message
,
4375 WPAS_DBUS_ERROR_SUBSCRIPTION_IN_USE
,
4376 "Another application is already subscribed");
4379 name
= os_strdup(dbus_message_get_sender(message
));
4381 return wpas_dbus_error_no_memory(message
);
4383 wpa_s
->preq_notify_peer
= name
;
4385 /* Subscribe to clean up if application closes socket */
4386 wpas_dbus_subscribe_noc(priv
);
4389 * Double-check it's still alive to make sure that we didn't
4390 * miss the NameOwnerChanged signal, e.g. while strdup'ing.
4392 if (!dbus_bus_name_has_owner(priv
->con
, name
, NULL
)) {
4394 * Application no longer exists, clean up.
4395 * The return value is irrelevant now.
4397 * Need to check if the NameOwnerChanged handling
4398 * already cleaned up because we have processed
4399 * DBus messages while checking if the name still
4402 if (!wpa_s
->preq_notify_peer
)
4404 os_free(wpa_s
->preq_notify_peer
);
4405 wpa_s
->preq_notify_peer
= NULL
;
4406 wpas_dbus_unsubscribe_noc(priv
);
4413 DBusMessage
* wpas_dbus_handler_unsubscribe_preq(
4414 DBusMessage
*message
, struct wpa_supplicant
*wpa_s
)
4416 struct wpas_dbus_priv
*priv
= wpa_s
->global
->dbus
;
4418 if (!wpa_s
->preq_notify_peer
)
4419 return dbus_message_new_error(message
,
4420 WPAS_DBUS_ERROR_NO_SUBSCRIPTION
,
4423 if (os_strcmp(wpa_s
->preq_notify_peer
,
4424 dbus_message_get_sender(message
)))
4425 return dbus_message_new_error(message
,
4426 WPAS_DBUS_ERROR_SUBSCRIPTION_EPERM
,
4427 "Can't unsubscribe others");
4429 os_free(wpa_s
->preq_notify_peer
);
4430 wpa_s
->preq_notify_peer
= NULL
;
4431 wpas_dbus_unsubscribe_noc(priv
);
4436 void wpas_dbus_signal_preq(struct wpa_supplicant
*wpa_s
,
4437 const u8
*addr
, const u8
*dst
, const u8
*bssid
,
4438 const u8
*ie
, size_t ie_len
, u32 ssi_signal
)
4441 DBusMessageIter iter
, dict_iter
;
4442 struct wpas_dbus_priv
*priv
= wpa_s
->global
->dbus
;
4444 /* Do nothing if the control interface is not turned on */
4445 if (priv
== NULL
|| !wpa_s
->dbus_new_path
)
4448 if (wpa_s
->preq_notify_peer
== NULL
)
4451 msg
= dbus_message_new_signal(wpa_s
->dbus_new_path
,
4452 WPAS_DBUS_NEW_IFACE_INTERFACE
,
4457 dbus_message_set_destination(msg
, wpa_s
->preq_notify_peer
);
4459 dbus_message_iter_init_append(msg
, &iter
);
4461 if (!wpa_dbus_dict_open_write(&iter
, &dict_iter
) ||
4462 (addr
&& !wpa_dbus_dict_append_byte_array(&dict_iter
, "addr",
4463 (const char *) addr
,
4465 (dst
&& !wpa_dbus_dict_append_byte_array(&dict_iter
, "dst",
4468 (bssid
&& !wpa_dbus_dict_append_byte_array(&dict_iter
, "bssid",
4469 (const char *) bssid
,
4471 (ie
&& ie_len
&& !wpa_dbus_dict_append_byte_array(&dict_iter
, "ies",
4474 (ssi_signal
&& !wpa_dbus_dict_append_int32(&dict_iter
, "signal",
4476 !wpa_dbus_dict_close_write(&iter
, &dict_iter
))
4479 dbus_connection_send(priv
->con
, msg
, NULL
);
4482 wpa_printf(MSG_ERROR
, "dbus: Failed to construct signal");
4484 dbus_message_unref(msg
);
4487 #endif /* CONFIG_AP */
4490 DBusMessage
* wpas_dbus_handler_vendor_elem_add(DBusMessage
*message
,
4491 struct wpa_supplicant
*wpa_s
)
4495 struct ieee802_11_elems elems
;
4496 dbus_int32_t frame_id
;
4497 DBusMessageIter iter
, array
;
4499 dbus_message_iter_init(message
, &iter
);
4500 dbus_message_iter_get_basic(&iter
, &frame_id
);
4501 if (frame_id
< 0 || frame_id
>= NUM_VENDOR_ELEM_FRAMES
) {
4502 return dbus_message_new_error(message
, DBUS_ERROR_INVALID_ARGS
,
4506 dbus_message_iter_next(&iter
);
4507 dbus_message_iter_recurse(&iter
, &array
);
4508 dbus_message_iter_get_fixed_array(&array
, &ielems
, &len
);
4509 if (!ielems
|| len
== 0) {
4510 return dbus_message_new_error(
4511 message
, DBUS_ERROR_INVALID_ARGS
, "Invalid value");
4514 if (ieee802_11_parse_elems(ielems
, len
, &elems
, 0) == ParseFailed
) {
4515 return dbus_message_new_error(message
, DBUS_ERROR_INVALID_ARGS
,
4519 wpa_s
= wpas_vendor_elem(wpa_s
, frame_id
);
4520 if (!wpa_s
->vendor_elem
[frame_id
]) {
4521 wpa_s
->vendor_elem
[frame_id
] = wpabuf_alloc_copy(ielems
, len
);
4522 wpas_vendor_elem_update(wpa_s
);
4526 if (wpabuf_resize(&wpa_s
->vendor_elem
[frame_id
], len
) < 0) {
4527 return dbus_message_new_error(message
, DBUS_ERROR_INVALID_ARGS
,
4531 wpabuf_put_data(wpa_s
->vendor_elem
[frame_id
], ielems
, len
);
4532 wpas_vendor_elem_update(wpa_s
);
4537 DBusMessage
* wpas_dbus_handler_vendor_elem_get(DBusMessage
*message
,
4538 struct wpa_supplicant
*wpa_s
)
4541 DBusMessageIter iter
, array_iter
;
4542 dbus_int32_t frame_id
;
4546 dbus_message_iter_init(message
, &iter
);
4547 dbus_message_iter_get_basic(&iter
, &frame_id
);
4549 if (frame_id
< 0 || frame_id
>= NUM_VENDOR_ELEM_FRAMES
) {
4550 return dbus_message_new_error(message
, DBUS_ERROR_INVALID_ARGS
,
4554 wpa_s
= wpas_vendor_elem(wpa_s
, frame_id
);
4555 if (!wpa_s
->vendor_elem
[frame_id
]) {
4556 return dbus_message_new_error(message
, DBUS_ERROR_INVALID_ARGS
,
4557 "ID value does not exist");
4560 reply
= dbus_message_new_method_return(message
);
4562 return wpas_dbus_error_no_memory(message
);
4564 dbus_message_iter_init_append(reply
, &iter
);
4566 elem
= wpabuf_head_u8(wpa_s
->vendor_elem
[frame_id
]);
4567 elem_len
= wpabuf_len(wpa_s
->vendor_elem
[frame_id
]);
4569 if (!dbus_message_iter_open_container(&iter
, DBUS_TYPE_ARRAY
,
4570 DBUS_TYPE_BYTE_AS_STRING
,
4572 !dbus_message_iter_append_fixed_array(&array_iter
, DBUS_TYPE_BYTE
,
4574 !dbus_message_iter_close_container(&iter
, &array_iter
)) {
4575 dbus_message_unref(reply
);
4576 reply
= wpas_dbus_error_no_memory(message
);
4583 DBusMessage
* wpas_dbus_handler_vendor_elem_remove(DBusMessage
*message
,
4584 struct wpa_supplicant
*wpa_s
)
4588 struct ieee802_11_elems elems
;
4589 DBusMessageIter iter
, array
;
4590 dbus_int32_t frame_id
;
4592 dbus_message_iter_init(message
, &iter
);
4593 dbus_message_iter_get_basic(&iter
, &frame_id
);
4594 if (frame_id
< 0 || frame_id
>= NUM_VENDOR_ELEM_FRAMES
) {
4595 return dbus_message_new_error(message
, DBUS_ERROR_INVALID_ARGS
,
4599 dbus_message_iter_next(&iter
);
4600 dbus_message_iter_recurse(&iter
, &array
);
4601 dbus_message_iter_get_fixed_array(&array
, &ielems
, &len
);
4602 if (!ielems
|| len
== 0) {
4603 return dbus_message_new_error(message
, DBUS_ERROR_INVALID_ARGS
,
4607 wpa_s
= wpas_vendor_elem(wpa_s
, frame_id
);
4609 if (len
== 1 && *ielems
== '*') {
4610 wpabuf_free(wpa_s
->vendor_elem
[frame_id
]);
4611 wpa_s
->vendor_elem
[frame_id
] = NULL
;
4612 wpas_vendor_elem_update(wpa_s
);
4616 if (!wpa_s
->vendor_elem
[frame_id
]) {
4617 return dbus_message_new_error(message
, DBUS_ERROR_INVALID_ARGS
,
4618 "ID value does not exist");
4621 if (ieee802_11_parse_elems(ielems
, len
, &elems
, 0) == ParseFailed
) {
4622 return dbus_message_new_error(message
, DBUS_ERROR_INVALID_ARGS
,
4626 if (wpas_vendor_elem_remove(wpa_s
, frame_id
, ielems
, len
) == 0)
4629 return dbus_message_new_error(message
, DBUS_ERROR_INVALID_ARGS
,