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, Jouni Malinen <j@w1.fi>
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License version 2 as
9 * published by the Free Software Foundation.
11 * Alternatively, this software may be distributed under the terms of BSD
14 * See README and COPYING for more details.
20 #include "common/ieee802_11_defs.h"
21 #include "eap_peer/eap_methods.h"
22 #include "eapol_supp/eapol_supp_sm.h"
23 #include "rsn_supp/wpa.h"
24 #include "../config.h"
25 #include "../wpa_supplicant_i.h"
26 #include "../driver_i.h"
27 #include "../notify.h"
28 #include "../wpas_glue.h"
31 #include "dbus_new_helpers.h"
33 #include "dbus_new_handlers.h"
34 #include "dbus_dict_helpers.h"
36 extern int wpa_debug_level
;
37 extern int wpa_debug_show_keys
;
38 extern int wpa_debug_timestamp
;
40 static const char *debug_strings
[] = {
41 "msgdump", "debug", "info", "warning", "error", NULL
46 * wpas_dbus_new_decompose_object_path - Decompose an interface object path into parts
47 * @path: The dbus object path
48 * @network: (out) the configured network this object path refers to, if any
49 * @bssid: (out) the scanned bssid this object path refers to, if any
50 * Returns: The object path of the network interface this path refers to
52 * For a given object path, decomposes the object path into object id, network,
53 * and BSSID parts, if those parts exist.
55 static char * wpas_dbus_new_decompose_object_path(const char *path
,
59 const unsigned int dev_path_prefix_len
=
60 strlen(WPAS_DBUS_NEW_PATH_INTERFACES
"/");
64 /* Be a bit paranoid about path */
65 if (!path
|| os_strncmp(path
, WPAS_DBUS_NEW_PATH_INTERFACES
"/",
69 /* Ensure there's something at the end of the path */
70 if ((path
+ dev_path_prefix_len
)[0] == '\0')
73 obj_path_only
= os_strdup(path
);
74 if (obj_path_only
== NULL
)
77 next_sep
= os_strchr(obj_path_only
+ dev_path_prefix_len
, '/');
78 if (next_sep
!= NULL
) {
79 const char *net_part
= os_strstr(
80 next_sep
, WPAS_DBUS_NEW_NETWORKS_PART
"/");
81 const char *bssid_part
= os_strstr(
82 next_sep
, WPAS_DBUS_NEW_BSSIDS_PART
"/");
84 if (network
&& net_part
) {
85 /* Deal with a request for a configured network */
86 const char *net_name
= net_part
+
87 os_strlen(WPAS_DBUS_NEW_NETWORKS_PART
"/");
89 if (os_strlen(net_name
))
90 *network
= os_strdup(net_name
);
91 } else if (bssid
&& bssid_part
) {
92 /* Deal with a request for a scanned BSSID */
93 const char *bssid_name
= bssid_part
+
94 os_strlen(WPAS_DBUS_NEW_BSSIDS_PART
"/");
95 if (strlen(bssid_name
))
96 *bssid
= os_strdup(bssid_name
);
101 /* Cut off interface object path before "/" */
105 return obj_path_only
;
110 * wpas_dbus_error_unknown_error - Return a new InvalidArgs error message
111 * @message: Pointer to incoming dbus message this error refers to
112 * @arg: Optional string appended to error message
113 * Returns: a dbus error message
115 * Convenience function to create and return an UnknownError
117 DBusMessage
* wpas_dbus_error_unknown_error(DBusMessage
*message
,
120 return dbus_message_new_error(message
, WPAS_DBUS_ERROR_UNKNOWN_ERROR
,
126 * wpas_dbus_error_iface_unknown - Return a new invalid interface error message
127 * @message: Pointer to incoming dbus message this error refers to
128 * Returns: A dbus error message
130 * Convenience function to create and return an invalid interface error
132 static DBusMessage
* wpas_dbus_error_iface_unknown(DBusMessage
*message
)
134 return dbus_message_new_error(message
, WPAS_DBUS_ERROR_IFACE_UNKNOWN
,
135 "wpa_supplicant knows nothing about "
141 * wpas_dbus_error_network_unknown - Return a new NetworkUnknown error message
142 * @message: Pointer to incoming dbus message this error refers to
143 * Returns: a dbus error message
145 * Convenience function to create and return an invalid network error
147 static DBusMessage
* wpas_dbus_error_network_unknown(DBusMessage
*message
)
149 return dbus_message_new_error(message
, WPAS_DBUS_ERROR_NETWORK_UNKNOWN
,
150 "There is no such a network in this "
156 * wpas_dbus_error_invalid_args - Return a new InvalidArgs error message
157 * @message: Pointer to incoming dbus message this error refers to
158 * Returns: a dbus error message
160 * Convenience function to create and return an invalid options error
162 DBusMessage
* wpas_dbus_error_invalid_args(DBusMessage
*message
,
167 reply
= dbus_message_new_error(message
, WPAS_DBUS_ERROR_INVALID_ARGS
,
168 "Did not receive correct message "
171 dbus_message_append_args(reply
, DBUS_TYPE_STRING
, &arg
,
178 static const char *dont_quote
[] = {
179 "key_mgmt", "proto", "pairwise", "auth_alg", "group", "eap",
180 "opensc_engine_path", "pkcs11_engine_path", "pkcs11_module_path",
184 static dbus_bool_t
should_quote_opt(const char *key
)
187 while (dont_quote
[i
] != NULL
) {
188 if (os_strcmp(key
, dont_quote
[i
]) == 0)
196 * get_iface_by_dbus_path - Get a new network interface
197 * @global: Pointer to global data from wpa_supplicant_init()
198 * @path: Pointer to a dbus object path representing an interface
199 * Returns: Pointer to the interface or %NULL if not found
201 static struct wpa_supplicant
* get_iface_by_dbus_path(
202 struct wpa_global
*global
, const char *path
)
204 struct wpa_supplicant
*wpa_s
;
206 for (wpa_s
= global
->ifaces
; wpa_s
; wpa_s
= wpa_s
->next
) {
207 if (os_strcmp(wpa_s
->dbus_new_path
, path
) == 0)
215 * set_network_properties - Set properties of a configured network
216 * @message: Pointer to incoming dbus message
217 * @wpa_s: wpa_supplicant structure for a network interface
218 * @ssid: wpa_ssid structure for a configured network
219 * @iter: DBus message iterator containing dictionary of network
221 * Returns: NULL when succeed or DBus error on failure
223 * Sets network configuration with parameters given id DBus dictionary
225 static DBusMessage
* set_network_properties(DBusMessage
*message
,
226 struct wpa_supplicant
*wpa_s
,
227 struct wpa_ssid
*ssid
,
228 DBusMessageIter
*iter
)
231 struct wpa_dbus_dict_entry entry
= { .type
= DBUS_TYPE_STRING
};
232 DBusMessage
*reply
= NULL
;
233 DBusMessageIter iter_dict
;
235 if (!wpa_dbus_dict_open_read(iter
, &iter_dict
))
236 return wpas_dbus_error_invalid_args(message
, NULL
);
238 while (wpa_dbus_dict_has_dict_entry(&iter_dict
)) {
242 if (!wpa_dbus_dict_get_entry(&iter_dict
, &entry
)) {
243 reply
= wpas_dbus_error_invalid_args(message
, NULL
);
246 if (entry
.type
== DBUS_TYPE_ARRAY
&&
247 entry
.array_type
== DBUS_TYPE_BYTE
) {
248 if (entry
.array_len
<= 0)
251 size
= entry
.array_len
* 2 + 1;
252 value
= os_zalloc(size
);
256 ret
= wpa_snprintf_hex(value
, size
,
257 (u8
*) entry
.bytearray_value
,
261 } else if (entry
.type
== DBUS_TYPE_STRING
) {
262 if (should_quote_opt(entry
.key
)) {
263 size
= os_strlen(entry
.str_value
);
268 value
= os_zalloc(size
);
272 ret
= os_snprintf(value
, size
, "\"%s\"",
274 if (ret
< 0 || (size_t) ret
!= (size
- 1))
277 value
= os_strdup(entry
.str_value
);
281 } else if (entry
.type
== DBUS_TYPE_UINT32
) {
282 value
= os_zalloc(size
);
286 ret
= os_snprintf(value
, size
, "%u",
290 } else if (entry
.type
== DBUS_TYPE_INT32
) {
291 value
= os_zalloc(size
);
295 ret
= os_snprintf(value
, size
, "%d",
302 if (wpa_config_set(ssid
, entry
.key
, value
, 0) < 0)
305 if ((os_strcmp(entry
.key
, "psk") == 0 &&
306 value
[0] == '"' && ssid
->ssid_len
) ||
307 (strcmp(entry
.key
, "ssid") == 0 && ssid
->passphrase
))
308 wpa_config_update_psk(ssid
);
309 else if (os_strcmp(entry
.key
, "priority") == 0)
310 wpa_config_update_prio_list(wpa_s
->conf
);
313 wpa_dbus_dict_entry_clear(&entry
);
318 reply
= wpas_dbus_error_invalid_args(message
, entry
.key
);
319 wpa_dbus_dict_entry_clear(&entry
);
328 * wpas_dbus_simple_property_getter - Get basic type property
329 * @message: Pointer to incoming dbus message
330 * @type: DBus type of property (must be basic type)
331 * @val: pointer to place holding property value
332 * Returns: The DBus message containing response for Properties.Get call
333 * or DBus error message if error occurred.
335 * Generic getter for basic type properties. Type is required to be basic.
337 DBusMessage
* wpas_dbus_simple_property_getter(DBusMessage
*message
,
338 const int type
, const void *val
)
340 DBusMessage
*reply
= NULL
;
341 DBusMessageIter iter
, variant_iter
;
343 if (!dbus_type_is_basic(type
)) {
344 wpa_printf(MSG_ERROR
, "dbus: wpas_dbus_simple_property_getter:"
345 " given type is not basic");
346 return wpas_dbus_error_unknown_error(message
, NULL
);
350 reply
= dbus_message_new(DBUS_MESSAGE_TYPE_SIGNAL
);
352 reply
= dbus_message_new_method_return(message
);
355 dbus_message_iter_init_append(reply
, &iter
);
356 if (!dbus_message_iter_open_container(
357 &iter
, DBUS_TYPE_VARIANT
,
358 wpa_dbus_type_as_string(type
), &variant_iter
) ||
359 !dbus_message_iter_append_basic(&variant_iter
, type
,
361 !dbus_message_iter_close_container(&iter
, &variant_iter
)) {
362 wpa_printf(MSG_ERROR
, "dbus: "
363 "wpas_dbus_simple_property_getter: out of "
364 "memory to put property value into "
366 dbus_message_unref(reply
);
367 reply
= dbus_message_new_error(message
,
368 DBUS_ERROR_NO_MEMORY
,
372 wpa_printf(MSG_ERROR
, "dbus: wpas_dbus_simple_property_getter:"
373 " out of memory to return property value");
374 reply
= dbus_message_new_error(message
, DBUS_ERROR_NO_MEMORY
,
383 * wpas_dbus_simple_property_setter - Set basic type property
384 * @message: Pointer to incoming dbus message
385 * @type: DBus type of property (must be basic type)
386 * @val: pointer to place where value being set will be stored
387 * Returns: NULL or DBus error message if error occurred.
389 * Generic setter for basic type properties. Type is required to be basic.
391 DBusMessage
* wpas_dbus_simple_property_setter(DBusMessage
*message
,
392 const int type
, void *val
)
394 DBusMessageIter iter
, variant_iter
;
396 if (!dbus_type_is_basic(type
)) {
397 wpa_printf(MSG_ERROR
, "dbus: wpas_dbus_simple_property_setter:"
398 " given type is not basic");
399 return wpas_dbus_error_unknown_error(message
, NULL
);
402 if (!dbus_message_iter_init(message
, &iter
)) {
403 wpa_printf(MSG_ERROR
, "dbus: wpas_dbus_simple_property_setter:"
404 " out of memory to return scanning state");
405 return dbus_message_new_error(message
, DBUS_ERROR_NO_MEMORY
,
409 /* omit first and second argument and get value from third */
410 dbus_message_iter_next(&iter
);
411 dbus_message_iter_next(&iter
);
412 dbus_message_iter_recurse(&iter
, &variant_iter
);
414 if (dbus_message_iter_get_arg_type(&variant_iter
) != type
) {
415 wpa_printf(MSG_DEBUG
, "dbus: wpas_dbus_simple_property_setter:"
416 " wrong property type");
417 return wpas_dbus_error_invalid_args(message
,
418 "wrong property type");
420 dbus_message_iter_get_basic(&variant_iter
, val
);
427 * wpas_dbus_simple_array_property_getter - Get array type property
428 * @message: Pointer to incoming dbus message
429 * @type: DBus type of property array elements (must be basic type)
430 * @array: pointer to array of elements to put into response message
431 * @array_len: length of above array
432 * Returns: The DBus message containing response for Properties.Get call
433 * or DBus error message if error occurred.
435 * Generic getter for array type properties. Array elements type is
436 * required to be basic.
438 DBusMessage
* wpas_dbus_simple_array_property_getter(DBusMessage
*message
,
443 DBusMessage
*reply
= NULL
;
444 DBusMessageIter iter
, variant_iter
, array_iter
;
445 char type_str
[] = "a?"; /* ? will be replaced with subtype letter; */
446 const char *sub_type_str
;
447 size_t element_size
, i
;
449 if (!dbus_type_is_basic(type
)) {
450 wpa_printf(MSG_ERROR
, "dbus: "
451 "wpas_dbus_simple_array_property_getter: given "
452 "type is not basic");
453 return wpas_dbus_error_unknown_error(message
, NULL
);
456 sub_type_str
= wpa_dbus_type_as_string(type
);
457 type_str
[1] = sub_type_str
[0];
460 reply
= dbus_message_new(DBUS_MESSAGE_TYPE_SIGNAL
);
462 reply
= dbus_message_new_method_return(message
);
464 wpa_printf(MSG_ERROR
, "dbus: "
465 "wpas_dbus_simple_array_property_getter: out of "
466 "memory to create return message");
467 return dbus_message_new_error(message
, DBUS_ERROR_NO_MEMORY
,
471 dbus_message_iter_init_append(reply
, &iter
);
473 if (!dbus_message_iter_open_container(&iter
, DBUS_TYPE_VARIANT
,
474 type_str
, &variant_iter
) ||
475 !dbus_message_iter_open_container(&variant_iter
, DBUS_TYPE_ARRAY
,
476 sub_type_str
, &array_iter
)) {
477 wpa_printf(MSG_ERROR
, "dbus: "
478 "wpas_dbus_simple_array_property_getter: out of "
479 "memory to open container");
480 dbus_message_unref(reply
);
481 return dbus_message_new_error(message
, DBUS_ERROR_NO_MEMORY
,
487 case DBUS_TYPE_BOOLEAN
:
490 case DBUS_TYPE_INT16
:
491 case DBUS_TYPE_UINT16
:
492 element_size
= sizeof(uint16_t);
494 case DBUS_TYPE_INT32
:
495 case DBUS_TYPE_UINT32
:
496 element_size
= sizeof(uint32_t);
498 case DBUS_TYPE_INT64
:
499 case DBUS_TYPE_UINT64
:
500 element_size
= sizeof(uint64_t);
502 case DBUS_TYPE_DOUBLE
:
503 element_size
= sizeof(double);
505 case DBUS_TYPE_STRING
:
506 case DBUS_TYPE_OBJECT_PATH
:
507 element_size
= sizeof(char *);
510 wpa_printf(MSG_ERROR
, "dbus: "
511 "wpas_dbus_simple_array_property_getter: "
512 "fatal: unknown element type");
517 for (i
= 0; i
< array_len
; i
++) {
518 dbus_message_iter_append_basic(&array_iter
, type
,
519 array
+ i
* element_size
);
522 if (!dbus_message_iter_close_container(&variant_iter
, &array_iter
) ||
523 !dbus_message_iter_close_container(&iter
, &variant_iter
)) {
524 wpa_printf(MSG_ERROR
, "dbus: "
525 "wpas_dbus_simple_array_property_getter: out of "
526 "memory to close container");
527 dbus_message_unref(reply
);
528 return dbus_message_new_error(message
, DBUS_ERROR_NO_MEMORY
,
537 * wpas_dbus_handler_create_interface - Request registration of a network iface
538 * @message: Pointer to incoming dbus message
539 * @global: %wpa_supplicant global data structure
540 * Returns: The object path of the new interface object,
541 * or a dbus error message with more information
543 * Handler function for "CreateInterface" method call. Handles requests
544 * by dbus clients to register a network interface that wpa_supplicant
547 DBusMessage
* wpas_dbus_handler_create_interface(DBusMessage
*message
,
548 struct wpa_global
*global
)
550 DBusMessageIter iter_dict
;
551 DBusMessage
*reply
= NULL
;
552 DBusMessageIter iter
;
553 struct wpa_dbus_dict_entry entry
;
556 char *bridge_ifname
= NULL
;
558 dbus_message_iter_init(message
, &iter
);
560 if (!wpa_dbus_dict_open_read(&iter
, &iter_dict
))
562 while (wpa_dbus_dict_has_dict_entry(&iter_dict
)) {
563 if (!wpa_dbus_dict_get_entry(&iter_dict
, &entry
))
565 if (!strcmp(entry
.key
, "Driver") &&
566 (entry
.type
== DBUS_TYPE_STRING
)) {
567 driver
= os_strdup(entry
.str_value
);
568 wpa_dbus_dict_entry_clear(&entry
);
571 } else if (!strcmp(entry
.key
, "Ifname") &&
572 (entry
.type
== DBUS_TYPE_STRING
)) {
573 ifname
= os_strdup(entry
.str_value
);
574 wpa_dbus_dict_entry_clear(&entry
);
577 } else if (!strcmp(entry
.key
, "BridgeIfname") &&
578 (entry
.type
== DBUS_TYPE_STRING
)) {
579 bridge_ifname
= os_strdup(entry
.str_value
);
580 wpa_dbus_dict_entry_clear(&entry
);
581 if (bridge_ifname
== NULL
)
584 wpa_dbus_dict_entry_clear(&entry
);
590 goto error
; /* Required Ifname argument missing */
593 * Try to get the wpa_supplicant record for this iface, return
594 * an error if we already control it.
596 if (wpa_supplicant_get_iface(global
, ifname
) != NULL
) {
597 reply
= dbus_message_new_error(message
,
598 WPAS_DBUS_ERROR_IFACE_EXISTS
,
599 "wpa_supplicant already "
600 "controls this interface.");
602 struct wpa_supplicant
*wpa_s
;
603 struct wpa_interface iface
;
604 os_memset(&iface
, 0, sizeof(iface
));
605 iface
.driver
= driver
;
606 iface
.ifname
= ifname
;
607 iface
.bridge_ifname
= bridge_ifname
;
608 /* Otherwise, have wpa_supplicant attach to it. */
609 if ((wpa_s
= wpa_supplicant_add_iface(global
, &iface
))) {
610 const char *path
= wpa_s
->dbus_new_path
;
611 reply
= dbus_message_new_method_return(message
);
612 dbus_message_append_args(reply
, DBUS_TYPE_OBJECT_PATH
,
613 &path
, DBUS_TYPE_INVALID
);
615 reply
= wpas_dbus_error_unknown_error(
616 message
, "wpa_supplicant couldn't grab this "
624 os_free(bridge_ifname
);
628 reply
= wpas_dbus_error_invalid_args(message
, NULL
);
634 * wpas_dbus_handler_remove_interface - Request deregistration of an interface
635 * @message: Pointer to incoming dbus message
636 * @global: wpa_supplicant global data structure
637 * Returns: a dbus message containing a UINT32 indicating success (1) or
638 * failure (0), or returns a dbus error message with more information
640 * Handler function for "removeInterface" method call. Handles requests
641 * by dbus clients to deregister a network interface that wpa_supplicant
644 DBusMessage
* wpas_dbus_handler_remove_interface(DBusMessage
*message
,
645 struct wpa_global
*global
)
647 struct wpa_supplicant
*wpa_s
;
649 DBusMessage
*reply
= NULL
;
651 dbus_message_get_args(message
, NULL
, DBUS_TYPE_OBJECT_PATH
, &path
,
654 wpa_s
= get_iface_by_dbus_path(global
, path
);
656 reply
= wpas_dbus_error_iface_unknown(message
);
657 else if (wpa_supplicant_remove_iface(global
, wpa_s
)) {
658 reply
= wpas_dbus_error_unknown_error(
659 message
, "wpa_supplicant couldn't remove this "
668 * wpas_dbus_handler_get_interface - Get the object path for an interface name
669 * @message: Pointer to incoming dbus message
670 * @global: %wpa_supplicant global data structure
671 * Returns: The object path of the interface object,
672 * or a dbus error message with more information
674 * Handler function for "getInterface" method call.
676 DBusMessage
* wpas_dbus_handler_get_interface(DBusMessage
*message
,
677 struct wpa_global
*global
)
679 DBusMessage
*reply
= NULL
;
682 struct wpa_supplicant
*wpa_s
;
684 dbus_message_get_args(message
, NULL
, DBUS_TYPE_STRING
, &ifname
,
687 wpa_s
= wpa_supplicant_get_iface(global
, ifname
);
689 return wpas_dbus_error_iface_unknown(message
);
691 path
= wpa_s
->dbus_new_path
;
692 reply
= dbus_message_new_method_return(message
);
694 return dbus_message_new_error(message
, DBUS_ERROR_NO_MEMORY
,
696 if (!dbus_message_append_args(reply
, DBUS_TYPE_OBJECT_PATH
, &path
,
697 DBUS_TYPE_INVALID
)) {
698 dbus_message_unref(reply
);
699 return dbus_message_new_error(message
, DBUS_ERROR_NO_MEMORY
,
708 * wpas_dbus_getter_debug_level - Get debug level
709 * @message: Pointer to incoming dbus message
710 * @global: %wpa_supplicant global data structure
711 * Returns: DBus message with value of debug level
713 * Getter for "DebugLevel" property.
715 DBusMessage
* wpas_dbus_getter_debug_level(DBusMessage
*message
,
716 struct wpa_global
*global
)
719 int idx
= wpa_debug_level
;
724 str
= debug_strings
[idx
];
725 return wpas_dbus_simple_property_getter(message
, DBUS_TYPE_STRING
,
731 * wpas_dbus_getter_debug_timestamp - Get debug timestamp
732 * @message: Pointer to incoming dbus message
733 * @global: %wpa_supplicant global data structure
734 * Returns: DBus message with value of debug timestamp
736 * Getter for "DebugTimestamp" property.
738 DBusMessage
* wpas_dbus_getter_debug_timestamp(DBusMessage
*message
,
739 struct wpa_global
*global
)
741 return wpas_dbus_simple_property_getter(message
, DBUS_TYPE_BOOLEAN
,
742 &wpa_debug_timestamp
);
748 * wpas_dbus_getter_debug_show_keys - Get debug show keys
749 * @message: Pointer to incoming dbus message
750 * @global: %wpa_supplicant global data structure
751 * Returns: DBus message with value of debug show_keys
753 * Getter for "DebugShowKeys" property.
755 DBusMessage
* wpas_dbus_getter_debug_show_keys(DBusMessage
*message
,
756 struct wpa_global
*global
)
758 return wpas_dbus_simple_property_getter(message
, DBUS_TYPE_BOOLEAN
,
759 &wpa_debug_show_keys
);
764 * wpas_dbus_setter_debug_level - Set debug level
765 * @message: Pointer to incoming dbus message
766 * @global: %wpa_supplicant global data structure
767 * Returns: %NULL or DBus error message
769 * Setter for "DebugLevel" property.
771 DBusMessage
* wpas_dbus_setter_debug_level(DBusMessage
*message
,
772 struct wpa_global
*global
)
775 const char *str
= NULL
;
778 reply
= wpas_dbus_simple_property_setter(message
, DBUS_TYPE_STRING
,
783 for (i
= 0; debug_strings
[i
]; i
++)
784 if (os_strcmp(debug_strings
[i
], str
) == 0) {
790 wpa_supplicant_set_debug_params(global
, val
, wpa_debug_timestamp
,
791 wpa_debug_show_keys
)) {
792 dbus_message_unref(reply
);
793 return wpas_dbus_error_invalid_args(
794 message
, "Wrong debug level value");
802 * wpas_dbus_setter_debug_timestamp - Set debug timestamp
803 * @message: Pointer to incoming dbus message
804 * @global: %wpa_supplicant global data structure
805 * Returns: %NULL or DBus error message
807 * Setter for "DebugTimestamp" property.
809 DBusMessage
* wpas_dbus_setter_debug_timestamp(DBusMessage
*message
,
810 struct wpa_global
*global
)
815 reply
= wpas_dbus_simple_property_setter(message
, DBUS_TYPE_BOOLEAN
,
820 wpa_supplicant_set_debug_params(global
, wpa_debug_level
, val
? 1 : 0,
821 wpa_debug_show_keys
);
828 * wpas_dbus_setter_debug_show_keys - Set debug show keys
829 * @message: Pointer to incoming dbus message
830 * @global: %wpa_supplicant global data structure
831 * Returns: %NULL or DBus error message
833 * Setter for "DebugShowKeys" property.
835 DBusMessage
* wpas_dbus_setter_debug_show_keys(DBusMessage
*message
,
836 struct wpa_global
*global
)
841 reply
= wpas_dbus_simple_property_setter(message
, DBUS_TYPE_BOOLEAN
,
846 wpa_supplicant_set_debug_params(global
, wpa_debug_level
,
855 * wpas_dbus_getter_interfaces - Request registered interfaces list
856 * @message: Pointer to incoming dbus message
857 * @global: %wpa_supplicant global data structure
858 * Returns: The object paths array containing registered interfaces
859 * objects paths or DBus error on failure
861 * Getter for "Interfaces" property. Handles requests
862 * by dbus clients to return list of registered interfaces objects
865 DBusMessage
* wpas_dbus_getter_interfaces(DBusMessage
*message
,
866 struct wpa_global
*global
)
868 DBusMessage
*reply
= NULL
;
869 struct wpa_supplicant
*wpa_s
;
871 unsigned int i
= 0, num
= 0;
873 for (wpa_s
= global
->ifaces
; wpa_s
; wpa_s
= wpa_s
->next
)
876 paths
= os_zalloc(num
* sizeof(char*));
878 return dbus_message_new_error(message
, DBUS_ERROR_NO_MEMORY
,
882 for (wpa_s
= global
->ifaces
; wpa_s
; wpa_s
= wpa_s
->next
)
883 paths
[i
] = wpa_s
->dbus_new_path
;
885 reply
= wpas_dbus_simple_array_property_getter(message
,
886 DBUS_TYPE_OBJECT_PATH
,
895 * wpas_dbus_getter_eap_methods - Request supported EAP methods list
896 * @message: Pointer to incoming dbus message
897 * @nothing: not used argument. may be NULL or anything else
898 * Returns: The object paths array containing supported EAP methods
899 * represented by strings or DBus error on failure
901 * Getter for "EapMethods" property. Handles requests
902 * by dbus clients to return list of strings with supported EAP methods
904 DBusMessage
* wpas_dbus_getter_eap_methods(DBusMessage
*message
, void *nothing
)
906 DBusMessage
*reply
= NULL
;
908 size_t num_items
= 0;
910 eap_methods
= eap_get_names_as_string_array(&num_items
);
912 return dbus_message_new_error(message
, DBUS_ERROR_NO_MEMORY
,
916 reply
= wpas_dbus_simple_array_property_getter(message
,
918 eap_methods
, num_items
);
921 os_free(eap_methods
[--num_items
]);
922 os_free(eap_methods
);
927 static int wpas_dbus_get_scan_type(DBusMessage
*message
, DBusMessageIter
*var
,
928 char **type
, DBusMessage
**reply
)
930 if (dbus_message_iter_get_arg_type(var
) != DBUS_TYPE_STRING
) {
931 wpa_printf(MSG_DEBUG
, "wpas_dbus_handler_scan[dbus]: "
932 "Type must be a string");
933 *reply
= wpas_dbus_error_invalid_args(
934 message
, "Wrong Type value type. String required");
937 dbus_message_iter_get_basic(var
, type
);
942 static int wpas_dbus_get_scan_ssids(DBusMessage
*message
, DBusMessageIter
*var
,
943 struct wpa_driver_scan_params
*params
,
946 struct wpa_driver_scan_ssid
*ssids
= params
->ssids
;
947 size_t ssids_num
= 0;
949 DBusMessageIter array_iter
, sub_array_iter
;
953 if (dbus_message_iter_get_arg_type(var
) != DBUS_TYPE_ARRAY
) {
954 wpa_printf(MSG_DEBUG
, "wpas_dbus_handler_scan[dbus]: ssids "
955 "must be an array of arrays of bytes");
956 *reply
= wpas_dbus_error_invalid_args(
957 message
, "Wrong SSIDs value type. Array of arrays of "
962 dbus_message_iter_recurse(var
, &array_iter
);
964 if (dbus_message_iter_get_arg_type(&array_iter
) != DBUS_TYPE_ARRAY
||
965 dbus_message_iter_get_element_type(&array_iter
) != DBUS_TYPE_BYTE
)
967 wpa_printf(MSG_DEBUG
, "wpas_dbus_handler_scan[dbus]: ssids "
968 "must be an array of arrays of bytes");
969 *reply
= wpas_dbus_error_invalid_args(
970 message
, "Wrong SSIDs value type. Array of arrays of "
975 while (dbus_message_iter_get_arg_type(&array_iter
) == DBUS_TYPE_ARRAY
)
977 if (ssids_num
>= WPAS_MAX_SCAN_SSIDS
) {
978 wpa_printf(MSG_DEBUG
, "wpas_dbus_handler_scan[dbus]: "
979 "Too many ssids specified on scan dbus "
981 *reply
= wpas_dbus_error_invalid_args(
982 message
, "Too many ssids specified. Specify "
987 dbus_message_iter_recurse(&array_iter
, &sub_array_iter
);
989 dbus_message_iter_get_fixed_array(&sub_array_iter
, &val
, &len
);
991 dbus_message_iter_next(&array_iter
);
995 ssid
= os_malloc(len
);
997 wpa_printf(MSG_DEBUG
, "wpas_dbus_handler_scan[dbus]: "
998 "out of memory. Cannot allocate memory for "
1000 *reply
= dbus_message_new_error(
1001 message
, DBUS_ERROR_NO_MEMORY
, NULL
);
1004 os_memcpy(ssid
, val
, len
);
1005 ssids
[ssids_num
].ssid
= ssid
;
1006 ssids
[ssids_num
].ssid_len
= len
;
1008 dbus_message_iter_next(&array_iter
);
1012 params
->num_ssids
= ssids_num
;
1017 static int wpas_dbus_get_scan_ies(DBusMessage
*message
, DBusMessageIter
*var
,
1018 struct wpa_driver_scan_params
*params
,
1019 DBusMessage
**reply
)
1021 u8
*ies
= NULL
, *nies
;
1023 DBusMessageIter array_iter
, sub_array_iter
;
1027 if (dbus_message_iter_get_arg_type(var
) != DBUS_TYPE_ARRAY
) {
1028 wpa_printf(MSG_DEBUG
, "wpas_dbus_handler_scan[dbus]: ies must "
1029 "be an array of arrays of bytes");
1030 *reply
= wpas_dbus_error_invalid_args(
1031 message
, "Wrong IEs value type. Array of arrays of "
1036 dbus_message_iter_recurse(var
, &array_iter
);
1038 if (dbus_message_iter_get_arg_type(&array_iter
) != DBUS_TYPE_ARRAY
||
1039 dbus_message_iter_get_element_type(&array_iter
) != DBUS_TYPE_BYTE
)
1041 wpa_printf(MSG_DEBUG
, "wpas_dbus_handler_scan[dbus]: ies must "
1042 "be an array of arrays of bytes");
1043 *reply
= wpas_dbus_error_invalid_args(
1044 message
, "Wrong IEs value type. Array required");
1048 while (dbus_message_iter_get_arg_type(&array_iter
) == DBUS_TYPE_ARRAY
)
1050 dbus_message_iter_recurse(&array_iter
, &sub_array_iter
);
1052 dbus_message_iter_get_fixed_array(&sub_array_iter
, &val
, &len
);
1054 dbus_message_iter_next(&array_iter
);
1058 nies
= os_realloc(ies
, ies_len
+ len
);
1060 wpa_printf(MSG_DEBUG
, "wpas_dbus_handler_scan[dbus]: "
1061 "out of memory. Cannot allocate memory for "
1064 *reply
= dbus_message_new_error(
1065 message
, DBUS_ERROR_NO_MEMORY
, NULL
);
1069 os_memcpy(ies
+ ies_len
, val
, len
);
1072 dbus_message_iter_next(&array_iter
);
1075 params
->extra_ies
= ies
;
1076 params
->extra_ies_len
= ies_len
;
1081 static int wpas_dbus_get_scan_channels(DBusMessage
*message
,
1082 DBusMessageIter
*var
,
1083 struct wpa_driver_scan_params
*params
,
1084 DBusMessage
**reply
)
1086 DBusMessageIter array_iter
, sub_array_iter
;
1087 int *freqs
= NULL
, *nfreqs
;
1090 if (dbus_message_iter_get_arg_type(var
) != DBUS_TYPE_ARRAY
) {
1091 wpa_printf(MSG_DEBUG
, "wpas_dbus_handler_scan[dbus]: "
1092 "Channels must be an array of structs");
1093 *reply
= wpas_dbus_error_invalid_args(
1094 message
, "Wrong Channels value type. Array of structs "
1099 dbus_message_iter_recurse(var
, &array_iter
);
1101 if (dbus_message_iter_get_arg_type(&array_iter
) != DBUS_TYPE_STRUCT
) {
1102 wpa_printf(MSG_DEBUG
,
1103 "wpas_dbus_handler_scan[dbus]: Channels must be an "
1104 "array of structs");
1105 *reply
= wpas_dbus_error_invalid_args(
1106 message
, "Wrong Channels value type. Array of structs "
1111 while (dbus_message_iter_get_arg_type(&array_iter
) == DBUS_TYPE_STRUCT
)
1115 dbus_message_iter_recurse(&array_iter
, &sub_array_iter
);
1117 if (dbus_message_iter_get_arg_type(&sub_array_iter
) !=
1119 wpa_printf(MSG_DEBUG
, "wpas_dbus_handler_scan[dbus]: "
1120 "Channel must by specified by struct of "
1122 dbus_message_iter_get_arg_type(
1124 *reply
= wpas_dbus_error_invalid_args(
1125 message
, "Wrong Channel struct. Two UINT32s "
1130 dbus_message_iter_get_basic(&sub_array_iter
, &freq
);
1132 if (!dbus_message_iter_next(&sub_array_iter
) ||
1133 dbus_message_iter_get_arg_type(&sub_array_iter
) !=
1135 wpa_printf(MSG_DEBUG
, "wpas_dbus_handler_scan[dbus]: "
1136 "Channel must by specified by struct of "
1138 *reply
= wpas_dbus_error_invalid_args(
1140 "Wrong Channel struct. Two UINT32s required");
1145 dbus_message_iter_get_basic(&sub_array_iter
, &width
);
1147 #define FREQS_ALLOC_CHUNK 32
1148 if (freqs_num
% FREQS_ALLOC_CHUNK
== 0) {
1149 nfreqs
= os_realloc(freqs
, sizeof(int) *
1150 (freqs_num
+ FREQS_ALLOC_CHUNK
));
1155 if (freqs
== NULL
) {
1156 wpa_printf(MSG_DEBUG
, "wpas_dbus_handler_scan[dbus]: "
1157 "out of memory. can't allocate memory for "
1159 *reply
= dbus_message_new_error(
1160 message
, DBUS_ERROR_NO_MEMORY
, NULL
);
1164 freqs
[freqs_num
] = freq
;
1167 dbus_message_iter_next(&array_iter
);
1170 nfreqs
= os_realloc(freqs
,
1171 sizeof(int) * (freqs_num
+ 1));
1175 if (freqs
== NULL
) {
1176 wpa_printf(MSG_DEBUG
, "wpas_dbus_handler_scan[dbus]: "
1177 "out of memory. Can't allocate memory for freqs");
1178 *reply
= dbus_message_new_error(
1179 message
, DBUS_ERROR_NO_MEMORY
, NULL
);
1182 freqs
[freqs_num
] = 0;
1184 params
->freqs
= freqs
;
1190 * wpas_dbus_handler_scan - Request a wireless scan on an interface
1191 * @message: Pointer to incoming dbus message
1192 * @wpa_s: wpa_supplicant structure for a network interface
1193 * Returns: NULL indicating success or DBus error message on failure
1195 * Handler function for "Scan" method call of a network device. Requests
1196 * that wpa_supplicant perform a wireless scan as soon as possible
1197 * on a particular wireless interface.
1199 DBusMessage
* wpas_dbus_handler_scan(DBusMessage
*message
,
1200 struct wpa_supplicant
*wpa_s
)
1202 DBusMessage
*reply
= NULL
;
1203 DBusMessageIter iter
, dict_iter
, entry_iter
, variant_iter
;
1204 char *key
= NULL
, *type
= NULL
;
1205 struct wpa_driver_scan_params params
;
1208 os_memset(¶ms
, 0, sizeof(params
));
1210 dbus_message_iter_init(message
, &iter
);
1212 dbus_message_iter_recurse(&iter
, &dict_iter
);
1214 while (dbus_message_iter_get_arg_type(&dict_iter
) ==
1215 DBUS_TYPE_DICT_ENTRY
) {
1216 dbus_message_iter_recurse(&dict_iter
, &entry_iter
);
1217 dbus_message_iter_get_basic(&entry_iter
, &key
);
1218 dbus_message_iter_next(&entry_iter
);
1219 dbus_message_iter_recurse(&entry_iter
, &variant_iter
);
1221 if (os_strcmp(key
, "Type") == 0) {
1222 if (wpas_dbus_get_scan_type(message
, &variant_iter
,
1225 } else if (os_strcmp(key
, "SSIDs") == 0) {
1226 if (wpas_dbus_get_scan_ssids(message
, &variant_iter
,
1227 ¶ms
, &reply
) < 0)
1229 } else if (os_strcmp(key
, "IEs") == 0) {
1230 if (wpas_dbus_get_scan_ies(message
, &variant_iter
,
1231 ¶ms
, &reply
) < 0)
1233 } else if (os_strcmp(key
, "Channels") == 0) {
1234 if (wpas_dbus_get_scan_channels(message
, &variant_iter
,
1235 ¶ms
, &reply
) < 0)
1238 wpa_printf(MSG_DEBUG
, "wpas_dbus_handler_scan[dbus]: "
1239 "Unknown argument %s", key
);
1240 reply
= wpas_dbus_error_invalid_args(message
, key
);
1244 dbus_message_iter_next(&dict_iter
);
1248 wpa_printf(MSG_DEBUG
, "wpas_dbus_handler_scan[dbus]: "
1249 "Scan type not specified");
1250 reply
= wpas_dbus_error_invalid_args(message
, key
);
1254 if (!os_strcmp(type
, "passive")) {
1255 if (params
.num_ssids
|| params
.extra_ies_len
) {
1256 wpa_printf(MSG_DEBUG
, "wpas_dbus_handler_scan[dbus]: "
1257 "SSIDs or IEs specified for passive scan.");
1258 reply
= wpas_dbus_error_invalid_args(
1259 message
, "You can specify only Channels in "
1262 } else if (params
.freqs
&& params
.freqs
[0]) {
1265 wpa_supplicant_trigger_scan(wpa_s
, ¶ms
);
1267 wpa_s
->scan_req
= 2;
1268 wpa_supplicant_req_scan(wpa_s
, 0, 0);
1270 } else if (!os_strcmp(type
, "active")) {
1271 wpa_supplicant_trigger_scan(wpa_s
, ¶ms
);
1273 wpa_printf(MSG_DEBUG
, "wpas_dbus_handler_scan[dbus]: "
1274 "Unknown scan type: %s", type
);
1275 reply
= wpas_dbus_error_invalid_args(message
,
1281 for (i
= 0; i
< WPAS_MAX_SCAN_SSIDS
; i
++)
1282 os_free((u8
*) params
.ssids
[i
].ssid
);
1283 os_free((u8
*) params
.extra_ies
);
1284 os_free(params
.freqs
);
1290 * wpas_dbus_handler_disconnect - Terminate the current connection
1291 * @message: Pointer to incoming dbus message
1292 * @wpa_s: wpa_supplicant structure for a network interface
1293 * Returns: NotConnected DBus error message if already not connected
1294 * or NULL otherwise.
1296 * Handler function for "Disconnect" method call of network interface.
1298 DBusMessage
* wpas_dbus_handler_disconnect(DBusMessage
*message
,
1299 struct wpa_supplicant
*wpa_s
)
1301 if (wpa_s
->current_ssid
!= NULL
) {
1302 wpa_s
->disconnected
= 1;
1303 wpa_supplicant_deauthenticate(wpa_s
,
1304 WLAN_REASON_DEAUTH_LEAVING
);
1309 return dbus_message_new_error(message
, WPAS_DBUS_ERROR_NOT_CONNECTED
,
1310 "This interface is not connected");
1315 * wpas_dbus_new_iface_add_network - Add a new configured network
1316 * @message: Pointer to incoming dbus message
1317 * @wpa_s: wpa_supplicant structure for a network interface
1318 * Returns: A dbus message containing the object path of the new network
1320 * Handler function for "AddNetwork" method call of a network interface.
1322 DBusMessage
* wpas_dbus_handler_add_network(DBusMessage
*message
,
1323 struct wpa_supplicant
*wpa_s
)
1325 DBusMessage
*reply
= NULL
;
1326 DBusMessageIter iter
;
1327 struct wpa_ssid
*ssid
= NULL
;
1328 char path_buf
[WPAS_DBUS_OBJECT_PATH_MAX
], *path
= path_buf
;
1330 dbus_message_iter_init(message
, &iter
);
1332 ssid
= wpa_config_add_network(wpa_s
->conf
);
1334 wpa_printf(MSG_ERROR
, "wpas_dbus_handler_add_network[dbus]: "
1335 "can't add new interface.");
1336 reply
= wpas_dbus_error_unknown_error(
1338 "wpa_supplicant could not add "
1339 "a network on this interface.");
1342 wpas_notify_network_added(wpa_s
, ssid
);
1344 wpa_config_set_network_defaults(ssid
);
1346 reply
= set_network_properties(message
, wpa_s
, ssid
, &iter
);
1348 wpa_printf(MSG_DEBUG
, "wpas_dbus_handler_add_network[dbus]:"
1349 "control interface couldn't set network "
1354 /* Construct the object path for this network. */
1355 os_snprintf(path
, WPAS_DBUS_OBJECT_PATH_MAX
,
1356 "%s/" WPAS_DBUS_NEW_NETWORKS_PART
"/%d",
1357 wpa_s
->dbus_new_path
, ssid
->id
);
1359 reply
= dbus_message_new_method_return(message
);
1360 if (reply
== NULL
) {
1361 reply
= dbus_message_new_error(message
, DBUS_ERROR_NO_MEMORY
,
1365 if (!dbus_message_append_args(reply
, DBUS_TYPE_OBJECT_PATH
, &path
,
1366 DBUS_TYPE_INVALID
)) {
1367 dbus_message_unref(reply
);
1368 reply
= dbus_message_new_error(message
, DBUS_ERROR_NO_MEMORY
,
1377 wpas_notify_network_removed(wpa_s
, ssid
);
1378 wpa_config_remove_network(wpa_s
->conf
, ssid
->id
);
1385 * wpas_dbus_handler_remove_network - Remove a configured network
1386 * @message: Pointer to incoming dbus message
1387 * @wpa_s: wpa_supplicant structure for a network interface
1388 * Returns: NULL on success or dbus error on failure
1390 * Handler function for "RemoveNetwork" method call of a network interface.
1392 DBusMessage
* wpas_dbus_handler_remove_network(DBusMessage
*message
,
1393 struct wpa_supplicant
*wpa_s
)
1395 DBusMessage
*reply
= NULL
;
1397 char *iface
= NULL
, *net_id
= NULL
;
1399 struct wpa_ssid
*ssid
;
1401 dbus_message_get_args(message
, NULL
, DBUS_TYPE_OBJECT_PATH
, &op
,
1404 /* Extract the network ID and ensure the network */
1405 /* is actually a child of this interface */
1406 iface
= wpas_dbus_new_decompose_object_path(op
, &net_id
, NULL
);
1407 if (iface
== NULL
|| os_strcmp(iface
, wpa_s
->dbus_new_path
) != 0) {
1408 reply
= wpas_dbus_error_invalid_args(message
, op
);
1412 id
= strtoul(net_id
, NULL
, 10);
1413 if (errno
== EINVAL
) {
1414 reply
= wpas_dbus_error_invalid_args(message
, op
);
1418 ssid
= wpa_config_get_network(wpa_s
->conf
, id
);
1420 reply
= wpas_dbus_error_network_unknown(message
);
1424 wpas_notify_network_removed(wpa_s
, ssid
);
1426 if (wpa_config_remove_network(wpa_s
->conf
, id
) < 0) {
1427 wpa_printf(MSG_ERROR
,
1428 "wpas_dbus_handler_remove_network[dbus]: "
1429 "error occurred when removing network %d", id
);
1430 reply
= wpas_dbus_error_unknown_error(
1431 message
, "error removing the specified network on "
1436 if (ssid
== wpa_s
->current_ssid
)
1437 wpa_supplicant_deauthenticate(wpa_s
,
1438 WLAN_REASON_DEAUTH_LEAVING
);
1448 * wpas_dbus_handler_select_network - Attempt association with a network
1449 * @message: Pointer to incoming dbus message
1450 * @wpa_s: wpa_supplicant structure for a network interface
1451 * Returns: NULL on success or dbus error on failure
1453 * Handler function for "SelectNetwork" method call of network interface.
1455 DBusMessage
* wpas_dbus_handler_select_network(DBusMessage
*message
,
1456 struct wpa_supplicant
*wpa_s
)
1458 DBusMessage
*reply
= NULL
;
1460 char *iface
= NULL
, *net_id
= NULL
;
1462 struct wpa_ssid
*ssid
;
1464 dbus_message_get_args(message
, NULL
, DBUS_TYPE_OBJECT_PATH
, &op
,
1467 /* Extract the network ID and ensure the network */
1468 /* is actually a child of this interface */
1469 iface
= wpas_dbus_new_decompose_object_path(op
, &net_id
, NULL
);
1470 if (iface
== NULL
|| os_strcmp(iface
, wpa_s
->dbus_new_path
) != 0) {
1471 reply
= wpas_dbus_error_invalid_args(message
, op
);
1475 id
= strtoul(net_id
, NULL
, 10);
1476 if (errno
== EINVAL
) {
1477 reply
= wpas_dbus_error_invalid_args(message
, op
);
1481 ssid
= wpa_config_get_network(wpa_s
->conf
, id
);
1483 reply
= wpas_dbus_error_network_unknown(message
);
1487 /* Finally, associate with the network */
1488 wpa_supplicant_select_network(wpa_s
, ssid
);
1498 * wpas_dbus_handler_add_blob - Store named binary blob (ie, for certificates)
1499 * @message: Pointer to incoming dbus message
1500 * @wpa_s: %wpa_supplicant data structure
1501 * Returns: A dbus message containing an error on failure or NULL on success
1503 * Asks wpa_supplicant to internally store a binary blobs.
1505 DBusMessage
* wpas_dbus_handler_add_blob(DBusMessage
*message
,
1506 struct wpa_supplicant
*wpa_s
)
1508 DBusMessage
*reply
= NULL
;
1509 DBusMessageIter iter
, array_iter
;
1514 struct wpa_config_blob
*blob
= NULL
;
1516 dbus_message_iter_init(message
, &iter
);
1517 dbus_message_iter_get_basic(&iter
, &blob_name
);
1519 if (wpa_config_get_blob(wpa_s
->conf
, blob_name
)) {
1520 return dbus_message_new_error(message
,
1521 WPAS_DBUS_ERROR_BLOB_EXISTS
,
1525 dbus_message_iter_next(&iter
);
1526 dbus_message_iter_recurse(&iter
, &array_iter
);
1528 dbus_message_iter_get_fixed_array(&array_iter
, &blob_data
, &blob_len
);
1530 blob
= os_zalloc(sizeof(*blob
));
1532 reply
= dbus_message_new_error(message
, DBUS_ERROR_NO_MEMORY
,
1537 blob
->data
= os_malloc(blob_len
);
1539 reply
= dbus_message_new_error(message
, DBUS_ERROR_NO_MEMORY
,
1543 os_memcpy(blob
->data
, blob_data
, blob_len
);
1545 blob
->len
= blob_len
;
1546 blob
->name
= os_strdup(blob_name
);
1548 reply
= dbus_message_new_error(message
, DBUS_ERROR_NO_MEMORY
,
1553 wpa_config_set_blob(wpa_s
->conf
, blob
);
1554 wpas_notify_blob_added(wpa_s
, blob
->name
);
1560 os_free(blob
->name
);
1561 os_free(blob
->data
);
1569 * wpas_dbus_handler_get_blob - Get named binary blob (ie, for certificates)
1570 * @message: Pointer to incoming dbus message
1571 * @wpa_s: %wpa_supplicant data structure
1572 * Returns: A dbus message containing array of bytes (blob)
1574 * Gets one wpa_supplicant's binary blobs.
1576 DBusMessage
* wpas_dbus_handler_get_blob(DBusMessage
*message
,
1577 struct wpa_supplicant
*wpa_s
)
1579 DBusMessage
*reply
= NULL
;
1580 DBusMessageIter iter
, array_iter
;
1583 const struct wpa_config_blob
*blob
;
1585 dbus_message_get_args(message
, NULL
, DBUS_TYPE_STRING
, &blob_name
,
1588 blob
= wpa_config_get_blob(wpa_s
->conf
, blob_name
);
1590 return dbus_message_new_error(message
,
1591 WPAS_DBUS_ERROR_BLOB_UNKNOWN
,
1595 reply
= dbus_message_new_method_return(message
);
1597 reply
= dbus_message_new_error(message
, DBUS_ERROR_NO_MEMORY
,
1602 dbus_message_iter_init_append(reply
, &iter
);
1604 if (!dbus_message_iter_open_container(&iter
, DBUS_TYPE_ARRAY
,
1605 DBUS_TYPE_BYTE_AS_STRING
,
1607 dbus_message_unref(reply
);
1608 reply
= dbus_message_new_error(message
, DBUS_ERROR_NO_MEMORY
,
1613 if (!dbus_message_iter_append_fixed_array(&array_iter
, DBUS_TYPE_BYTE
,
1614 &(blob
->data
), blob
->len
)) {
1615 dbus_message_unref(reply
);
1616 reply
= dbus_message_new_error(message
, DBUS_ERROR_NO_MEMORY
,
1621 if (!dbus_message_iter_close_container(&iter
, &array_iter
)) {
1622 dbus_message_unref(reply
);
1623 reply
= dbus_message_new_error(message
, DBUS_ERROR_NO_MEMORY
,
1634 * wpas_remove_handler_remove_blob - Remove named binary blob
1635 * @message: Pointer to incoming dbus message
1636 * @wpa_s: %wpa_supplicant data structure
1637 * Returns: NULL on success or dbus error
1639 * Asks wpa_supplicant to internally remove a binary blobs.
1641 DBusMessage
* wpas_dbus_handler_remove_blob(DBusMessage
*message
,
1642 struct wpa_supplicant
*wpa_s
)
1644 DBusMessage
*reply
= NULL
;
1647 dbus_message_get_args(message
, NULL
, DBUS_TYPE_STRING
, &blob_name
,
1650 if (wpa_config_remove_blob(wpa_s
->conf
, blob_name
)) {
1651 return dbus_message_new_error(message
,
1652 WPAS_DBUS_ERROR_BLOB_UNKNOWN
,
1655 wpas_notify_blob_removed(wpa_s
, blob_name
);
1663 * wpas_dbus_getter_capabilities - Return interface capabilities
1664 * @message: Pointer to incoming dbus message
1665 * @wpa_s: wpa_supplicant structure for a network interface
1666 * Returns: A dbus message containing a dict of strings
1668 * Getter for "Capabilities" property of an interface.
1670 DBusMessage
* wpas_dbus_getter_capabilities(DBusMessage
*message
,
1671 struct wpa_supplicant
*wpa_s
)
1673 DBusMessage
*reply
= NULL
;
1674 struct wpa_driver_capa capa
;
1676 DBusMessageIter iter
, iter_dict
;
1677 DBusMessageIter iter_dict_entry
, iter_dict_val
, iter_array
,
1679 const char *scans
[] = { "active", "passive", "ssid" };
1680 const char *modes
[] = { "infrastructure", "ad-hoc", "ap" };
1681 int n
= sizeof(modes
) / sizeof(char *);
1683 if (message
== NULL
)
1684 reply
= dbus_message_new(DBUS_MESSAGE_TYPE_SIGNAL
);
1686 reply
= dbus_message_new_method_return(message
);
1690 dbus_message_iter_init_append(reply
, &iter
);
1691 if (!dbus_message_iter_open_container(&iter
, DBUS_TYPE_VARIANT
,
1692 "a{sv}", &variant_iter
))
1695 if (!wpa_dbus_dict_open_write(&variant_iter
, &iter_dict
))
1698 res
= wpa_drv_get_capa(wpa_s
, &capa
);
1700 /***** pairwise cipher */
1702 const char *args
[] = {"ccmp", "tkip", "none"};
1703 if (!wpa_dbus_dict_append_string_array(
1704 &iter_dict
, "Pairwise", args
,
1705 sizeof(args
) / sizeof(char*)))
1708 if (!wpa_dbus_dict_begin_string_array(&iter_dict
, "Pairwise",
1714 if (capa
.enc
& WPA_DRIVER_CAPA_ENC_CCMP
) {
1715 if (!wpa_dbus_dict_string_array_add_element(
1716 &iter_array
, "ccmp"))
1720 if (capa
.enc
& WPA_DRIVER_CAPA_ENC_TKIP
) {
1721 if (!wpa_dbus_dict_string_array_add_element(
1722 &iter_array
, "tkip"))
1726 if (capa
.key_mgmt
& WPA_DRIVER_CAPA_KEY_MGMT_WPA_NONE
) {
1727 if (!wpa_dbus_dict_string_array_add_element(
1728 &iter_array
, "none"))
1732 if (!wpa_dbus_dict_end_string_array(&iter_dict
,
1739 /***** group cipher */
1741 const char *args
[] = {
1742 "ccmp", "tkip", "wep104", "wep40"
1744 if (!wpa_dbus_dict_append_string_array(
1745 &iter_dict
, "Group", args
,
1746 sizeof(args
) / sizeof(char*)))
1749 if (!wpa_dbus_dict_begin_string_array(&iter_dict
, "Group",
1755 if (capa
.enc
& WPA_DRIVER_CAPA_ENC_CCMP
) {
1756 if (!wpa_dbus_dict_string_array_add_element(
1757 &iter_array
, "ccmp"))
1761 if (capa
.enc
& WPA_DRIVER_CAPA_ENC_TKIP
) {
1762 if (!wpa_dbus_dict_string_array_add_element(
1763 &iter_array
, "tkip"))
1767 if (capa
.enc
& WPA_DRIVER_CAPA_ENC_WEP104
) {
1768 if (!wpa_dbus_dict_string_array_add_element(
1769 &iter_array
, "wep104"))
1773 if (capa
.enc
& WPA_DRIVER_CAPA_ENC_WEP40
) {
1774 if (!wpa_dbus_dict_string_array_add_element(
1775 &iter_array
, "wep40"))
1779 if (!wpa_dbus_dict_end_string_array(&iter_dict
,
1786 /***** key management */
1788 const char *args
[] = {
1789 "wpa-psk", "wpa-eap", "ieee8021x", "wpa-none",
1792 #endif /* CONFIG_WPS */
1795 if (!wpa_dbus_dict_append_string_array(
1796 &iter_dict
, "KeyMgmt", args
,
1797 sizeof(args
) / sizeof(char*)))
1800 if (!wpa_dbus_dict_begin_string_array(&iter_dict
, "KeyMgmt",
1806 if (!wpa_dbus_dict_string_array_add_element(&iter_array
,
1810 if (!wpa_dbus_dict_string_array_add_element(&iter_array
,
1814 if (capa
.key_mgmt
& (WPA_DRIVER_CAPA_KEY_MGMT_WPA
|
1815 WPA_DRIVER_CAPA_KEY_MGMT_WPA2
)) {
1816 if (!wpa_dbus_dict_string_array_add_element(
1817 &iter_array
, "wpa-eap"))
1820 if (capa
.key_mgmt
& WPA_DRIVER_CAPA_KEY_MGMT_FT
)
1821 if (!wpa_dbus_dict_string_array_add_element(
1822 &iter_array
, "wpa-ft-eap"))
1825 /* TODO: Ensure that driver actually supports sha256 encryption. */
1826 #ifdef CONFIG_IEEE80211W
1827 if (!wpa_dbus_dict_string_array_add_element(
1828 &iter_array
, "wpa-eap-sha256"))
1830 #endif /* CONFIG_IEEE80211W */
1833 if (capa
.key_mgmt
& (WPA_DRIVER_CAPA_KEY_MGMT_WPA_PSK
|
1834 WPA_DRIVER_CAPA_KEY_MGMT_WPA2_PSK
)) {
1835 if (!wpa_dbus_dict_string_array_add_element(
1836 &iter_array
, "wpa-psk"))
1839 if (capa
.key_mgmt
& WPA_DRIVER_CAPA_KEY_MGMT_FT_PSK
)
1840 if (!wpa_dbus_dict_string_array_add_element(
1841 &iter_array
, "wpa-ft-psk"))
1844 /* TODO: Ensure that driver actually supports sha256 encryption. */
1845 #ifdef CONFIG_IEEE80211W
1846 if (!wpa_dbus_dict_string_array_add_element(
1847 &iter_array
, "wpa-psk-sha256"))
1849 #endif /* CONFIG_IEEE80211W */
1852 if (capa
.key_mgmt
& WPA_DRIVER_CAPA_KEY_MGMT_WPA_NONE
) {
1853 if (!wpa_dbus_dict_string_array_add_element(
1854 &iter_array
, "wpa-none"))
1860 if (!wpa_dbus_dict_string_array_add_element(&iter_array
,
1863 #endif /* CONFIG_WPS */
1865 if (!wpa_dbus_dict_end_string_array(&iter_dict
,
1872 /***** WPA protocol */
1874 const char *args
[] = { "rsn", "wpa" };
1875 if (!wpa_dbus_dict_append_string_array(
1876 &iter_dict
, "Protocol", args
,
1877 sizeof(args
) / sizeof(char*)))
1880 if (!wpa_dbus_dict_begin_string_array(&iter_dict
, "Protocol",
1886 if (capa
.key_mgmt
& (WPA_DRIVER_CAPA_KEY_MGMT_WPA2
|
1887 WPA_DRIVER_CAPA_KEY_MGMT_WPA2_PSK
)) {
1888 if (!wpa_dbus_dict_string_array_add_element(
1889 &iter_array
, "rsn"))
1893 if (capa
.key_mgmt
& (WPA_DRIVER_CAPA_KEY_MGMT_WPA
|
1894 WPA_DRIVER_CAPA_KEY_MGMT_WPA_PSK
)) {
1895 if (!wpa_dbus_dict_string_array_add_element(
1896 &iter_array
, "wpa"))
1900 if (!wpa_dbus_dict_end_string_array(&iter_dict
,
1909 const char *args
[] = { "open", "shared", "leap" };
1910 if (!wpa_dbus_dict_append_string_array(
1911 &iter_dict
, "AuthAlg", args
,
1912 sizeof(args
) / sizeof(char*)))
1915 if (!wpa_dbus_dict_begin_string_array(&iter_dict
, "AuthAlg",
1921 if (capa
.auth
& (WPA_DRIVER_AUTH_OPEN
)) {
1922 if (!wpa_dbus_dict_string_array_add_element(
1923 &iter_array
, "open"))
1927 if (capa
.auth
& (WPA_DRIVER_AUTH_SHARED
)) {
1928 if (!wpa_dbus_dict_string_array_add_element(
1929 &iter_array
, "shared"))
1933 if (capa
.auth
& (WPA_DRIVER_AUTH_LEAP
)) {
1934 if (!wpa_dbus_dict_string_array_add_element(
1935 &iter_array
, "leap"))
1939 if (!wpa_dbus_dict_end_string_array(&iter_dict
,
1947 if (!wpa_dbus_dict_append_string_array(&iter_dict
, "Scan", scans
,
1948 sizeof(scans
) / sizeof(char *)))
1952 if (res
< 0 || !(capa
.flags
& WPA_DRIVER_FLAGS_AP
))
1953 n
--; /* exclude ap mode if it is not supported by the driver */
1954 if (!wpa_dbus_dict_append_string_array(&iter_dict
, "Modes", modes
, n
))
1957 if (!wpa_dbus_dict_close_write(&variant_iter
, &iter_dict
))
1959 if (!dbus_message_iter_close_container(&iter
, &variant_iter
))
1966 dbus_message_unref(reply
);
1968 return dbus_message_new_error(message
, DBUS_ERROR_NO_MEMORY
, NULL
);
1973 * wpas_dbus_getter_state - Get interface state
1974 * @message: Pointer to incoming dbus message
1975 * @wpa_s: wpa_supplicant structure for a network interface
1976 * Returns: A dbus message containing a STRING representing the current
1979 * Getter for "State" property.
1981 DBusMessage
* wpas_dbus_getter_state(DBusMessage
*message
,
1982 struct wpa_supplicant
*wpa_s
)
1984 DBusMessage
*reply
= NULL
;
1985 const char *str_state
;
1986 char *state_ls
, *tmp
;
1988 str_state
= wpa_supplicant_state_txt(wpa_s
->wpa_state
);
1990 /* make state string lowercase to fit new DBus API convention
1992 state_ls
= tmp
= os_strdup(str_state
);
1994 return dbus_message_new_error(message
, DBUS_ERROR_NO_MEMORY
,
1998 *tmp
= tolower(*tmp
);
2002 reply
= wpas_dbus_simple_property_getter(message
, DBUS_TYPE_STRING
,
2012 * wpas_dbus_new_iface_get_scanning - Get interface scanning state
2013 * @message: Pointer to incoming dbus message
2014 * @wpa_s: wpa_supplicant structure for a network interface
2015 * Returns: A dbus message containing whether the interface is scanning
2017 * Getter for "scanning" property.
2019 DBusMessage
* wpas_dbus_getter_scanning(DBusMessage
*message
,
2020 struct wpa_supplicant
*wpa_s
)
2022 dbus_bool_t scanning
= wpa_s
->scanning
? TRUE
: FALSE
;
2023 return wpas_dbus_simple_property_getter(message
, DBUS_TYPE_BOOLEAN
,
2029 * wpas_dbus_getter_ap_scan - Control roaming mode
2030 * @message: Pointer to incoming dbus message
2031 * @wpa_s: wpa_supplicant structure for a network interface
2032 * Returns: A message containong value of ap_scan variable
2034 * Getter function for "ApScan" property.
2036 DBusMessage
* wpas_dbus_getter_ap_scan(DBusMessage
*message
,
2037 struct wpa_supplicant
*wpa_s
)
2039 dbus_uint32_t ap_scan
= wpa_s
->conf
->ap_scan
;
2040 return wpas_dbus_simple_property_getter(message
, DBUS_TYPE_UINT32
,
2046 * wpas_dbus_setter_ap_scan - Control roaming mode
2047 * @message: Pointer to incoming dbus message
2048 * @wpa_s: wpa_supplicant structure for a network interface
2051 * Setter function for "ApScan" property.
2053 DBusMessage
* wpas_dbus_setter_ap_scan(DBusMessage
*message
,
2054 struct wpa_supplicant
*wpa_s
)
2056 DBusMessage
*reply
= NULL
;
2057 dbus_uint32_t ap_scan
;
2059 reply
= wpas_dbus_simple_property_setter(message
, DBUS_TYPE_UINT32
,
2064 if (wpa_supplicant_set_ap_scan(wpa_s
, ap_scan
)) {
2065 return wpas_dbus_error_invalid_args(
2066 message
, "ap_scan must equal 0, 1 or 2");
2073 * wpas_dbus_getter_ifname - Get interface name
2074 * @message: Pointer to incoming dbus message
2075 * @wpa_s: wpa_supplicant structure for a network interface
2076 * Returns: A dbus message containing a name of network interface
2077 * associated with with wpa_s
2079 * Getter for "Ifname" property.
2081 DBusMessage
* wpas_dbus_getter_ifname(DBusMessage
*message
,
2082 struct wpa_supplicant
*wpa_s
)
2084 const char *ifname
= wpa_s
->ifname
;
2085 return wpas_dbus_simple_property_getter(message
, DBUS_TYPE_STRING
,
2091 * wpas_dbus_getter_driver - Get interface name
2092 * @message: Pointer to incoming dbus message
2093 * @wpa_s: wpa_supplicant structure for a network interface
2094 * Returns: A dbus message containing a name of network interface
2095 * driver associated with with wpa_s
2097 * Getter for "Driver" property.
2099 DBusMessage
* wpas_dbus_getter_driver(DBusMessage
*message
,
2100 struct wpa_supplicant
*wpa_s
)
2104 if (wpa_s
->driver
== NULL
|| wpa_s
->driver
->name
== NULL
) {
2105 wpa_printf(MSG_DEBUG
, "wpas_dbus_getter_driver[dbus]: "
2106 "wpa_s has no driver set");
2107 return wpas_dbus_error_unknown_error(message
, NULL
);
2110 driver
= wpa_s
->driver
->name
;
2111 return wpas_dbus_simple_property_getter(message
, DBUS_TYPE_STRING
,
2117 * wpas_dbus_getter_current_bss - Get current bss object path
2118 * @message: Pointer to incoming dbus message
2119 * @wpa_s: wpa_supplicant structure for a network interface
2120 * Returns: A dbus message containing a DBus object path to
2123 * Getter for "CurrentBSS" property.
2125 DBusMessage
* wpas_dbus_getter_current_bss(DBusMessage
*message
,
2126 struct wpa_supplicant
*wpa_s
)
2129 char path_buf
[WPAS_DBUS_OBJECT_PATH_MAX
], *bss_obj_path
= path_buf
;
2131 if (wpa_s
->current_bss
)
2132 os_snprintf(bss_obj_path
, WPAS_DBUS_OBJECT_PATH_MAX
,
2133 "%s/" WPAS_DBUS_NEW_BSSIDS_PART
"/%u",
2134 wpa_s
->dbus_new_path
, wpa_s
->current_bss
->id
);
2136 os_snprintf(bss_obj_path
, WPAS_DBUS_OBJECT_PATH_MAX
, "/");
2138 reply
= wpas_dbus_simple_property_getter(message
,
2139 DBUS_TYPE_OBJECT_PATH
,
2147 * wpas_dbus_getter_current_network - Get current network object path
2148 * @message: Pointer to incoming dbus message
2149 * @wpa_s: wpa_supplicant structure for a network interface
2150 * Returns: A dbus message containing a DBus object path to
2153 * Getter for "CurrentNetwork" property.
2155 DBusMessage
* wpas_dbus_getter_current_network(DBusMessage
*message
,
2156 struct wpa_supplicant
*wpa_s
)
2159 char path_buf
[WPAS_DBUS_OBJECT_PATH_MAX
], *net_obj_path
= path_buf
;
2161 if (wpa_s
->current_ssid
)
2162 os_snprintf(net_obj_path
, WPAS_DBUS_OBJECT_PATH_MAX
,
2163 "%s/" WPAS_DBUS_NEW_NETWORKS_PART
"/%u",
2164 wpa_s
->dbus_new_path
, wpa_s
->current_ssid
->id
);
2166 os_snprintf(net_obj_path
, WPAS_DBUS_OBJECT_PATH_MAX
, "/");
2168 reply
= wpas_dbus_simple_property_getter(message
,
2169 DBUS_TYPE_OBJECT_PATH
,
2177 * wpas_dbus_getter_bridge_ifname - Get interface name
2178 * @message: Pointer to incoming dbus message
2179 * @wpa_s: wpa_supplicant structure for a network interface
2180 * Returns: A dbus message containing a name of bridge network
2181 * interface associated with with wpa_s
2183 * Getter for "BridgeIfname" property.
2185 DBusMessage
* wpas_dbus_getter_bridge_ifname(DBusMessage
*message
,
2186 struct wpa_supplicant
*wpa_s
)
2188 const char *bridge_ifname
= NULL
;
2190 bridge_ifname
= wpa_s
->bridge_ifname
;
2191 if (bridge_ifname
== NULL
) {
2192 wpa_printf(MSG_ERROR
, "wpas_dbus_getter_bridge_ifname[dbus]: "
2193 "wpa_s has no bridge interface name set");
2194 return wpas_dbus_error_unknown_error(message
, NULL
);
2197 return wpas_dbus_simple_property_getter(message
, DBUS_TYPE_STRING
,
2203 * wpas_dbus_getter_bsss - Get array of BSSs objects
2204 * @message: Pointer to incoming dbus message
2205 * @wpa_s: wpa_supplicant structure for a network interface
2206 * Returns: a dbus message containing an array of all known BSS objects
2209 * Getter for "BSSs" property.
2211 DBusMessage
* wpas_dbus_getter_bsss(DBusMessage
*message
,
2212 struct wpa_supplicant
*wpa_s
)
2214 DBusMessage
*reply
= NULL
;
2215 struct wpa_bss
*bss
;
2219 paths
= os_zalloc(wpa_s
->num_bss
* sizeof(char *));
2221 return dbus_message_new_error(message
, DBUS_ERROR_NO_MEMORY
,
2225 /* Loop through scan results and append each result's object path */
2226 dl_list_for_each(bss
, &wpa_s
->bss_id
, struct wpa_bss
, list_id
) {
2227 paths
[i
] = os_zalloc(WPAS_DBUS_OBJECT_PATH_MAX
);
2228 if (paths
[i
] == NULL
) {
2229 reply
= dbus_message_new_error(message
,
2230 DBUS_ERROR_NO_MEMORY
,
2234 /* Construct the object path for this BSS. */
2235 os_snprintf(paths
[i
++], WPAS_DBUS_OBJECT_PATH_MAX
,
2236 "%s/" WPAS_DBUS_NEW_BSSIDS_PART
"/%u",
2237 wpa_s
->dbus_new_path
, bss
->id
);
2240 reply
= wpas_dbus_simple_array_property_getter(message
,
2241 DBUS_TYPE_OBJECT_PATH
,
2242 paths
, wpa_s
->num_bss
);
2246 os_free(paths
[--i
]);
2253 * wpas_dbus_getter_networks - Get array of networks objects
2254 * @message: Pointer to incoming dbus message
2255 * @wpa_s: wpa_supplicant structure for a network interface
2256 * Returns: a dbus message containing an array of all configured
2257 * networks dbus object paths.
2259 * Getter for "Networks" property.
2261 DBusMessage
* wpas_dbus_getter_networks(DBusMessage
*message
,
2262 struct wpa_supplicant
*wpa_s
)
2264 DBusMessage
*reply
= NULL
;
2265 struct wpa_ssid
*ssid
;
2267 unsigned int i
= 0, num
= 0;
2269 if (wpa_s
->conf
== NULL
) {
2270 wpa_printf(MSG_ERROR
, "wpas_dbus_getter_networks[dbus]: "
2271 "An error occurred getting networks list.");
2272 return wpas_dbus_error_unknown_error(message
, NULL
);
2275 for (ssid
= wpa_s
->conf
->ssid
; ssid
; ssid
= ssid
->next
)
2278 paths
= os_zalloc(num
* sizeof(char *));
2280 return dbus_message_new_error(message
, DBUS_ERROR_NO_MEMORY
,
2284 /* Loop through configured networks and append object path of each */
2285 for (ssid
= wpa_s
->conf
->ssid
; ssid
; ssid
= ssid
->next
) {
2286 paths
[i
] = os_zalloc(WPAS_DBUS_OBJECT_PATH_MAX
);
2287 if (paths
[i
] == NULL
) {
2288 reply
= dbus_message_new_error(message
,
2289 DBUS_ERROR_NO_MEMORY
,
2294 /* Construct the object path for this network. */
2295 os_snprintf(paths
[i
++], WPAS_DBUS_OBJECT_PATH_MAX
,
2296 "%s/" WPAS_DBUS_NEW_NETWORKS_PART
"/%d",
2297 wpa_s
->dbus_new_path
, ssid
->id
);
2300 reply
= wpas_dbus_simple_array_property_getter(message
,
2301 DBUS_TYPE_OBJECT_PATH
,
2306 os_free(paths
[--i
]);
2313 * wpas_dbus_getter_blobs - Get all blobs defined for this interface
2314 * @message: Pointer to incoming dbus message
2315 * @wpa_s: wpa_supplicant structure for a network interface
2316 * Returns: a dbus message containing a dictionary of pairs (blob_name, blob)
2318 * Getter for "Blobs" property.
2320 DBusMessage
* wpas_dbus_getter_blobs(DBusMessage
*message
,
2321 struct wpa_supplicant
*wpa_s
)
2323 DBusMessage
*reply
= NULL
;
2324 DBusMessageIter iter
, variant_iter
, dict_iter
, entry_iter
, array_iter
;
2325 struct wpa_config_blob
*blob
;
2327 if (message
== NULL
)
2328 reply
= dbus_message_new(DBUS_MESSAGE_TYPE_SIGNAL
);
2330 reply
= dbus_message_new_method_return(message
);
2332 return dbus_message_new_error(message
, DBUS_ERROR_NO_MEMORY
,
2335 dbus_message_iter_init_append(reply
, &iter
);
2337 if (!dbus_message_iter_open_container(&iter
, DBUS_TYPE_VARIANT
,
2338 "a{say}", &variant_iter
) ||
2339 !dbus_message_iter_open_container(&variant_iter
, DBUS_TYPE_ARRAY
,
2340 "{say}", &dict_iter
)) {
2341 dbus_message_unref(reply
);
2342 return dbus_message_new_error(message
, DBUS_ERROR_NO_MEMORY
,
2346 blob
= wpa_s
->conf
->blobs
;
2348 if (!dbus_message_iter_open_container(&dict_iter
,
2349 DBUS_TYPE_DICT_ENTRY
,
2350 NULL
, &entry_iter
) ||
2351 !dbus_message_iter_append_basic(&entry_iter
,
2354 !dbus_message_iter_open_container(&entry_iter
,
2356 DBUS_TYPE_BYTE_AS_STRING
,
2358 !dbus_message_iter_append_fixed_array(&array_iter
,
2362 !dbus_message_iter_close_container(&entry_iter
,
2364 !dbus_message_iter_close_container(&dict_iter
,
2366 dbus_message_unref(reply
);
2367 return dbus_message_new_error(message
,
2368 DBUS_ERROR_NO_MEMORY
,
2375 if (!dbus_message_iter_close_container(&variant_iter
, &dict_iter
) ||
2376 !dbus_message_iter_close_container(&iter
, &variant_iter
)) {
2377 dbus_message_unref(reply
);
2378 return dbus_message_new_error(message
, DBUS_ERROR_NO_MEMORY
,
2387 * wpas_dbus_getter_bss_bssid - Return the BSSID of a BSS
2388 * @message: Pointer to incoming dbus message
2389 * @bss: a pair of interface describing structure and bss's id
2390 * Returns: a dbus message containing the bssid for the requested bss
2392 * Getter for "BSSID" property.
2394 DBusMessage
* wpas_dbus_getter_bss_bssid(DBusMessage
*message
,
2395 struct bss_handler_args
*bss
)
2397 struct wpa_bss
*res
= wpa_bss_get_id(bss
->wpa_s
, bss
->id
);
2400 wpa_printf(MSG_ERROR
, "wpas_dbus_getter_bss_bssid[dbus]: no "
2401 "bss with id %d found", bss
->id
);
2405 return wpas_dbus_simple_array_property_getter(message
, DBUS_TYPE_BYTE
,
2406 res
->bssid
, ETH_ALEN
);
2411 * wpas_dbus_getter_bss_ssid - Return the SSID of a BSS
2412 * @message: Pointer to incoming dbus message
2413 * @bss: a pair of interface describing structure and bss's id
2414 * Returns: a dbus message containing the ssid for the requested bss
2416 * Getter for "SSID" property.
2418 DBusMessage
* wpas_dbus_getter_bss_ssid(DBusMessage
*message
,
2419 struct bss_handler_args
*bss
)
2421 struct wpa_bss
*res
= wpa_bss_get_id(bss
->wpa_s
, bss
->id
);
2424 wpa_printf(MSG_ERROR
, "wpas_dbus_getter_bss_ssid[dbus]: no "
2425 "bss with id %d found", bss
->id
);
2429 return wpas_dbus_simple_array_property_getter(message
, DBUS_TYPE_BYTE
,
2436 * wpas_dbus_getter_bss_privacy - Return the privacy flag of a BSS
2437 * @message: Pointer to incoming dbus message
2438 * @bss: a pair of interface describing structure and bss's id
2439 * Returns: a dbus message containing the privacy flag value of requested bss
2441 * Getter for "Privacy" property.
2443 DBusMessage
* wpas_dbus_getter_bss_privacy(DBusMessage
*message
,
2444 struct bss_handler_args
*bss
)
2446 struct wpa_bss
*res
= wpa_bss_get_id(bss
->wpa_s
, bss
->id
);
2447 dbus_bool_t privacy
;
2450 wpa_printf(MSG_ERROR
, "wpas_dbus_getter_bss_privacy[dbus]: no "
2451 "bss with id %d found", bss
->id
);
2455 privacy
= (res
->caps
& IEEE80211_CAP_PRIVACY
) ? TRUE
: FALSE
;
2456 return wpas_dbus_simple_property_getter(message
, DBUS_TYPE_BOOLEAN
,
2462 * wpas_dbus_getter_bss_mode - Return the mode of a BSS
2463 * @message: Pointer to incoming dbus message
2464 * @bss: a pair of interface describing structure and bss's id
2465 * Returns: a dbus message containing the mode of requested bss
2467 * Getter for "Mode" property.
2469 DBusMessage
* wpas_dbus_getter_bss_mode(DBusMessage
*message
,
2470 struct bss_handler_args
*bss
)
2472 struct wpa_bss
*res
= wpa_bss_get_id(bss
->wpa_s
, bss
->id
);
2476 wpa_printf(MSG_ERROR
, "wpas_dbus_getter_bss_mode[dbus]: no "
2477 "bss with id %d found", bss
->id
);
2481 if (res
->caps
& IEEE80211_CAP_IBSS
)
2484 mode
= "infrastructure";
2486 return wpas_dbus_simple_property_getter(message
, DBUS_TYPE_STRING
,
2492 * wpas_dbus_getter_bss_level - Return the signal strength of a BSS
2493 * @message: Pointer to incoming dbus message
2494 * @bss: a pair of interface describing structure and bss's id
2495 * Returns: a dbus message containing the signal strength of requested bss
2497 * Getter for "Level" property.
2499 DBusMessage
* wpas_dbus_getter_bss_signal(DBusMessage
*message
,
2500 struct bss_handler_args
*bss
)
2502 struct wpa_bss
*res
= wpa_bss_get_id(bss
->wpa_s
, bss
->id
);
2505 wpa_printf(MSG_ERROR
, "wpas_dbus_getter_bss_signal[dbus]: no "
2506 "bss with id %d found", bss
->id
);
2510 return wpas_dbus_simple_property_getter(message
, DBUS_TYPE_INT16
,
2516 * wpas_dbus_getter_bss_frequency - Return the frequency of a BSS
2517 * @message: Pointer to incoming dbus message
2518 * @bss: a pair of interface describing structure and bss's id
2519 * Returns: a dbus message containing the frequency of requested bss
2521 * Getter for "Frequency" property.
2523 DBusMessage
* wpas_dbus_getter_bss_frequency(DBusMessage
*message
,
2524 struct bss_handler_args
*bss
)
2526 struct wpa_bss
*res
= wpa_bss_get_id(bss
->wpa_s
, bss
->id
);
2529 wpa_printf(MSG_ERROR
, "wpas_dbus_getter_bss_frequency[dbus]: "
2530 "no bss with id %d found", bss
->id
);
2534 return wpas_dbus_simple_property_getter(message
, DBUS_TYPE_UINT16
,
2539 static int cmp_u8s_desc(const void *a
, const void *b
)
2541 return (*(u8
*) b
- *(u8
*) a
);
2546 * wpas_dbus_getter_bss_rates - Return available bit rates of a BSS
2547 * @message: Pointer to incoming dbus message
2548 * @bss: a pair of interface describing structure and bss's id
2549 * Returns: a dbus message containing sorted array of bit rates
2551 * Getter for "Rates" property.
2553 DBusMessage
* wpas_dbus_getter_bss_rates(DBusMessage
*message
,
2554 struct bss_handler_args
*bss
)
2557 struct wpa_bss
*res
= wpa_bss_get_id(bss
->wpa_s
, bss
->id
);
2558 u8
*ie_rates
= NULL
;
2563 wpa_printf(MSG_ERROR
, "wpas_dbus_getter_bss_rates[dbus]: "
2564 "no bss with id %d found", bss
->id
);
2568 rates_num
= wpa_bss_get_bit_rates(res
, &ie_rates
);
2572 qsort(ie_rates
, rates_num
, 1, cmp_u8s_desc
);
2574 real_rates
= os_malloc(sizeof(u32
) * rates_num
);
2577 return dbus_message_new_error(message
, DBUS_ERROR_NO_MEMORY
,
2581 for (i
= 0; i
< rates_num
; i
++)
2582 real_rates
[i
] = ie_rates
[i
] * 500000;
2584 reply
= wpas_dbus_simple_array_property_getter(message
,
2586 real_rates
, rates_num
);
2589 os_free(real_rates
);
2594 static DBusMessage
* wpas_dbus_get_bss_security_prop(
2595 DBusMessage
*message
, struct wpa_ie_data
*ie_data
)
2598 DBusMessageIter iter
, iter_dict
, variant_iter
;
2600 const char *pairwise
[2]; /* max 2 pairwise ciphers is supported */
2601 const char *key_mgmt
[7]; /* max 7 key managements may be supported */
2604 if (message
== NULL
)
2605 reply
= dbus_message_new(DBUS_MESSAGE_TYPE_SIGNAL
);
2607 reply
= dbus_message_new_method_return(message
);
2611 dbus_message_iter_init_append(reply
, &iter
);
2612 if (!dbus_message_iter_open_container(&iter
, DBUS_TYPE_VARIANT
,
2613 "a{sv}", &variant_iter
))
2616 if (!wpa_dbus_dict_open_write(&variant_iter
, &iter_dict
))
2621 if (ie_data
->key_mgmt
& WPA_KEY_MGMT_PSK
)
2622 key_mgmt
[n
++] = "wpa-psk";
2623 if (ie_data
->key_mgmt
& WPA_KEY_MGMT_FT_PSK
)
2624 key_mgmt
[n
++] = "wpa-ft-psk";
2625 if (ie_data
->key_mgmt
& WPA_KEY_MGMT_PSK_SHA256
)
2626 key_mgmt
[n
++] = "wpa-psk-sha256";
2627 if (ie_data
->key_mgmt
& WPA_KEY_MGMT_IEEE8021X
)
2628 key_mgmt
[n
++] = "wpa-eap";
2629 if (ie_data
->key_mgmt
& WPA_KEY_MGMT_FT_IEEE8021X
)
2630 key_mgmt
[n
++] = "wpa-ft-eap";
2631 if (ie_data
->key_mgmt
& WPA_KEY_MGMT_IEEE8021X_SHA256
)
2632 key_mgmt
[n
++] = "wpa-eap-sha256";
2633 if (ie_data
->key_mgmt
& WPA_KEY_MGMT_NONE
)
2634 key_mgmt
[n
++] = "wpa-none";
2636 if (!wpa_dbus_dict_append_string_array(&iter_dict
, "KeyMgmt",
2641 switch (ie_data
->group_cipher
) {
2642 case WPA_CIPHER_WEP40
:
2645 case WPA_CIPHER_TKIP
:
2648 case WPA_CIPHER_CCMP
:
2651 case WPA_CIPHER_WEP104
:
2659 if (!wpa_dbus_dict_append_string(&iter_dict
, "Group", group
))
2664 if (ie_data
->pairwise_cipher
& WPA_CIPHER_TKIP
)
2665 pairwise
[n
++] = "tkip";
2666 if (ie_data
->pairwise_cipher
& WPA_CIPHER_CCMP
)
2667 pairwise
[n
++] = "ccmp";
2669 if (!wpa_dbus_dict_append_string_array(&iter_dict
, "Pairwise",
2673 /* Management group (RSN only) */
2674 if (ie_data
->proto
== WPA_PROTO_RSN
) {
2675 switch (ie_data
->mgmt_group_cipher
) {
2676 #ifdef CONFIG_IEEE80211W
2677 case WPA_CIPHER_AES_128_CMAC
:
2678 group
= "aes128cmac";
2680 #endif /* CONFIG_IEEE80211W */
2686 if (!wpa_dbus_dict_append_string(&iter_dict
, "MgmtGroup",
2691 if (!wpa_dbus_dict_close_write(&variant_iter
, &iter_dict
))
2693 if (!dbus_message_iter_close_container(&iter
, &variant_iter
))
2700 dbus_message_unref(reply
);
2702 return dbus_message_new_error(message
, DBUS_ERROR_NO_MEMORY
, NULL
);
2707 * wpas_dbus_getter_bss_wpa - Return the WPA options of a BSS
2708 * @message: Pointer to incoming dbus message
2709 * @bss: a pair of interface describing structure and bss's id
2710 * Returns: a dbus message containing the WPA options of requested bss
2712 * Getter for "WPA" property.
2714 DBusMessage
* wpas_dbus_getter_bss_wpa(DBusMessage
*message
,
2715 struct bss_handler_args
*bss
)
2717 struct wpa_bss
*res
= wpa_bss_get_id(bss
->wpa_s
, bss
->id
);
2718 struct wpa_ie_data wpa_data
;
2722 wpa_printf(MSG_ERROR
, "wpas_dbus_getter_bss_wpa[dbus]: no "
2723 "bss with id %d found", bss
->id
);
2727 os_memset(&wpa_data
, 0, sizeof(wpa_data
));
2728 ie
= wpa_bss_get_vendor_ie(res
, WPA_IE_VENDOR_TYPE
);
2730 if (wpa_parse_wpa_ie(ie
, 2 + ie
[1], &wpa_data
) < 0)
2731 return wpas_dbus_error_unknown_error(message
,
2735 return wpas_dbus_get_bss_security_prop(message
, &wpa_data
);
2740 * wpas_dbus_getter_bss_rsn - Return the RSN options of a BSS
2741 * @message: Pointer to incoming dbus message
2742 * @bss: a pair of interface describing structure and bss's id
2743 * Returns: a dbus message containing the RSN options of requested bss
2745 * Getter for "RSN" property.
2747 DBusMessage
* wpas_dbus_getter_bss_rsn(DBusMessage
*message
,
2748 struct bss_handler_args
*bss
)
2750 struct wpa_bss
*res
= wpa_bss_get_id(bss
->wpa_s
, bss
->id
);
2751 struct wpa_ie_data wpa_data
;
2755 wpa_printf(MSG_ERROR
, "wpas_dbus_getter_bss_rsn[dbus]: no "
2756 "bss with id %d found", bss
->id
);
2760 os_memset(&wpa_data
, 0, sizeof(wpa_data
));
2761 ie
= wpa_bss_get_ie(res
, WLAN_EID_RSN
);
2763 if (wpa_parse_wpa_ie(ie
, 2 + ie
[1], &wpa_data
) < 0)
2764 return wpas_dbus_error_unknown_error(message
,
2768 return wpas_dbus_get_bss_security_prop(message
, &wpa_data
);
2773 * wpas_dbus_getter_bss_ies - Return all IEs of a BSS
2774 * @message: Pointer to incoming dbus message
2775 * @bss: a pair of interface describing structure and bss's id
2776 * Returns: a dbus message containing IEs byte array
2778 * Getter for "IEs" property.
2780 DBusMessage
* wpas_dbus_getter_bss_ies(DBusMessage
*message
,
2781 struct bss_handler_args
*bss
)
2783 struct wpa_bss
*res
= wpa_bss_get_id(bss
->wpa_s
, bss
->id
);
2786 wpa_printf(MSG_ERROR
, "wpas_dbus_getter_bss_ies[dbus]: no "
2787 "bss with id %d found", bss
->id
);
2791 return wpas_dbus_simple_array_property_getter(message
, DBUS_TYPE_BYTE
,
2792 res
+ 1, res
->ie_len
);
2797 * wpas_dbus_getter_enabled - Check whether network is enabled or disabled
2798 * @message: Pointer to incoming dbus message
2799 * @wpas_dbus_setter_enabled: wpa_supplicant structure for a network interface
2800 * and wpa_ssid structure for a configured network
2801 * Returns: DBus message with boolean indicating state of configured network
2802 * or DBus error on failure
2804 * Getter for "enabled" property of a configured network.
2806 DBusMessage
* wpas_dbus_getter_enabled(DBusMessage
*message
,
2807 struct network_handler_args
*net
)
2809 dbus_bool_t enabled
= net
->ssid
->disabled
? FALSE
: TRUE
;
2810 return wpas_dbus_simple_property_getter(message
, DBUS_TYPE_BOOLEAN
,
2816 * wpas_dbus_setter_enabled - Mark a configured network as enabled or disabled
2817 * @message: Pointer to incoming dbus message
2818 * @wpas_dbus_setter_enabled: wpa_supplicant structure for a network interface
2819 * and wpa_ssid structure for a configured network
2820 * Returns: NULL indicating success or DBus error on failure
2822 * Setter for "Enabled" property of a configured network.
2824 DBusMessage
* wpas_dbus_setter_enabled(DBusMessage
*message
,
2825 struct network_handler_args
*net
)
2827 DBusMessage
*reply
= NULL
;
2829 struct wpa_supplicant
*wpa_s
;
2830 struct wpa_ssid
*ssid
;
2834 reply
= wpas_dbus_simple_property_setter(message
, DBUS_TYPE_BOOLEAN
,
2844 wpa_supplicant_enable_network(wpa_s
, ssid
);
2846 wpa_supplicant_disable_network(wpa_s
, ssid
);
2853 * wpas_dbus_getter_network_properties - Get options for a configured network
2854 * @message: Pointer to incoming dbus message
2855 * @net: wpa_supplicant structure for a network interface and
2856 * wpa_ssid structure for a configured network
2857 * Returns: DBus message with network properties or DBus error on failure
2859 * Getter for "Properties" property of a configured network.
2861 DBusMessage
* wpas_dbus_getter_network_properties(
2862 DBusMessage
*message
, struct network_handler_args
*net
)
2864 DBusMessage
*reply
= NULL
;
2865 DBusMessageIter iter
, variant_iter
, dict_iter
;
2867 char **props
= wpa_config_get_all(net
->ssid
, 0);
2869 return dbus_message_new_error(message
, DBUS_ERROR_NO_MEMORY
,
2872 if (message
== NULL
)
2873 reply
= dbus_message_new(DBUS_MESSAGE_TYPE_SIGNAL
);
2875 reply
= dbus_message_new_method_return(message
);
2877 reply
= dbus_message_new_error(message
, DBUS_ERROR_NO_MEMORY
,
2882 dbus_message_iter_init_append(reply
, &iter
);
2884 if (!dbus_message_iter_open_container(&iter
, DBUS_TYPE_VARIANT
,
2885 "a{sv}", &variant_iter
) ||
2886 !wpa_dbus_dict_open_write(&variant_iter
, &dict_iter
)) {
2887 dbus_message_unref(reply
);
2888 reply
= dbus_message_new_error(message
, DBUS_ERROR_NO_MEMORY
,
2895 if (!wpa_dbus_dict_append_string(&dict_iter
, *iterator
,
2897 dbus_message_unref(reply
);
2898 reply
= dbus_message_new_error(message
,
2899 DBUS_ERROR_NO_MEMORY
,
2907 if (!wpa_dbus_dict_close_write(&variant_iter
, &dict_iter
) ||
2908 !dbus_message_iter_close_container(&iter
, &variant_iter
)) {
2909 dbus_message_unref(reply
);
2910 reply
= dbus_message_new_error(message
, DBUS_ERROR_NO_MEMORY
,
2927 * wpas_dbus_setter_network_properties - Set options for a configured network
2928 * @message: Pointer to incoming dbus message
2929 * @net: wpa_supplicant structure for a network interface and
2930 * wpa_ssid structure for a configured network
2931 * Returns: NULL indicating success or DBus error on failure
2933 * Setter for "Properties" property of a configured network.
2935 DBusMessage
* wpas_dbus_setter_network_properties(
2936 DBusMessage
*message
, struct network_handler_args
*net
)
2938 struct wpa_ssid
*ssid
= net
->ssid
;
2940 DBusMessage
*reply
= NULL
;
2941 DBusMessageIter iter
, variant_iter
;
2943 dbus_message_iter_init(message
, &iter
);
2945 dbus_message_iter_next(&iter
);
2946 dbus_message_iter_next(&iter
);
2948 dbus_message_iter_recurse(&iter
, &variant_iter
);
2950 reply
= set_network_properties(message
, net
->wpa_s
, ssid
,
2953 wpa_printf(MSG_DEBUG
, "dbus control interface couldn't set "
2954 "network properties");