2 * WPA Supplicant / dbus-based control interface
3 * Copyright (c) 2006, Dan Williams <dcbw@redhat.com> and Red Hat, Inc.
4 * Copyright (c) 2009, 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 "../config.h"
24 #include "../wpa_supplicant_i.h"
25 #include "../driver_i.h"
26 #include "../notify.h"
27 #include "../wpas_glue.h"
29 #include "dbus_new_helpers.h"
31 #include "dbus_new_handlers.h"
32 #include "dbus_dict_helpers.h"
34 extern int wpa_debug_level
;
35 extern int wpa_debug_show_keys
;
36 extern int wpa_debug_timestamp
;
40 * wpas_dbus_new_decompose_object_path - Decompose an interface object path into parts
41 * @path: The dbus object path
42 * @network: (out) the configured network this object path refers to, if any
43 * @bssid: (out) the scanned bssid this object path refers to, if any
44 * Returns: The object path of the network interface this path refers to
46 * For a given object path, decomposes the object path into object id, network,
47 * and BSSID parts, if those parts exist.
49 static char * wpas_dbus_new_decompose_object_path(const char *path
,
53 const unsigned int dev_path_prefix_len
=
54 strlen(WPAS_DBUS_NEW_PATH_INTERFACES
"/");
58 /* Be a bit paranoid about path */
59 if (!path
|| os_strncmp(path
, WPAS_DBUS_NEW_PATH_INTERFACES
"/",
63 /* Ensure there's something at the end of the path */
64 if ((path
+ dev_path_prefix_len
)[0] == '\0')
67 obj_path_only
= os_strdup(path
);
68 if (obj_path_only
== NULL
)
71 next_sep
= os_strchr(obj_path_only
+ dev_path_prefix_len
, '/');
72 if (next_sep
!= NULL
) {
73 const char *net_part
= os_strstr(
74 next_sep
, WPAS_DBUS_NEW_NETWORKS_PART
"/");
75 const char *bssid_part
= os_strstr(
76 next_sep
, WPAS_DBUS_NEW_BSSIDS_PART
"/");
78 if (network
&& net_part
) {
79 /* Deal with a request for a configured network */
80 const char *net_name
= net_part
+
81 os_strlen(WPAS_DBUS_NEW_NETWORKS_PART
"/");
83 if (os_strlen(net_name
))
84 *network
= os_strdup(net_name
);
85 } else if (bssid
&& bssid_part
) {
86 /* Deal with a request for a scanned BSSID */
87 const char *bssid_name
= bssid_part
+
88 os_strlen(WPAS_DBUS_NEW_BSSIDS_PART
"/");
89 if (strlen(bssid_name
))
90 *bssid
= os_strdup(bssid_name
);
95 /* Cut off interface object path before "/" */
104 * wpas_dbus_error_unknown_error - Return a new InvalidArgs error message
105 * @message: Pointer to incoming dbus message this error refers to
106 * @arg: Optional string appended to error message
107 * Returns: a dbus error message
109 * Convenience function to create and return an UnknownError
111 DBusMessage
* wpas_dbus_error_unknown_error(DBusMessage
*message
,
114 return dbus_message_new_error(message
, WPAS_DBUS_ERROR_UNKNOWN_ERROR
,
120 * wpas_dbus_error_iface_unknown - Return a new invalid interface error message
121 * @message: Pointer to incoming dbus message this error refers to
122 * Returns: A dbus error message
124 * Convenience function to create and return an invalid interface error
126 static DBusMessage
* wpas_dbus_error_iface_unknown(DBusMessage
*message
)
128 return dbus_message_new_error(message
, WPAS_DBUS_ERROR_IFACE_UNKNOWN
,
129 "wpa_supplicant knows nothing about "
135 * wpas_dbus_error_network_unknown - Return a new NetworkUnknown error message
136 * @message: Pointer to incoming dbus message this error refers to
137 * Returns: a dbus error message
139 * Convenience function to create and return an invalid network error
141 static DBusMessage
* wpas_dbus_error_network_unknown(DBusMessage
*message
)
143 return dbus_message_new_error(message
, WPAS_DBUS_ERROR_NETWORK_UNKNOWN
,
144 "There is no such a network in this "
150 * wpas_dbus_error_invalid_args - Return a new InvalidArgs error message
151 * @message: Pointer to incoming dbus message this error refers to
152 * Returns: a dbus error message
154 * Convenience function to create and return an invalid options error
156 DBusMessage
* wpas_dbus_error_invalid_args(DBusMessage
*message
,
161 reply
= dbus_message_new_error(message
, WPAS_DBUS_ERROR_INVALID_ARGS
,
162 "Did not receive correct message "
165 dbus_message_append_args(reply
, DBUS_TYPE_STRING
, &arg
,
172 static const char *dont_quote
[] = {
173 "key_mgmt", "proto", "pairwise", "auth_alg", "group", "eap",
174 "opensc_engine_path", "pkcs11_engine_path", "pkcs11_module_path",
178 static dbus_bool_t
should_quote_opt(const char *key
)
181 while (dont_quote
[i
] != NULL
) {
182 if (os_strcmp(key
, dont_quote
[i
]) == 0)
190 * get_iface_by_dbus_path - Get a new network interface
191 * @global: Pointer to global data from wpa_supplicant_init()
192 * @path: Pointer to a dbus object path representing an interface
193 * Returns: Pointer to the interface or %NULL if not found
195 static struct wpa_supplicant
* get_iface_by_dbus_path(
196 struct wpa_global
*global
, const char *path
)
198 struct wpa_supplicant
*wpa_s
;
200 for (wpa_s
= global
->ifaces
; wpa_s
; wpa_s
= wpa_s
->next
) {
201 if (os_strcmp(wpa_s
->dbus_new_path
, path
) == 0)
209 * set_network_properties - Set properties of a configured network
210 * @message: Pointer to incoming dbus message
211 * @ssid: wpa_ssid structure for a configured network
212 * @iter: DBus message iterator containing dictionary of network
214 * Returns: NULL when succeed or DBus error on failure
216 * Sets network configuration with parameters given id DBus dictionary
218 static DBusMessage
* set_network_properties(DBusMessage
*message
,
219 struct wpa_ssid
*ssid
,
220 DBusMessageIter
*iter
)
223 struct wpa_dbus_dict_entry entry
= { .type
= DBUS_TYPE_STRING
};
224 DBusMessage
*reply
= NULL
;
225 DBusMessageIter iter_dict
;
227 if (!wpa_dbus_dict_open_read(iter
, &iter_dict
))
228 return wpas_dbus_error_invalid_args(message
, NULL
);
230 while (wpa_dbus_dict_has_dict_entry(&iter_dict
)) {
234 if (!wpa_dbus_dict_get_entry(&iter_dict
, &entry
)) {
235 reply
= wpas_dbus_error_invalid_args(message
, NULL
);
238 if (entry
.type
== DBUS_TYPE_ARRAY
&&
239 entry
.array_type
== DBUS_TYPE_BYTE
) {
240 if (entry
.array_len
<= 0)
243 size
= entry
.array_len
* 2 + 1;
244 value
= os_zalloc(size
);
248 ret
= wpa_snprintf_hex(value
, size
,
249 (u8
*) entry
.bytearray_value
,
253 } else if (entry
.type
== DBUS_TYPE_STRING
) {
254 if (should_quote_opt(entry
.key
)) {
255 size
= os_strlen(entry
.str_value
);
260 value
= os_zalloc(size
);
264 ret
= os_snprintf(value
, size
, "\"%s\"",
266 if (ret
< 0 || (size_t) ret
!= (size
- 1))
269 value
= os_strdup(entry
.str_value
);
273 } else if (entry
.type
== DBUS_TYPE_UINT32
) {
274 value
= os_zalloc(size
);
278 ret
= os_snprintf(value
, size
, "%u",
282 } else if (entry
.type
== DBUS_TYPE_INT32
) {
283 value
= os_zalloc(size
);
287 ret
= os_snprintf(value
, size
, "%d",
294 if (wpa_config_set(ssid
, entry
.key
, value
, 0) < 0)
297 if ((os_strcmp(entry
.key
, "psk") == 0 &&
298 value
[0] == '"' && ssid
->ssid_len
) ||
299 (strcmp(entry
.key
, "ssid") == 0 && ssid
->passphrase
))
300 wpa_config_update_psk(ssid
);
303 wpa_dbus_dict_entry_clear(&entry
);
308 reply
= wpas_dbus_error_invalid_args(message
, entry
.key
);
309 wpa_dbus_dict_entry_clear(&entry
);
317 static const char * _get_dbus_type_as_string(const int type
)
321 return DBUS_TYPE_BYTE_AS_STRING
;
322 case DBUS_TYPE_BOOLEAN
:
323 return DBUS_TYPE_BOOLEAN_AS_STRING
;
324 case DBUS_TYPE_INT16
:
325 return DBUS_TYPE_INT16_AS_STRING
;
326 case DBUS_TYPE_UINT16
:
327 return DBUS_TYPE_UINT16_AS_STRING
;
328 case DBUS_TYPE_INT32
:
329 return DBUS_TYPE_INT32_AS_STRING
;
330 case DBUS_TYPE_UINT32
:
331 return DBUS_TYPE_UINT32_AS_STRING
;
332 case DBUS_TYPE_INT64
:
333 return DBUS_TYPE_INT64_AS_STRING
;
334 case DBUS_TYPE_UINT64
:
335 return DBUS_TYPE_UINT64_AS_STRING
;
336 case DBUS_TYPE_DOUBLE
:
337 return DBUS_TYPE_DOUBLE_AS_STRING
;
338 case DBUS_TYPE_STRING
:
339 return DBUS_TYPE_STRING_AS_STRING
;
340 case DBUS_TYPE_OBJECT_PATH
:
341 return DBUS_TYPE_OBJECT_PATH_AS_STRING
;
349 * wpas_dbus_simple_property_getter - Get basic type property
350 * @message: Pointer to incoming dbus message
351 * @type: DBus type of property (must be basic type)
352 * @val: pointer to place holding property value
353 * Returns: The DBus message containing response for Properties.Get call
354 * or DBus error message if error occurred.
356 * Generic getter for basic type properties. Type is required to be basic.
358 DBusMessage
* wpas_dbus_simple_property_getter(DBusMessage
*message
,
359 const int type
, const void *val
)
361 DBusMessage
*reply
= NULL
;
362 DBusMessageIter iter
, variant_iter
;
364 if (!dbus_type_is_basic(type
)) {
365 wpa_printf(MSG_ERROR
, "dbus: wpas_dbus_simple_property_getter:"
366 " given type is not basic");
367 return wpas_dbus_error_unknown_error(message
, NULL
);
371 reply
= dbus_message_new(DBUS_MESSAGE_TYPE_SIGNAL
);
373 reply
= dbus_message_new_method_return(message
);
376 dbus_message_iter_init_append(reply
, &iter
);
377 if (!dbus_message_iter_open_container(
378 &iter
, DBUS_TYPE_VARIANT
,
379 _get_dbus_type_as_string(type
), &variant_iter
) ||
380 !dbus_message_iter_append_basic(&variant_iter
, type
,
382 !dbus_message_iter_close_container(&iter
, &variant_iter
)) {
383 wpa_printf(MSG_ERROR
, "dbus: "
384 "wpas_dbus_simple_property_getter: out of "
385 "memory to put property value into "
387 dbus_message_unref(reply
);
388 reply
= dbus_message_new_error(message
,
389 DBUS_ERROR_NO_MEMORY
,
393 wpa_printf(MSG_ERROR
, "dbus: wpas_dbus_simple_property_getter:"
394 " out of memory to return property value");
395 reply
= dbus_message_new_error(message
, DBUS_ERROR_NO_MEMORY
,
404 * wpas_dbus_simple_property_setter - Set basic type property
405 * @message: Pointer to incoming dbus message
406 * @type: DBus type of property (must be basic type)
407 * @val: pointer to place where value being set will be stored
408 * Returns: NULL or DBus error message if error occurred.
410 * Generic setter for basic type properties. Type is required to be basic.
412 DBusMessage
* wpas_dbus_simple_property_setter(DBusMessage
*message
,
413 const int type
, void *val
)
415 DBusMessageIter iter
, variant_iter
;
417 if (!dbus_type_is_basic(type
)) {
418 wpa_printf(MSG_ERROR
, "dbus: wpas_dbus_simple_property_setter:"
419 " given type is not basic");
420 return wpas_dbus_error_unknown_error(message
, NULL
);
423 if (!dbus_message_iter_init(message
, &iter
)) {
424 wpa_printf(MSG_ERROR
, "dbus: wpas_dbus_simple_property_setter:"
425 " out of memory to return scanning state");
426 return dbus_message_new_error(message
, DBUS_ERROR_NO_MEMORY
,
430 /* omit first and second argument and get value from third */
431 dbus_message_iter_next(&iter
);
432 dbus_message_iter_next(&iter
);
433 dbus_message_iter_recurse(&iter
, &variant_iter
);
435 if (dbus_message_iter_get_arg_type(&variant_iter
) != type
) {
436 wpa_printf(MSG_DEBUG
, "dbus: wpas_dbus_simple_property_setter:"
437 " wrong property type");
438 return wpas_dbus_error_invalid_args(message
,
439 "wrong property type");
441 dbus_message_iter_get_basic(&variant_iter
, val
);
448 * wpas_dbus_simple_array_property_getter - Get array type property
449 * @message: Pointer to incoming dbus message
450 * @type: DBus type of property array elements (must be basic type)
451 * @array: pointer to array of elements to put into response message
452 * @array_len: length of above array
453 * Returns: The DBus message containing response for Properties.Get call
454 * or DBus error message if error occurred.
456 * Generic getter for array type properties. Array elements type is
457 * required to be basic.
459 DBusMessage
* wpas_dbus_simple_array_property_getter(DBusMessage
*message
,
464 DBusMessage
*reply
= NULL
;
465 DBusMessageIter iter
, variant_iter
, array_iter
;
466 char type_str
[] = "a?"; /* ? will be replaced with subtype letter; */
467 const char *sub_type_str
;
468 size_t element_size
, i
;
470 if (!dbus_type_is_basic(type
)) {
471 wpa_printf(MSG_ERROR
, "dbus: "
472 "wpas_dbus_simple_array_property_getter: given "
473 "type is not basic");
474 return wpas_dbus_error_unknown_error(message
, NULL
);
477 sub_type_str
= _get_dbus_type_as_string(type
);
478 type_str
[1] = sub_type_str
[0];
481 reply
= dbus_message_new(DBUS_MESSAGE_TYPE_SIGNAL
);
483 reply
= dbus_message_new_method_return(message
);
485 wpa_printf(MSG_ERROR
, "dbus: "
486 "wpas_dbus_simple_array_property_getter: out of "
487 "memory to create return message");
488 return dbus_message_new_error(message
, DBUS_ERROR_NO_MEMORY
,
492 dbus_message_iter_init_append(reply
, &iter
);
494 if (!dbus_message_iter_open_container(&iter
, DBUS_TYPE_VARIANT
,
495 type_str
, &variant_iter
) ||
496 !dbus_message_iter_open_container(&variant_iter
, DBUS_TYPE_ARRAY
,
497 sub_type_str
, &array_iter
)) {
498 wpa_printf(MSG_ERROR
, "dbus: "
499 "wpas_dbus_simple_array_property_getter: out of "
500 "memory to open container");
501 dbus_message_unref(reply
);
502 return dbus_message_new_error(message
, DBUS_ERROR_NO_MEMORY
,
508 case DBUS_TYPE_BOOLEAN
:
511 case DBUS_TYPE_INT16
:
512 case DBUS_TYPE_UINT16
:
513 element_size
= sizeof(uint16_t);
515 case DBUS_TYPE_INT32
:
516 case DBUS_TYPE_UINT32
:
517 element_size
= sizeof(uint32_t);
519 case DBUS_TYPE_INT64
:
520 case DBUS_TYPE_UINT64
:
521 element_size
= sizeof(uint64_t);
523 case DBUS_TYPE_DOUBLE
:
524 element_size
= sizeof(double);
526 case DBUS_TYPE_STRING
:
527 case DBUS_TYPE_OBJECT_PATH
:
528 element_size
= sizeof(char *);
531 wpa_printf(MSG_ERROR
, "dbus: "
532 "wpas_dbus_simple_array_property_getter: "
533 "fatal: unknown element type");
538 for (i
= 0; i
< array_len
; i
++) {
539 dbus_message_iter_append_basic(&array_iter
, type
,
540 array
+ i
* element_size
);
543 if (!dbus_message_iter_close_container(&variant_iter
, &array_iter
) ||
544 !dbus_message_iter_close_container(&iter
, &variant_iter
)) {
545 wpa_printf(MSG_ERROR
, "dbus: "
546 "wpas_dbus_simple_array_property_getter: out of "
547 "memory to close container");
548 dbus_message_unref(reply
);
549 return dbus_message_new_error(message
, DBUS_ERROR_NO_MEMORY
,
558 * wpas_dbus_handler_create_interface - Request registration of a network iface
559 * @message: Pointer to incoming dbus message
560 * @global: %wpa_supplicant global data structure
561 * Returns: The object path of the new interface object,
562 * or a dbus error message with more information
564 * Handler function for "CreateInterface" method call. Handles requests
565 * by dbus clients to register a network interface that wpa_supplicant
568 DBusMessage
* wpas_dbus_handler_create_interface(DBusMessage
*message
,
569 struct wpa_global
*global
)
571 DBusMessageIter iter_dict
;
572 DBusMessage
*reply
= NULL
;
573 DBusMessageIter iter
;
574 struct wpa_dbus_dict_entry entry
;
577 char *bridge_ifname
= NULL
;
579 dbus_message_iter_init(message
, &iter
);
581 if (!wpa_dbus_dict_open_read(&iter
, &iter_dict
))
583 while (wpa_dbus_dict_has_dict_entry(&iter_dict
)) {
584 if (!wpa_dbus_dict_get_entry(&iter_dict
, &entry
))
586 if (!strcmp(entry
.key
, "Driver") &&
587 (entry
.type
== DBUS_TYPE_STRING
)) {
588 driver
= os_strdup(entry
.str_value
);
589 wpa_dbus_dict_entry_clear(&entry
);
592 } else if (!strcmp(entry
.key
, "Ifname") &&
593 (entry
.type
== DBUS_TYPE_STRING
)) {
594 ifname
= os_strdup(entry
.str_value
);
595 wpa_dbus_dict_entry_clear(&entry
);
598 } else if (!strcmp(entry
.key
, "BridgeIfname") &&
599 (entry
.type
== DBUS_TYPE_STRING
)) {
600 bridge_ifname
= os_strdup(entry
.str_value
);
601 wpa_dbus_dict_entry_clear(&entry
);
602 if (bridge_ifname
== NULL
)
605 wpa_dbus_dict_entry_clear(&entry
);
611 goto error
; /* Required Ifname argument missing */
614 * Try to get the wpa_supplicant record for this iface, return
615 * an error if we already control it.
617 if (wpa_supplicant_get_iface(global
, ifname
) != NULL
) {
618 reply
= dbus_message_new_error(message
,
619 WPAS_DBUS_ERROR_IFACE_EXISTS
,
620 "wpa_supplicant already "
621 "controls this interface.");
623 struct wpa_supplicant
*wpa_s
;
624 struct wpa_interface iface
;
625 os_memset(&iface
, 0, sizeof(iface
));
626 iface
.driver
= driver
;
627 iface
.ifname
= ifname
;
628 iface
.bridge_ifname
= bridge_ifname
;
629 /* Otherwise, have wpa_supplicant attach to it. */
630 if ((wpa_s
= wpa_supplicant_add_iface(global
, &iface
))) {
631 const char *path
= wpa_s
->dbus_new_path
;
632 reply
= dbus_message_new_method_return(message
);
633 dbus_message_append_args(reply
, DBUS_TYPE_OBJECT_PATH
,
634 &path
, DBUS_TYPE_INVALID
);
636 reply
= wpas_dbus_error_unknown_error(
637 message
, "wpa_supplicant couldn't grab this "
645 os_free(bridge_ifname
);
649 reply
= wpas_dbus_error_invalid_args(message
, NULL
);
655 * wpas_dbus_handler_remove_interface - Request deregistration of an interface
656 * @message: Pointer to incoming dbus message
657 * @global: wpa_supplicant global data structure
658 * Returns: a dbus message containing a UINT32 indicating success (1) or
659 * failure (0), or returns a dbus error message with more information
661 * Handler function for "removeInterface" method call. Handles requests
662 * by dbus clients to deregister a network interface that wpa_supplicant
665 DBusMessage
* wpas_dbus_handler_remove_interface(DBusMessage
*message
,
666 struct wpa_global
*global
)
668 struct wpa_supplicant
*wpa_s
;
670 DBusMessage
*reply
= NULL
;
672 dbus_message_get_args(message
, NULL
, DBUS_TYPE_OBJECT_PATH
, &path
,
675 wpa_s
= get_iface_by_dbus_path(global
, path
);
677 reply
= wpas_dbus_error_iface_unknown(message
);
678 else if (wpa_supplicant_remove_iface(global
, wpa_s
)) {
679 reply
= wpas_dbus_error_unknown_error(
680 message
, "wpa_supplicant couldn't remove this "
689 * wpas_dbus_handler_get_interface - Get the object path for an interface name
690 * @message: Pointer to incoming dbus message
691 * @global: %wpa_supplicant global data structure
692 * Returns: The object path of the interface object,
693 * or a dbus error message with more information
695 * Handler function for "getInterface" method call.
697 DBusMessage
* wpas_dbus_handler_get_interface(DBusMessage
*message
,
698 struct wpa_global
*global
)
700 DBusMessage
*reply
= NULL
;
703 struct wpa_supplicant
*wpa_s
;
705 dbus_message_get_args(message
, NULL
, DBUS_TYPE_STRING
, &ifname
,
708 wpa_s
= wpa_supplicant_get_iface(global
, ifname
);
710 return wpas_dbus_error_iface_unknown(message
);
712 path
= wpa_s
->dbus_new_path
;
713 reply
= dbus_message_new_method_return(message
);
715 return dbus_message_new_error(message
, DBUS_ERROR_NO_MEMORY
,
717 if (!dbus_message_append_args(reply
, DBUS_TYPE_OBJECT_PATH
, &path
,
718 DBUS_TYPE_INVALID
)) {
719 dbus_message_unref(reply
);
720 return dbus_message_new_error(message
, DBUS_ERROR_NO_MEMORY
,
729 * wpas_dbus_getter_debug_level - Get debug level
730 * @message: Pointer to incoming dbus message
731 * @global: %wpa_supplicant global data structure
732 * Returns: DBus message with value of debug level
734 * Getter for "DebugLevel" property.
736 DBusMessage
* wpas_dbus_getter_debug_level(DBusMessage
*message
,
737 struct wpa_global
*global
)
739 return wpas_dbus_simple_property_getter(message
, DBUS_TYPE_BYTE
,
746 * wpas_dbus_getter_debug_timestamp - Get debug timestamp
747 * @message: Pointer to incoming dbus message
748 * @global: %wpa_supplicant global data structure
749 * Returns: DBus message with value of debug timestamp
751 * Getter for "DebugTimestamp" property.
753 DBusMessage
* wpas_dbus_getter_debug_timestamp(DBusMessage
*message
,
754 struct wpa_global
*global
)
756 return wpas_dbus_simple_property_getter(message
, DBUS_TYPE_BOOLEAN
,
757 &wpa_debug_timestamp
);
763 * wpas_dbus_getter_debug_show_keys - Get debug show keys
764 * @message: Pointer to incoming dbus message
765 * @global: %wpa_supplicant global data structure
766 * Returns: DBus message with value of debug show_keys
768 * Getter for "DebugShowKeys" property.
770 DBusMessage
* wpas_dbus_getter_debug_show_keys(DBusMessage
*message
,
771 struct wpa_global
*global
)
773 return wpas_dbus_simple_property_getter(message
, DBUS_TYPE_BOOLEAN
,
774 &wpa_debug_show_keys
);
779 * wpas_dbus_setter_debug_level - Set debug level
780 * @message: Pointer to incoming dbus message
781 * @global: %wpa_supplicant global data structure
782 * Returns: %NULL or DBus error message
784 * Setter for "DebugLevel" property.
786 DBusMessage
* wpas_dbus_setter_debug_level(DBusMessage
*message
,
787 struct wpa_global
*global
)
789 DBusMessage
*reply
= NULL
;
792 reply
= wpas_dbus_simple_property_setter(message
, DBUS_TYPE_INT16
,
797 if (wpa_supplicant_set_debug_params(global
, val
, wpa_debug_timestamp
,
798 wpa_debug_show_keys
)) {
799 dbus_message_unref(reply
);
800 return wpas_dbus_error_invalid_args(
801 message
, "Wrong debug level value");
809 * wpas_dbus_setter_debug_timestamp - Set debug timestamp
810 * @message: Pointer to incoming dbus message
811 * @global: %wpa_supplicant global data structure
812 * Returns: %NULL or DBus error message
814 * Setter for "DebugTimestamp" property.
816 DBusMessage
* wpas_dbus_setter_debug_timestamp(DBusMessage
*message
,
817 struct wpa_global
*global
)
819 DBusMessage
*reply
= NULL
;
822 reply
= wpas_dbus_simple_property_setter(message
, DBUS_TYPE_BOOLEAN
,
827 wpa_supplicant_set_debug_params(global
, wpa_debug_level
, val
? 1 : 0,
828 wpa_debug_show_keys
);
835 * wpas_dbus_setter_debug_show_keys - Set debug show keys
836 * @message: Pointer to incoming dbus message
837 * @global: %wpa_supplicant global data structure
838 * Returns: %NULL or DBus error message
840 * Setter for "DebugShowKeys" property.
842 DBusMessage
* wpas_dbus_setter_debug_show_keys(DBusMessage
*message
,
843 struct wpa_global
*global
)
845 DBusMessage
*reply
= NULL
;
848 reply
= wpas_dbus_simple_property_setter(message
, DBUS_TYPE_BOOLEAN
,
853 wpa_supplicant_set_debug_params(global
, wpa_debug_level
,
862 * wpas_dbus_getter_interfaces - Request registered interfaces list
863 * @message: Pointer to incoming dbus message
864 * @global: %wpa_supplicant global data structure
865 * Returns: The object paths array containing registered interfaces
866 * objects paths or DBus error on failure
868 * Getter for "Interfaces" property. Handles requests
869 * by dbus clients to return list of registered interfaces objects
872 DBusMessage
* wpas_dbus_getter_interfaces(DBusMessage
*message
,
873 struct wpa_global
*global
)
875 DBusMessage
*reply
= NULL
;
876 struct wpa_supplicant
*wpa_s
;
878 unsigned int i
= 0, num
= 0;
880 for (wpa_s
= global
->ifaces
; wpa_s
; wpa_s
= wpa_s
->next
)
883 paths
= os_zalloc(num
* sizeof(char*));
885 return dbus_message_new_error(message
, DBUS_ERROR_NO_MEMORY
,
889 for (wpa_s
= global
->ifaces
; wpa_s
; wpa_s
= wpa_s
->next
)
890 paths
[i
] = wpa_s
->dbus_new_path
;
892 reply
= wpas_dbus_simple_array_property_getter(message
,
893 DBUS_TYPE_OBJECT_PATH
,
902 * wpas_dbus_getter_eap_methods - Request supported EAP methods list
903 * @message: Pointer to incoming dbus message
904 * @nothing: not used argument. may be NULL or anything else
905 * Returns: The object paths array containing supported EAP methods
906 * represented by strings or DBus error on failure
908 * Getter for "EapMethods" property. Handles requests
909 * by dbus clients to return list of strings with supported EAP methods
911 DBusMessage
* wpas_dbus_getter_eap_methods(DBusMessage
*message
, void *nothing
)
913 DBusMessage
*reply
= NULL
;
915 size_t num_items
= 0;
917 eap_methods
= eap_get_names_as_string_array(&num_items
);
919 return dbus_message_new_error(message
, DBUS_ERROR_NO_MEMORY
,
923 reply
= wpas_dbus_simple_array_property_getter(message
,
925 eap_methods
, num_items
);
928 os_free(eap_methods
[--num_items
]);
929 os_free(eap_methods
);
934 static int wpas_dbus_get_scan_type(DBusMessage
*message
, DBusMessageIter
*var
,
935 char **type
, DBusMessage
**reply
)
937 if (dbus_message_iter_get_arg_type(var
) != DBUS_TYPE_STRING
) {
938 wpa_printf(MSG_DEBUG
, "wpas_dbus_handler_scan[dbus]: "
939 "Type must be a string");
940 *reply
= wpas_dbus_error_invalid_args(
941 message
, "Wrong Type value type. String required");
944 dbus_message_iter_get_basic(var
, type
);
949 static int wpas_dbus_get_scan_ssids(DBusMessage
*message
, DBusMessageIter
*var
,
950 struct wpa_driver_scan_params
*params
,
953 struct wpa_driver_scan_ssid
*ssids
= params
->ssids
;
954 size_t ssids_num
= 0;
956 DBusMessageIter array_iter
, sub_array_iter
;
960 if (dbus_message_iter_get_arg_type(var
) != DBUS_TYPE_ARRAY
) {
961 wpa_printf(MSG_DEBUG
, "wpas_dbus_handler_scan[dbus]: ssids "
962 "must be an array of arrays of bytes");
963 *reply
= wpas_dbus_error_invalid_args(
964 message
, "Wrong SSIDs value type. Array of arrays of "
969 dbus_message_iter_recurse(var
, &array_iter
);
971 if (dbus_message_iter_get_arg_type(&array_iter
) != DBUS_TYPE_ARRAY
||
972 dbus_message_iter_get_element_type(&array_iter
) != DBUS_TYPE_BYTE
)
974 wpa_printf(MSG_DEBUG
, "wpas_dbus_handler_scan[dbus]: ssids "
975 "must be an array of arrays of bytes");
976 *reply
= wpas_dbus_error_invalid_args(
977 message
, "Wrong SSIDs value type. Array of arrays of "
982 while (dbus_message_iter_get_arg_type(&array_iter
) == DBUS_TYPE_ARRAY
)
984 if (ssids_num
>= WPAS_MAX_SCAN_SSIDS
) {
985 wpa_printf(MSG_DEBUG
, "wpas_dbus_handler_scan[dbus]: "
986 "Too many ssids specified on scan dbus "
988 *reply
= wpas_dbus_error_invalid_args(
989 message
, "Too many ssids specified. Specify "
994 dbus_message_iter_recurse(&array_iter
, &sub_array_iter
);
996 dbus_message_iter_get_fixed_array(&sub_array_iter
, &val
, &len
);
998 dbus_message_iter_next(&array_iter
);
1002 ssid
= os_malloc(len
);
1004 wpa_printf(MSG_DEBUG
, "wpas_dbus_handler_scan[dbus]: "
1005 "out of memory. Cannot allocate memory for "
1007 *reply
= dbus_message_new_error(
1008 message
, DBUS_ERROR_NO_MEMORY
, NULL
);
1011 os_memcpy(ssid
, val
, len
);
1012 ssids
[ssids_num
].ssid
= ssid
;
1013 ssids
[ssids_num
].ssid_len
= len
;
1015 dbus_message_iter_next(&array_iter
);
1019 params
->num_ssids
= ssids_num
;
1024 static int wpas_dbus_get_scan_ies(DBusMessage
*message
, DBusMessageIter
*var
,
1025 struct wpa_driver_scan_params
*params
,
1026 DBusMessage
**reply
)
1028 u8
*ies
= NULL
, *nies
;
1030 DBusMessageIter array_iter
, sub_array_iter
;
1034 if (dbus_message_iter_get_arg_type(var
) != DBUS_TYPE_ARRAY
) {
1035 wpa_printf(MSG_DEBUG
, "wpas_dbus_handler_scan[dbus]: ies must "
1036 "be an array of arrays of bytes");
1037 *reply
= wpas_dbus_error_invalid_args(
1038 message
, "Wrong IEs value type. Array of arrays of "
1043 dbus_message_iter_recurse(var
, &array_iter
);
1045 if (dbus_message_iter_get_arg_type(&array_iter
) != DBUS_TYPE_ARRAY
||
1046 dbus_message_iter_get_element_type(&array_iter
) != DBUS_TYPE_BYTE
)
1048 wpa_printf(MSG_DEBUG
, "wpas_dbus_handler_scan[dbus]: ies must "
1049 "be an array of arrays of bytes");
1050 *reply
= wpas_dbus_error_invalid_args(
1051 message
, "Wrong IEs value type. Array required");
1055 while (dbus_message_iter_get_arg_type(&array_iter
) == DBUS_TYPE_ARRAY
)
1057 dbus_message_iter_recurse(&array_iter
, &sub_array_iter
);
1059 dbus_message_iter_get_fixed_array(&sub_array_iter
, &val
, &len
);
1061 dbus_message_iter_next(&array_iter
);
1065 nies
= os_realloc(ies
, ies_len
+ len
);
1067 wpa_printf(MSG_DEBUG
, "wpas_dbus_handler_scan[dbus]: "
1068 "out of memory. Cannot allocate memory for "
1071 *reply
= dbus_message_new_error(
1072 message
, DBUS_ERROR_NO_MEMORY
, NULL
);
1076 os_memcpy(ies
+ ies_len
, val
, len
);
1079 dbus_message_iter_next(&array_iter
);
1082 params
->extra_ies
= ies
;
1083 params
->extra_ies_len
= ies_len
;
1088 static int wpas_dbus_get_scan_channels(DBusMessage
*message
,
1089 DBusMessageIter
*var
,
1090 struct wpa_driver_scan_params
*params
,
1091 DBusMessage
**reply
)
1093 DBusMessageIter array_iter
, sub_array_iter
;
1094 int *freqs
= NULL
, *nfreqs
;
1097 if (dbus_message_iter_get_arg_type(var
) != DBUS_TYPE_ARRAY
) {
1098 wpa_printf(MSG_DEBUG
, "wpas_dbus_handler_scan[dbus]: "
1099 "Channels must be an array of structs");
1100 *reply
= wpas_dbus_error_invalid_args(
1101 message
, "Wrong Channels value type. Array of structs "
1106 dbus_message_iter_recurse(var
, &array_iter
);
1108 if (dbus_message_iter_get_arg_type(&array_iter
) != DBUS_TYPE_STRUCT
) {
1109 wpa_printf(MSG_DEBUG
,
1110 "wpas_dbus_handler_scan[dbus]: Channels must be an "
1111 "array of structs");
1112 *reply
= wpas_dbus_error_invalid_args(
1113 message
, "Wrong Channels value type. Array of structs "
1118 while (dbus_message_iter_get_arg_type(&array_iter
) == DBUS_TYPE_STRUCT
)
1122 dbus_message_iter_recurse(&array_iter
, &sub_array_iter
);
1124 if (dbus_message_iter_get_arg_type(&sub_array_iter
) !=
1126 wpa_printf(MSG_DEBUG
, "wpas_dbus_handler_scan[dbus]: "
1127 "Channel must by specified by struct of "
1129 dbus_message_iter_get_arg_type(
1131 *reply
= wpas_dbus_error_invalid_args(
1132 message
, "Wrong Channel struct. Two UINT32s "
1137 dbus_message_iter_get_basic(&sub_array_iter
, &freq
);
1139 if (!dbus_message_iter_next(&sub_array_iter
) ||
1140 dbus_message_iter_get_arg_type(&sub_array_iter
) !=
1142 wpa_printf(MSG_DEBUG
, "wpas_dbus_handler_scan[dbus]: "
1143 "Channel must by specified by struct of "
1145 *reply
= wpas_dbus_error_invalid_args(
1147 "Wrong Channel struct. Two UINT32s required");
1152 dbus_message_iter_get_basic(&sub_array_iter
, &width
);
1154 #define FREQS_ALLOC_CHUNK 32
1155 if (freqs_num
% FREQS_ALLOC_CHUNK
== 0) {
1156 nfreqs
= os_realloc(freqs
, sizeof(int) *
1157 (freqs_num
+ FREQS_ALLOC_CHUNK
));
1162 if (freqs
== NULL
) {
1163 wpa_printf(MSG_DEBUG
, "wpas_dbus_handler_scan[dbus]: "
1164 "out of memory. can't allocate memory for "
1166 *reply
= dbus_message_new_error(
1167 message
, DBUS_ERROR_NO_MEMORY
, NULL
);
1171 freqs
[freqs_num
] = freq
;
1174 dbus_message_iter_next(&array_iter
);
1177 nfreqs
= os_realloc(freqs
,
1178 sizeof(int) * (freqs_num
+ 1));
1182 if (freqs
== NULL
) {
1183 wpa_printf(MSG_DEBUG
, "wpas_dbus_handler_scan[dbus]: "
1184 "out of memory. Can't allocate memory for freqs");
1185 *reply
= dbus_message_new_error(
1186 message
, DBUS_ERROR_NO_MEMORY
, NULL
);
1189 freqs
[freqs_num
] = 0;
1191 params
->freqs
= freqs
;
1197 * wpas_dbus_handler_scan - Request a wireless scan on an interface
1198 * @message: Pointer to incoming dbus message
1199 * @wpa_s: wpa_supplicant structure for a network interface
1200 * Returns: NULL indicating success or DBus error message on failure
1202 * Handler function for "Scan" method call of a network device. Requests
1203 * that wpa_supplicant perform a wireless scan as soon as possible
1204 * on a particular wireless interface.
1206 DBusMessage
* wpas_dbus_handler_scan(DBusMessage
*message
,
1207 struct wpa_supplicant
*wpa_s
)
1209 DBusMessage
*reply
= NULL
;
1210 DBusMessageIter iter
, dict_iter
, entry_iter
, variant_iter
;
1211 char *key
= NULL
, *type
= NULL
;
1212 struct wpa_driver_scan_params params
;
1215 os_memset(¶ms
, 0, sizeof(params
));
1217 dbus_message_iter_init(message
, &iter
);
1219 dbus_message_iter_recurse(&iter
, &dict_iter
);
1221 while (dbus_message_iter_get_arg_type(&dict_iter
) ==
1222 DBUS_TYPE_DICT_ENTRY
) {
1223 dbus_message_iter_recurse(&dict_iter
, &entry_iter
);
1224 dbus_message_iter_get_basic(&entry_iter
, &key
);
1225 dbus_message_iter_next(&entry_iter
);
1226 dbus_message_iter_recurse(&entry_iter
, &variant_iter
);
1228 if (os_strcmp(key
, "Type") == 0) {
1229 if (wpas_dbus_get_scan_type(message
, &variant_iter
,
1232 } else if (os_strcmp(key
, "SSIDs") == 0) {
1233 if (wpas_dbus_get_scan_ssids(message
, &variant_iter
,
1234 ¶ms
, &reply
) < 0)
1236 } else if (os_strcmp(key
, "IEs") == 0) {
1237 if (wpas_dbus_get_scan_ies(message
, &variant_iter
,
1238 ¶ms
, &reply
) < 0)
1240 } else if (os_strcmp(key
, "Channels") == 0) {
1241 if (wpas_dbus_get_scan_channels(message
, &variant_iter
,
1242 ¶ms
, &reply
) < 0)
1245 wpa_printf(MSG_DEBUG
, "wpas_dbus_handler_scan[dbus]: "
1246 "Unknown argument %s", key
);
1247 reply
= wpas_dbus_error_invalid_args(message
, key
);
1251 dbus_message_iter_next(&dict_iter
);
1255 wpa_printf(MSG_DEBUG
, "wpas_dbus_handler_scan[dbus]: "
1256 "Scan type not specified");
1257 reply
= wpas_dbus_error_invalid_args(message
, key
);
1261 if (!os_strcmp(type
, "passive")) {
1262 if (params
.num_ssids
|| params
.extra_ies_len
) {
1263 wpa_printf(MSG_DEBUG
, "wpas_dbus_handler_scan[dbus]: "
1264 "SSIDs or IEs specified for passive scan.");
1265 reply
= wpas_dbus_error_invalid_args(
1266 message
, "You can specify only Channels in "
1269 } else if (params
.freqs
&& params
.freqs
[0]) {
1272 wpa_supplicant_trigger_scan(wpa_s
, ¶ms
);
1274 wpa_s
->scan_req
= 2;
1275 wpa_supplicant_req_scan(wpa_s
, 0, 0);
1277 } else if (!os_strcmp(type
, "active")) {
1278 wpa_supplicant_trigger_scan(wpa_s
, ¶ms
);
1280 wpa_printf(MSG_DEBUG
, "wpas_dbus_handler_scan[dbus]: "
1281 "Unknown scan type: %s", type
);
1282 reply
= wpas_dbus_error_invalid_args(message
,
1288 for (i
= 0; i
< WPAS_MAX_SCAN_SSIDS
; i
++)
1289 os_free((u8
*) params
.ssids
[i
].ssid
);
1290 os_free((u8
*) params
.extra_ies
);
1291 os_free(params
.freqs
);
1297 * wpas_dbus_handler_disconnect - Terminate the current connection
1298 * @message: Pointer to incoming dbus message
1299 * @wpa_s: wpa_supplicant structure for a network interface
1300 * Returns: NotConnected DBus error message if already not connected
1301 * or NULL otherwise.
1303 * Handler function for "Disconnect" method call of network interface.
1305 DBusMessage
* wpas_dbus_handler_disconnect(DBusMessage
*message
,
1306 struct wpa_supplicant
*wpa_s
)
1308 if (wpa_s
->current_ssid
!= NULL
) {
1309 wpa_s
->disconnected
= 1;
1310 wpa_supplicant_disassociate(wpa_s
, WLAN_REASON_DEAUTH_LEAVING
);
1315 return dbus_message_new_error(message
, WPAS_DBUS_ERROR_NOT_CONNECTED
,
1316 "This interface is not connected");
1321 * wpas_dbus_new_iface_add_network - Add a new configured network
1322 * @message: Pointer to incoming dbus message
1323 * @wpa_s: wpa_supplicant structure for a network interface
1324 * Returns: A dbus message containing the object path of the new network
1326 * Handler function for "AddNetwork" method call of a network interface.
1328 DBusMessage
* wpas_dbus_handler_add_network(DBusMessage
*message
,
1329 struct wpa_supplicant
*wpa_s
)
1331 DBusMessage
*reply
= NULL
;
1332 DBusMessageIter iter
;
1333 struct wpa_ssid
*ssid
= NULL
;
1336 path
= os_zalloc(WPAS_DBUS_OBJECT_PATH_MAX
);
1338 reply
= dbus_message_new_error(message
, DBUS_ERROR_NO_MEMORY
,
1343 dbus_message_iter_init(message
, &iter
);
1345 ssid
= wpa_config_add_network(wpa_s
->conf
);
1347 wpa_printf(MSG_ERROR
, "wpas_dbus_handler_add_network[dbus]: "
1348 "can't add new interface.");
1349 reply
= wpas_dbus_error_unknown_error(
1351 "wpa_supplicant could not add "
1352 "a network on this interface.");
1355 wpas_notify_network_added(wpa_s
, ssid
);
1357 wpa_config_set_network_defaults(ssid
);
1359 reply
= set_network_properties(message
, ssid
, &iter
);
1361 wpa_printf(MSG_DEBUG
, "wpas_dbus_handler_add_network[dbus]:"
1362 "control interface couldn't set network "
1367 /* Construct the object path for this network. */
1368 os_snprintf(path
, WPAS_DBUS_OBJECT_PATH_MAX
,
1369 "%s/" WPAS_DBUS_NEW_NETWORKS_PART
"/%d",
1370 wpa_s
->dbus_new_path
, ssid
->id
);
1372 reply
= dbus_message_new_method_return(message
);
1373 if (reply
== NULL
) {
1374 reply
= dbus_message_new_error(message
, DBUS_ERROR_NO_MEMORY
,
1378 if (!dbus_message_append_args(reply
, DBUS_TYPE_OBJECT_PATH
, &path
,
1379 DBUS_TYPE_INVALID
)) {
1380 dbus_message_unref(reply
);
1381 reply
= dbus_message_new_error(message
, DBUS_ERROR_NO_MEMORY
,
1391 wpas_notify_network_removed(wpa_s
, ssid
);
1392 wpa_config_remove_network(wpa_s
->conf
, ssid
->id
);
1400 * wpas_dbus_handler_remove_network - Remove a configured network
1401 * @message: Pointer to incoming dbus message
1402 * @wpa_s: wpa_supplicant structure for a network interface
1403 * Returns: NULL on success or dbus error on failure
1405 * Handler function for "RemoveNetwork" method call of a network interface.
1407 DBusMessage
* wpas_dbus_handler_remove_network(DBusMessage
*message
,
1408 struct wpa_supplicant
*wpa_s
)
1410 DBusMessage
*reply
= NULL
;
1412 char *iface
= NULL
, *net_id
= NULL
;
1414 struct wpa_ssid
*ssid
;
1416 dbus_message_get_args(message
, NULL
, DBUS_TYPE_OBJECT_PATH
, &op
,
1419 /* Extract the network ID and ensure the network */
1420 /* is actually a child of this interface */
1421 iface
= wpas_dbus_new_decompose_object_path(op
, &net_id
, NULL
);
1422 if (iface
== NULL
|| os_strcmp(iface
, wpa_s
->dbus_new_path
) != 0) {
1423 reply
= wpas_dbus_error_invalid_args(message
, op
);
1427 id
= strtoul(net_id
, NULL
, 10);
1428 if (errno
== EINVAL
) {
1429 reply
= wpas_dbus_error_invalid_args(message
, op
);
1433 ssid
= wpa_config_get_network(wpa_s
->conf
, id
);
1435 reply
= wpas_dbus_error_network_unknown(message
);
1439 wpas_notify_network_removed(wpa_s
, ssid
);
1441 if (wpa_config_remove_network(wpa_s
->conf
, id
) < 0) {
1442 wpa_printf(MSG_ERROR
,
1443 "wpas_dbus_handler_remove_network[dbus]: "
1444 "error occurred when removing network %d", id
);
1445 reply
= wpas_dbus_error_unknown_error(
1446 message
, "error removing the specified network on "
1451 if (ssid
== wpa_s
->current_ssid
)
1452 wpa_supplicant_disassociate(wpa_s
, WLAN_REASON_DEAUTH_LEAVING
);
1462 * wpas_dbus_handler_select_network - Attempt association with a network
1463 * @message: Pointer to incoming dbus message
1464 * @wpa_s: wpa_supplicant structure for a network interface
1465 * Returns: NULL on success or dbus error on failure
1467 * Handler function for "SelectNetwork" method call of network interface.
1469 DBusMessage
* wpas_dbus_handler_select_network(DBusMessage
*message
,
1470 struct wpa_supplicant
*wpa_s
)
1472 DBusMessage
*reply
= NULL
;
1474 char *iface
= NULL
, *net_id
= NULL
;
1476 struct wpa_ssid
*ssid
;
1478 dbus_message_get_args(message
, NULL
, DBUS_TYPE_OBJECT_PATH
, &op
,
1481 /* Extract the network ID and ensure the network */
1482 /* is actually a child of this interface */
1483 iface
= wpas_dbus_new_decompose_object_path(op
, &net_id
, NULL
);
1484 if (iface
== NULL
|| os_strcmp(iface
, wpa_s
->dbus_new_path
) != 0) {
1485 reply
= wpas_dbus_error_invalid_args(message
, op
);
1489 id
= strtoul(net_id
, NULL
, 10);
1490 if (errno
== EINVAL
) {
1491 reply
= wpas_dbus_error_invalid_args(message
, op
);
1495 ssid
= wpa_config_get_network(wpa_s
->conf
, id
);
1497 reply
= wpas_dbus_error_network_unknown(message
);
1501 /* Finally, associate with the network */
1502 wpa_supplicant_select_network(wpa_s
, ssid
);
1512 * wpas_dbus_handler_add_blob - Store named binary blob (ie, for certificates)
1513 * @message: Pointer to incoming dbus message
1514 * @wpa_s: %wpa_supplicant data structure
1515 * Returns: A dbus message containing an error on failure or NULL on success
1517 * Asks wpa_supplicant to internally store a binary blobs.
1519 DBusMessage
* wpas_dbus_handler_add_blob(DBusMessage
*message
,
1520 struct wpa_supplicant
*wpa_s
)
1522 DBusMessage
*reply
= NULL
;
1523 DBusMessageIter iter
, array_iter
;
1528 struct wpa_config_blob
*blob
= NULL
;
1530 dbus_message_iter_init(message
, &iter
);
1531 dbus_message_iter_get_basic(&iter
, &blob_name
);
1533 if (wpa_config_get_blob(wpa_s
->conf
, blob_name
)) {
1534 return dbus_message_new_error(message
,
1535 WPAS_DBUS_ERROR_BLOB_EXISTS
,
1539 dbus_message_iter_next(&iter
);
1540 dbus_message_iter_recurse(&iter
, &array_iter
);
1542 dbus_message_iter_get_fixed_array(&array_iter
, &blob_data
, &blob_len
);
1544 blob
= os_zalloc(sizeof(*blob
));
1546 reply
= dbus_message_new_error(message
, DBUS_ERROR_NO_MEMORY
,
1551 blob
->data
= os_malloc(blob_len
);
1553 reply
= dbus_message_new_error(message
, DBUS_ERROR_NO_MEMORY
,
1557 os_memcpy(blob
->data
, blob_data
, blob_len
);
1559 blob
->len
= blob_len
;
1560 blob
->name
= os_strdup(blob_name
);
1562 reply
= dbus_message_new_error(message
, DBUS_ERROR_NO_MEMORY
,
1567 wpa_config_set_blob(wpa_s
->conf
, blob
);
1568 wpas_notify_blob_added(wpa_s
, blob
->name
);
1574 os_free(blob
->name
);
1575 os_free(blob
->data
);
1583 * wpas_dbus_handler_get_blob - Get named binary blob (ie, for certificates)
1584 * @message: Pointer to incoming dbus message
1585 * @wpa_s: %wpa_supplicant data structure
1586 * Returns: A dbus message containing array of bytes (blob)
1588 * Gets one wpa_supplicant's binary blobs.
1590 DBusMessage
* wpas_dbus_handler_get_blob(DBusMessage
*message
,
1591 struct wpa_supplicant
*wpa_s
)
1593 DBusMessage
*reply
= NULL
;
1594 DBusMessageIter iter
, array_iter
;
1597 const struct wpa_config_blob
*blob
;
1599 dbus_message_get_args(message
, NULL
, DBUS_TYPE_STRING
, &blob_name
,
1602 blob
= wpa_config_get_blob(wpa_s
->conf
, blob_name
);
1604 return dbus_message_new_error(message
,
1605 WPAS_DBUS_ERROR_BLOB_UNKNOWN
,
1609 reply
= dbus_message_new_method_return(message
);
1611 reply
= dbus_message_new_error(message
, DBUS_ERROR_NO_MEMORY
,
1616 dbus_message_iter_init_append(reply
, &iter
);
1618 if (!dbus_message_iter_open_container(&iter
, DBUS_TYPE_ARRAY
,
1619 DBUS_TYPE_BYTE_AS_STRING
,
1621 dbus_message_unref(reply
);
1622 reply
= dbus_message_new_error(message
, DBUS_ERROR_NO_MEMORY
,
1627 if (!dbus_message_iter_append_fixed_array(&array_iter
, DBUS_TYPE_BYTE
,
1628 &(blob
->data
), blob
->len
)) {
1629 dbus_message_unref(reply
);
1630 reply
= dbus_message_new_error(message
, DBUS_ERROR_NO_MEMORY
,
1635 if (!dbus_message_iter_close_container(&iter
, &array_iter
)) {
1636 dbus_message_unref(reply
);
1637 reply
= dbus_message_new_error(message
, DBUS_ERROR_NO_MEMORY
,
1648 * wpas_remove_handler_remove_blob - Remove named binary blob
1649 * @message: Pointer to incoming dbus message
1650 * @wpa_s: %wpa_supplicant data structure
1651 * Returns: NULL on success or dbus error
1653 * Asks wpa_supplicant to internally remove a binary blobs.
1655 DBusMessage
* wpas_dbus_handler_remove_blob(DBusMessage
*message
,
1656 struct wpa_supplicant
*wpa_s
)
1658 DBusMessage
*reply
= NULL
;
1661 dbus_message_get_args(message
, NULL
, DBUS_TYPE_STRING
, &blob_name
,
1664 if (wpa_config_remove_blob(wpa_s
->conf
, blob_name
)) {
1665 return dbus_message_new_error(message
,
1666 WPAS_DBUS_ERROR_BLOB_UNKNOWN
,
1669 wpas_notify_blob_removed(wpa_s
, blob_name
);
1677 * wpas_dbus_getter_capabilities - Return interface capabilities
1678 * @message: Pointer to incoming dbus message
1679 * @wpa_s: wpa_supplicant structure for a network interface
1680 * Returns: A dbus message containing a dict of strings
1682 * Getter for "Capabilities" property of an interface.
1684 DBusMessage
* wpas_dbus_getter_capabilities(DBusMessage
*message
,
1685 struct wpa_supplicant
*wpa_s
)
1687 DBusMessage
*reply
= NULL
;
1688 struct wpa_driver_capa capa
;
1690 DBusMessageIter iter
, iter_dict
;
1691 DBusMessageIter iter_dict_entry
, iter_dict_val
, iter_array
,
1693 const char *scans
[] = { "active", "passive", "ssid" };
1694 const char *modes
[] = { "infrastructure", "ad-hoc", "ap" };
1695 int n
= sizeof(modes
) / sizeof(char *);
1697 if (message
== NULL
)
1698 reply
= dbus_message_new(DBUS_MESSAGE_TYPE_SIGNAL
);
1700 reply
= dbus_message_new_method_return(message
);
1704 dbus_message_iter_init_append(reply
, &iter
);
1705 if (!dbus_message_iter_open_container(&iter
, DBUS_TYPE_VARIANT
,
1706 "a{sv}", &variant_iter
))
1709 if (!wpa_dbus_dict_open_write(&variant_iter
, &iter_dict
))
1712 res
= wpa_drv_get_capa(wpa_s
, &capa
);
1714 /***** pairwise cipher */
1716 const char *args
[] = {"ccmp", "tkip", "none"};
1717 if (!wpa_dbus_dict_append_string_array(
1718 &iter_dict
, "Pairwise", args
,
1719 sizeof(args
) / sizeof(char*)))
1722 if (!wpa_dbus_dict_begin_string_array(&iter_dict
, "Pairwise",
1728 if (capa
.enc
& WPA_DRIVER_CAPA_ENC_CCMP
) {
1729 if (!wpa_dbus_dict_string_array_add_element(
1730 &iter_array
, "ccmp"))
1734 if (capa
.enc
& WPA_DRIVER_CAPA_ENC_TKIP
) {
1735 if (!wpa_dbus_dict_string_array_add_element(
1736 &iter_array
, "tkip"))
1740 if (capa
.key_mgmt
& WPA_DRIVER_CAPA_KEY_MGMT_WPA_NONE
) {
1741 if (!wpa_dbus_dict_string_array_add_element(
1742 &iter_array
, "none"))
1746 if (!wpa_dbus_dict_end_string_array(&iter_dict
,
1753 /***** group cipher */
1755 const char *args
[] = {
1756 "ccmp", "tkip", "wep104", "wep40"
1758 if (!wpa_dbus_dict_append_string_array(
1759 &iter_dict
, "Group", args
,
1760 sizeof(args
) / sizeof(char*)))
1763 if (!wpa_dbus_dict_begin_string_array(&iter_dict
, "Group",
1769 if (capa
.enc
& WPA_DRIVER_CAPA_ENC_CCMP
) {
1770 if (!wpa_dbus_dict_string_array_add_element(
1771 &iter_array
, "ccmp"))
1775 if (capa
.enc
& WPA_DRIVER_CAPA_ENC_TKIP
) {
1776 if (!wpa_dbus_dict_string_array_add_element(
1777 &iter_array
, "tkip"))
1781 if (capa
.enc
& WPA_DRIVER_CAPA_ENC_WEP104
) {
1782 if (!wpa_dbus_dict_string_array_add_element(
1783 &iter_array
, "wep104"))
1787 if (capa
.enc
& WPA_DRIVER_CAPA_ENC_WEP40
) {
1788 if (!wpa_dbus_dict_string_array_add_element(
1789 &iter_array
, "wep40"))
1793 if (!wpa_dbus_dict_end_string_array(&iter_dict
,
1800 /***** key management */
1802 const char *args
[] = {
1803 "wpa-psk", "wpa-eap", "ieee8021x", "wpa-none",
1806 #endif /* CONFIG_WPS */
1809 if (!wpa_dbus_dict_append_string_array(
1810 &iter_dict
, "KeyMgmt", args
,
1811 sizeof(args
) / sizeof(char*)))
1814 if (!wpa_dbus_dict_begin_string_array(&iter_dict
, "KeyMgmt",
1820 if (!wpa_dbus_dict_string_array_add_element(&iter_array
,
1824 if (!wpa_dbus_dict_string_array_add_element(&iter_array
,
1828 if (capa
.key_mgmt
& (WPA_DRIVER_CAPA_KEY_MGMT_WPA
|
1829 WPA_DRIVER_CAPA_KEY_MGMT_WPA2
)) {
1830 if (!wpa_dbus_dict_string_array_add_element(
1831 &iter_array
, "wpa-eap"))
1835 if (capa
.key_mgmt
& (WPA_DRIVER_CAPA_KEY_MGMT_WPA_PSK
|
1836 WPA_DRIVER_CAPA_KEY_MGMT_WPA2_PSK
)) {
1837 if (!wpa_dbus_dict_string_array_add_element(
1838 &iter_array
, "wpa-psk"))
1842 if (capa
.key_mgmt
& WPA_DRIVER_CAPA_KEY_MGMT_WPA_NONE
) {
1843 if (!wpa_dbus_dict_string_array_add_element(
1844 &iter_array
, "wpa-none"))
1850 if (!wpa_dbus_dict_string_array_add_element(&iter_array
,
1853 #endif /* CONFIG_WPS */
1855 if (!wpa_dbus_dict_end_string_array(&iter_dict
,
1862 /***** WPA protocol */
1864 const char *args
[] = { "rsn", "wpa" };
1865 if (!wpa_dbus_dict_append_string_array(
1866 &iter_dict
, "Protocol", args
,
1867 sizeof(args
) / sizeof(char*)))
1870 if (!wpa_dbus_dict_begin_string_array(&iter_dict
, "Protocol",
1876 if (capa
.key_mgmt
& (WPA_DRIVER_CAPA_KEY_MGMT_WPA2
|
1877 WPA_DRIVER_CAPA_KEY_MGMT_WPA2_PSK
)) {
1878 if (!wpa_dbus_dict_string_array_add_element(
1879 &iter_array
, "rsn"))
1883 if (capa
.key_mgmt
& (WPA_DRIVER_CAPA_KEY_MGMT_WPA
|
1884 WPA_DRIVER_CAPA_KEY_MGMT_WPA_PSK
)) {
1885 if (!wpa_dbus_dict_string_array_add_element(
1886 &iter_array
, "wpa"))
1890 if (!wpa_dbus_dict_end_string_array(&iter_dict
,
1899 const char *args
[] = { "open", "shared", "leap" };
1900 if (!wpa_dbus_dict_append_string_array(
1901 &iter_dict
, "AuthAlg", args
,
1902 sizeof(args
) / sizeof(char*)))
1905 if (!wpa_dbus_dict_begin_string_array(&iter_dict
, "AuthAlg",
1911 if (capa
.auth
& (WPA_DRIVER_AUTH_OPEN
)) {
1912 if (!wpa_dbus_dict_string_array_add_element(
1913 &iter_array
, "open"))
1917 if (capa
.auth
& (WPA_DRIVER_AUTH_SHARED
)) {
1918 if (!wpa_dbus_dict_string_array_add_element(
1919 &iter_array
, "shared"))
1923 if (capa
.auth
& (WPA_DRIVER_AUTH_LEAP
)) {
1924 if (!wpa_dbus_dict_string_array_add_element(
1925 &iter_array
, "leap"))
1929 if (!wpa_dbus_dict_end_string_array(&iter_dict
,
1937 if (!wpa_dbus_dict_append_string_array(&iter_dict
, "Scan", scans
,
1938 sizeof(scans
) / sizeof(char *)))
1942 if (res
< 0 || !(capa
.flags
& WPA_DRIVER_FLAGS_AP
))
1943 n
--; /* exclude ap mode if it is not supported by the driver */
1944 if (!wpa_dbus_dict_append_string_array(&iter_dict
, "Modes", modes
, n
))
1947 if (!wpa_dbus_dict_close_write(&variant_iter
, &iter_dict
))
1949 if (!dbus_message_iter_close_container(&iter
, &variant_iter
))
1956 dbus_message_unref(reply
);
1958 return dbus_message_new_error(message
, DBUS_ERROR_NO_MEMORY
, NULL
);
1963 * wpas_dbus_getter_state - Get interface state
1964 * @message: Pointer to incoming dbus message
1965 * @wpa_s: wpa_supplicant structure for a network interface
1966 * Returns: A dbus message containing a STRING representing the current
1969 * Getter for "State" property.
1971 DBusMessage
* wpas_dbus_getter_state(DBusMessage
*message
,
1972 struct wpa_supplicant
*wpa_s
)
1974 DBusMessage
*reply
= NULL
;
1975 const char *str_state
;
1976 char *state_ls
, *tmp
;
1978 str_state
= wpa_supplicant_state_txt(wpa_s
->wpa_state
);
1980 /* make state string lowercase to fit new DBus API convention
1982 state_ls
= tmp
= os_strdup(str_state
);
1984 return dbus_message_new_error(message
, DBUS_ERROR_NO_MEMORY
,
1988 *tmp
= tolower(*tmp
);
1992 reply
= wpas_dbus_simple_property_getter(message
, DBUS_TYPE_STRING
,
2002 * wpas_dbus_new_iface_get_scanning - Get interface scanning state
2003 * @message: Pointer to incoming dbus message
2004 * @wpa_s: wpa_supplicant structure for a network interface
2005 * Returns: A dbus message containing whether the interface is scanning
2007 * Getter for "scanning" property.
2009 DBusMessage
* wpas_dbus_getter_scanning(DBusMessage
*message
,
2010 struct wpa_supplicant
*wpa_s
)
2012 dbus_bool_t scanning
= wpa_s
->scanning
? TRUE
: FALSE
;
2013 return wpas_dbus_simple_property_getter(message
, DBUS_TYPE_BOOLEAN
,
2019 * wpas_dbus_getter_ap_scan - Control roaming mode
2020 * @message: Pointer to incoming dbus message
2021 * @wpa_s: wpa_supplicant structure for a network interface
2022 * Returns: A message containong value of ap_scan variable
2024 * Getter function for "ApScan" property.
2026 DBusMessage
* wpas_dbus_getter_ap_scan(DBusMessage
*message
,
2027 struct wpa_supplicant
*wpa_s
)
2029 dbus_uint32_t ap_scan
= wpa_s
->conf
->ap_scan
;
2030 return wpas_dbus_simple_property_getter(message
, DBUS_TYPE_UINT32
,
2036 * wpas_dbus_setter_ap_scan - Control roaming mode
2037 * @message: Pointer to incoming dbus message
2038 * @wpa_s: wpa_supplicant structure for a network interface
2041 * Setter function for "ApScan" property.
2043 DBusMessage
* wpas_dbus_setter_ap_scan(DBusMessage
*message
,
2044 struct wpa_supplicant
*wpa_s
)
2046 DBusMessage
*reply
= NULL
;
2047 dbus_uint32_t ap_scan
;
2049 reply
= wpas_dbus_simple_property_setter(message
, DBUS_TYPE_UINT32
,
2054 if (wpa_supplicant_set_ap_scan(wpa_s
, ap_scan
)) {
2055 return wpas_dbus_error_invalid_args(
2056 message
, "ap_scan must equal 0, 1 or 2");
2063 * wpas_dbus_getter_ifname - Get interface name
2064 * @message: Pointer to incoming dbus message
2065 * @wpa_s: wpa_supplicant structure for a network interface
2066 * Returns: A dbus message containing a name of network interface
2067 * associated with with wpa_s
2069 * Getter for "Ifname" property.
2071 DBusMessage
* wpas_dbus_getter_ifname(DBusMessage
*message
,
2072 struct wpa_supplicant
*wpa_s
)
2074 const char *ifname
= wpa_s
->ifname
;
2075 return wpas_dbus_simple_property_getter(message
, DBUS_TYPE_STRING
,
2081 * wpas_dbus_getter_driver - Get interface name
2082 * @message: Pointer to incoming dbus message
2083 * @wpa_s: wpa_supplicant structure for a network interface
2084 * Returns: A dbus message containing a name of network interface
2085 * driver associated with with wpa_s
2087 * Getter for "Driver" property.
2089 DBusMessage
* wpas_dbus_getter_driver(DBusMessage
*message
,
2090 struct wpa_supplicant
*wpa_s
)
2094 if (wpa_s
->driver
== NULL
|| wpa_s
->driver
->name
== NULL
) {
2095 wpa_printf(MSG_DEBUG
, "wpas_dbus_getter_driver[dbus]: "
2096 "wpa_s has no driver set");
2097 return wpas_dbus_error_unknown_error(message
, NULL
);
2100 driver
= wpa_s
->driver
->name
;
2101 return wpas_dbus_simple_property_getter(message
, DBUS_TYPE_STRING
,
2107 * wpas_dbus_getter_current_bss - Get current bss object path
2108 * @message: Pointer to incoming dbus message
2109 * @wpa_s: wpa_supplicant structure for a network interface
2110 * Returns: A dbus message containing a DBus object path to
2113 * Getter for "CurrentBSS" property.
2115 DBusMessage
* wpas_dbus_getter_current_bss(DBusMessage
*message
,
2116 struct wpa_supplicant
*wpa_s
)
2118 DBusMessage
*reply
= NULL
;
2119 char *bss_obj_path
= os_zalloc(WPAS_DBUS_OBJECT_PATH_MAX
);
2120 struct wpa_bss
*bss
= NULL
;
2122 if (bss_obj_path
== NULL
)
2123 return dbus_message_new_error(message
, DBUS_ERROR_NO_MEMORY
,
2126 /* TODO: store current BSS or BSS id in wpa_s */
2127 if (!is_zero_ether_addr(wpa_s
->bssid
))
2128 bss
= wpa_bss_get_bssid(wpa_s
, wpa_s
->bssid
);
2131 os_snprintf(bss_obj_path
, WPAS_DBUS_OBJECT_PATH_MAX
,
2132 "%s/" WPAS_DBUS_NEW_BSSIDS_PART
"/%u",
2133 wpa_s
->dbus_new_path
, bss
->id
);
2135 os_snprintf(bss_obj_path
, WPAS_DBUS_OBJECT_PATH_MAX
, "/");
2137 reply
= wpas_dbus_simple_property_getter(message
,
2138 DBUS_TYPE_OBJECT_PATH
,
2141 os_free(bss_obj_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
)
2158 DBusMessage
*reply
= NULL
;
2159 char *net_obj_path
= os_zalloc(WPAS_DBUS_OBJECT_PATH_MAX
);
2161 if (net_obj_path
== NULL
)
2162 return dbus_message_new_error(message
, DBUS_ERROR_NO_MEMORY
,
2165 if (wpa_s
->current_ssid
)
2166 os_snprintf(net_obj_path
, WPAS_DBUS_OBJECT_PATH_MAX
,
2167 "%s/" WPAS_DBUS_NEW_NETWORKS_PART
"/%u",
2168 wpa_s
->dbus_new_path
, wpa_s
->current_ssid
->id
);
2170 os_snprintf(net_obj_path
, WPAS_DBUS_OBJECT_PATH_MAX
, "/");
2172 reply
= wpas_dbus_simple_property_getter(message
,
2173 DBUS_TYPE_OBJECT_PATH
,
2176 os_free(net_obj_path
);
2182 * wpas_dbus_getter_bridge_ifname - Get interface name
2183 * @message: Pointer to incoming dbus message
2184 * @wpa_s: wpa_supplicant structure for a network interface
2185 * Returns: A dbus message containing a name of bridge network
2186 * interface associated with with wpa_s
2188 * Getter for "BridgeIfname" property.
2190 DBusMessage
* wpas_dbus_getter_bridge_ifname(DBusMessage
*message
,
2191 struct wpa_supplicant
*wpa_s
)
2193 const char *bridge_ifname
= NULL
;
2195 bridge_ifname
= wpa_s
->bridge_ifname
;
2196 if (bridge_ifname
== NULL
) {
2197 wpa_printf(MSG_ERROR
, "wpas_dbus_getter_bridge_ifname[dbus]: "
2198 "wpa_s has no bridge interface name set");
2199 return wpas_dbus_error_unknown_error(message
, NULL
);
2202 return wpas_dbus_simple_property_getter(message
, DBUS_TYPE_STRING
,
2208 * wpas_dbus_getter_bsss - Get array of BSSs objects
2209 * @message: Pointer to incoming dbus message
2210 * @wpa_s: wpa_supplicant structure for a network interface
2211 * Returns: a dbus message containing an array of all known BSS objects
2214 * Getter for "BSSs" property.
2216 DBusMessage
* wpas_dbus_getter_bsss(DBusMessage
*message
,
2217 struct wpa_supplicant
*wpa_s
)
2219 DBusMessage
*reply
= NULL
;
2220 struct wpa_bss
*bss
;
2224 paths
= os_zalloc(wpa_s
->num_bss
* sizeof(char *));
2226 return dbus_message_new_error(message
, DBUS_ERROR_NO_MEMORY
,
2230 /* Loop through scan results and append each result's object path */
2231 dl_list_for_each(bss
, &wpa_s
->bss_id
, struct wpa_bss
, list_id
) {
2232 paths
[i
] = os_zalloc(WPAS_DBUS_OBJECT_PATH_MAX
);
2233 if (paths
[i
] == NULL
) {
2234 reply
= dbus_message_new_error(message
,
2235 DBUS_ERROR_NO_MEMORY
,
2239 /* Construct the object path for this BSS. */
2240 os_snprintf(paths
[i
++], WPAS_DBUS_OBJECT_PATH_MAX
,
2241 "%s/" WPAS_DBUS_NEW_BSSIDS_PART
"/%u",
2242 wpa_s
->dbus_new_path
, bss
->id
);
2245 reply
= wpas_dbus_simple_array_property_getter(message
,
2246 DBUS_TYPE_OBJECT_PATH
,
2247 paths
, wpa_s
->num_bss
);
2251 os_free(paths
[--i
]);
2258 * wpas_dbus_getter_networks - Get array of networks objects
2259 * @message: Pointer to incoming dbus message
2260 * @wpa_s: wpa_supplicant structure for a network interface
2261 * Returns: a dbus message containing an array of all configured
2262 * networks dbus object paths.
2264 * Getter for "Networks" property.
2266 DBusMessage
* wpas_dbus_getter_networks(DBusMessage
*message
,
2267 struct wpa_supplicant
*wpa_s
)
2269 DBusMessage
*reply
= NULL
;
2270 struct wpa_ssid
*ssid
;
2272 unsigned int i
= 0, num
= 0;
2274 if (wpa_s
->conf
== NULL
) {
2275 wpa_printf(MSG_ERROR
, "wpas_dbus_getter_networks[dbus]: "
2276 "An error occurred getting networks list.");
2277 return wpas_dbus_error_unknown_error(message
, NULL
);
2280 for (ssid
= wpa_s
->conf
->ssid
; ssid
; ssid
= ssid
->next
)
2283 paths
= os_zalloc(num
* sizeof(char *));
2285 return dbus_message_new_error(message
, DBUS_ERROR_NO_MEMORY
,
2289 /* Loop through configured networks and append object path of each */
2290 for (ssid
= wpa_s
->conf
->ssid
; ssid
; ssid
= ssid
->next
) {
2291 paths
[i
] = os_zalloc(WPAS_DBUS_OBJECT_PATH_MAX
);
2292 if (paths
[i
] == NULL
) {
2293 reply
= dbus_message_new_error(message
,
2294 DBUS_ERROR_NO_MEMORY
,
2299 /* Construct the object path for this network. */
2300 os_snprintf(paths
[i
++], WPAS_DBUS_OBJECT_PATH_MAX
,
2301 "%s/" WPAS_DBUS_NEW_NETWORKS_PART
"/%d",
2302 wpa_s
->dbus_new_path
, ssid
->id
);
2305 reply
= wpas_dbus_simple_array_property_getter(message
,
2306 DBUS_TYPE_OBJECT_PATH
,
2311 os_free(paths
[--i
]);
2318 * wpas_dbus_getter_blobs - Get all blobs defined for this interface
2319 * @message: Pointer to incoming dbus message
2320 * @wpa_s: wpa_supplicant structure for a network interface
2321 * Returns: a dbus message containing a dictionary of pairs (blob_name, blob)
2323 * Getter for "Blobs" property.
2325 DBusMessage
* wpas_dbus_getter_blobs(DBusMessage
*message
,
2326 struct wpa_supplicant
*wpa_s
)
2328 DBusMessage
*reply
= NULL
;
2329 DBusMessageIter iter
, variant_iter
, dict_iter
, entry_iter
, array_iter
;
2330 struct wpa_config_blob
*blob
;
2332 if (message
== NULL
)
2333 reply
= dbus_message_new(DBUS_MESSAGE_TYPE_SIGNAL
);
2335 reply
= dbus_message_new_method_return(message
);
2337 return dbus_message_new_error(message
, DBUS_ERROR_NO_MEMORY
,
2340 dbus_message_iter_init_append(reply
, &iter
);
2342 if (!dbus_message_iter_open_container(&iter
, DBUS_TYPE_VARIANT
,
2343 "a{say}", &variant_iter
) ||
2344 !dbus_message_iter_open_container(&variant_iter
, DBUS_TYPE_ARRAY
,
2345 "{say}", &dict_iter
)) {
2346 dbus_message_unref(reply
);
2347 return dbus_message_new_error(message
, DBUS_ERROR_NO_MEMORY
,
2351 blob
= wpa_s
->conf
->blobs
;
2353 if (!dbus_message_iter_open_container(&dict_iter
,
2354 DBUS_TYPE_DICT_ENTRY
,
2355 NULL
, &entry_iter
) ||
2356 !dbus_message_iter_append_basic(&entry_iter
,
2359 !dbus_message_iter_open_container(&entry_iter
,
2361 DBUS_TYPE_BYTE_AS_STRING
,
2363 !dbus_message_iter_append_fixed_array(&array_iter
,
2367 !dbus_message_iter_close_container(&entry_iter
,
2369 !dbus_message_iter_close_container(&dict_iter
,
2371 dbus_message_unref(reply
);
2372 return dbus_message_new_error(message
,
2373 DBUS_ERROR_NO_MEMORY
,
2380 if (!dbus_message_iter_close_container(&variant_iter
, &dict_iter
) ||
2381 !dbus_message_iter_close_container(&iter
, &variant_iter
)) {
2382 dbus_message_unref(reply
);
2383 return dbus_message_new_error(message
, DBUS_ERROR_NO_MEMORY
,
2392 * wpas_dbus_getter_bss_bssid - Return the BSSID of a BSS
2393 * @message: Pointer to incoming dbus message
2394 * @bss: a pair of interface describing structure and bss's id
2395 * Returns: a dbus message containing the bssid for the requested bss
2397 * Getter for "BSSID" property.
2399 DBusMessage
* wpas_dbus_getter_bss_bssid(DBusMessage
*message
,
2400 struct bss_handler_args
*bss
)
2402 struct wpa_bss
*res
= wpa_bss_get_id(bss
->wpa_s
, bss
->id
);
2405 wpa_printf(MSG_ERROR
, "wpas_dbus_getter_bss_bssid[dbus]: no "
2406 "bss with id %d found", bss
->id
);
2410 return wpas_dbus_simple_array_property_getter(message
, DBUS_TYPE_BYTE
,
2411 res
->bssid
, ETH_ALEN
);
2416 * wpas_dbus_getter_bss_ssid - Return the SSID of a BSS
2417 * @message: Pointer to incoming dbus message
2418 * @bss: a pair of interface describing structure and bss's id
2419 * Returns: a dbus message containing the ssid for the requested bss
2421 * Getter for "SSID" property.
2423 DBusMessage
* wpas_dbus_getter_bss_ssid(DBusMessage
*message
,
2424 struct bss_handler_args
*bss
)
2426 struct wpa_bss
*res
= wpa_bss_get_id(bss
->wpa_s
, bss
->id
);
2429 wpa_printf(MSG_ERROR
, "wpas_dbus_getter_bss_ssid[dbus]: no "
2430 "bss with id %d found", bss
->id
);
2434 return wpas_dbus_simple_array_property_getter(message
, DBUS_TYPE_BYTE
,
2441 * wpas_dbus_getter_bss_privacy - Return the privacy flag of a BSS
2442 * @message: Pointer to incoming dbus message
2443 * @bss: a pair of interface describing structure and bss's id
2444 * Returns: a dbus message containing the privacy flag value of requested bss
2446 * Getter for "Privacy" property.
2448 DBusMessage
* wpas_dbus_getter_bss_privacy(DBusMessage
*message
,
2449 struct bss_handler_args
*bss
)
2451 struct wpa_bss
*res
= wpa_bss_get_id(bss
->wpa_s
, bss
->id
);
2452 dbus_bool_t privacy
;
2455 wpa_printf(MSG_ERROR
, "wpas_dbus_getter_bss_privacy[dbus]: no "
2456 "bss with id %d found", bss
->id
);
2460 privacy
= res
->caps
&& IEEE80211_CAP_PRIVACY
? TRUE
: FALSE
;
2461 return wpas_dbus_simple_property_getter(message
, DBUS_TYPE_BOOLEAN
,
2467 * wpas_dbus_getter_bss_mode - Return the mode of a BSS
2468 * @message: Pointer to incoming dbus message
2469 * @bss: a pair of interface describing structure and bss's id
2470 * Returns: a dbus message containing the mode of requested bss
2472 * Getter for "Mode" property.
2474 DBusMessage
* wpas_dbus_getter_bss_mode(DBusMessage
*message
,
2475 struct bss_handler_args
*bss
)
2477 struct wpa_bss
*res
= wpa_bss_get_id(bss
->wpa_s
, bss
->id
);
2481 wpa_printf(MSG_ERROR
, "wpas_dbus_getter_bss_mode[dbus]: no "
2482 "bss with id %d found", bss
->id
);
2486 if (res
->caps
& IEEE80211_CAP_IBSS
)
2489 mode
= "infrastructure";
2491 return wpas_dbus_simple_property_getter(message
, DBUS_TYPE_STRING
,
2497 * wpas_dbus_getter_bss_level - Return the signal strength of a BSS
2498 * @message: Pointer to incoming dbus message
2499 * @bss: a pair of interface describing structure and bss's id
2500 * Returns: a dbus message containing the signal strength of requested bss
2502 * Getter for "Level" property.
2504 DBusMessage
* wpas_dbus_getter_bss_signal(DBusMessage
*message
,
2505 struct bss_handler_args
*bss
)
2507 struct wpa_bss
*res
= wpa_bss_get_id(bss
->wpa_s
, bss
->id
);
2510 wpa_printf(MSG_ERROR
, "wpas_dbus_getter_bss_signal[dbus]: no "
2511 "bss with id %d found", bss
->id
);
2515 return wpas_dbus_simple_property_getter(message
, DBUS_TYPE_INT16
,
2521 * wpas_dbus_getter_bss_frequency - Return the frequency of a BSS
2522 * @message: Pointer to incoming dbus message
2523 * @bss: a pair of interface describing structure and bss's id
2524 * Returns: a dbus message containing the frequency of requested bss
2526 * Getter for "Frequency" property.
2528 DBusMessage
* wpas_dbus_getter_bss_frequency(DBusMessage
*message
,
2529 struct bss_handler_args
*bss
)
2531 struct wpa_bss
*res
= wpa_bss_get_id(bss
->wpa_s
, bss
->id
);
2534 wpa_printf(MSG_ERROR
, "wpas_dbus_getter_bss_frequency[dbus]: "
2535 "no bss with id %d found", bss
->id
);
2539 return wpas_dbus_simple_property_getter(message
, DBUS_TYPE_UINT16
,
2545 * wpas_dbus_getter_bss_max_rate - Return the maximal rate of a BSS
2546 * @message: Pointer to incoming dbus message
2547 * @bss: a pair of interface describing structure and bss's id
2548 * Returns: a dbus message containing the maximal data rate of requested bss
2550 * Getter for "MaxRate" property.
2552 DBusMessage
* wpas_dbus_getter_bss_max_rate(DBusMessage
*message
,
2553 struct bss_handler_args
*bss
)
2555 struct wpa_bss
*res
= wpa_bss_get_id(bss
->wpa_s
, bss
->id
);
2559 wpa_printf(MSG_ERROR
, "wpas_dbus_getter_bss_max_rate[dbus]: "
2560 "no bss with id %d found", bss
->id
);
2564 max_rate
= wpa_bss_get_max_rate(res
);
2565 return wpas_dbus_simple_property_getter(message
, DBUS_TYPE_UINT16
,
2571 * wpas_dbus_getter_bss_wpaie - Return the WPA IE of a BSS
2572 * @message: Pointer to incoming dbus message
2573 * @bss: a pair of interface describing structure and bss's id
2574 * Returns: a dbus message containing the WPA information elements
2577 * Getter for "WPAIE" property.
2579 DBusMessage
* wpas_dbus_getter_bss_wpaie(DBusMessage
*message
,
2580 struct bss_handler_args
*bss
)
2582 struct wpa_bss
*res
= wpa_bss_get_id(bss
->wpa_s
, bss
->id
);
2586 wpa_printf(MSG_ERROR
, "wpas_dbus_getter_bss_wpaie[dbus]: no "
2587 "bss with id %d found", bss
->id
);
2591 ie
= wpa_bss_get_vendor_ie(res
, WPA_IE_VENDOR_TYPE
);
2594 return wpas_dbus_simple_array_property_getter(message
, DBUS_TYPE_BYTE
,
2600 * wpas_dbus_getter_bss_rsnie - Return the RSN IE of a BSS
2601 * @message: Pointer to incoming dbus message
2602 * @bss: a pair of interface describing structure and bss's id
2603 * Returns: a dbus message containing the RSN information elements
2606 * Getter for "RSNIE" property.
2608 DBusMessage
* wpas_dbus_getter_bss_rsnie(DBusMessage
*message
,
2609 struct bss_handler_args
*bss
)
2611 struct wpa_bss
*res
= wpa_bss_get_id(bss
->wpa_s
, bss
->id
);
2615 wpa_printf(MSG_ERROR
, "wpas_dbus_getter_bss_rsnie[dbus]: no "
2616 "bss with id %d found", bss
->id
);
2620 ie
= wpa_bss_get_ie(res
, WLAN_EID_RSN
);
2623 return wpas_dbus_simple_array_property_getter(message
, DBUS_TYPE_BYTE
,
2629 * wpas_dbus_getter_bss_wpsie - Return the WPS IE of a BSS
2630 * @message: Pointer to incoming dbus message
2631 * @bss: a pair of interface describing structure and bss's id
2632 * Returns: a dbus message containing the WPS information elements
2635 * Getter for "WPSIE" property.
2637 DBusMessage
* wpas_dbus_getter_bss_wpsie(DBusMessage
*message
,
2638 struct bss_handler_args
*bss
)
2640 struct wpa_bss
*res
= wpa_bss_get_id(bss
->wpa_s
, bss
->id
);
2644 wpa_printf(MSG_ERROR
, "wpas_dbus_getter_bss_wpsie[dbus]: no "
2645 "bss with id %d found", bss
->id
);
2649 ie
= wpa_bss_get_vendor_ie(res
, WPS_IE_VENDOR_TYPE
);
2652 return wpas_dbus_simple_array_property_getter(message
, DBUS_TYPE_BYTE
,
2658 * wpas_dbus_getter_enabled - Check whether network is enabled or disabled
2659 * @message: Pointer to incoming dbus message
2660 * @wpas_dbus_setter_enabled: wpa_supplicant structure for a network interface
2661 * and wpa_ssid structure for a configured network
2662 * Returns: DBus message with boolean indicating state of configured network
2663 * or DBus error on failure
2665 * Getter for "enabled" property of a configured network.
2667 DBusMessage
* wpas_dbus_getter_enabled(DBusMessage
*message
,
2668 struct network_handler_args
*net
)
2670 dbus_bool_t enabled
= net
->ssid
->disabled
? FALSE
: TRUE
;
2671 return wpas_dbus_simple_property_getter(message
, DBUS_TYPE_BOOLEAN
,
2677 * wpas_dbus_setter_enabled - Mark a configured network as enabled or disabled
2678 * @message: Pointer to incoming dbus message
2679 * @wpas_dbus_setter_enabled: wpa_supplicant structure for a network interface
2680 * and wpa_ssid structure for a configured network
2681 * Returns: NULL indicating success or DBus error on failure
2683 * Setter for "Enabled" property of a configured network.
2685 DBusMessage
* wpas_dbus_setter_enabled(DBusMessage
*message
,
2686 struct network_handler_args
*net
)
2688 DBusMessage
*reply
= NULL
;
2690 struct wpa_supplicant
*wpa_s
;
2691 struct wpa_ssid
*ssid
;
2695 reply
= wpas_dbus_simple_property_setter(message
, DBUS_TYPE_BOOLEAN
,
2705 wpa_supplicant_enable_network(wpa_s
, ssid
);
2707 wpa_supplicant_disable_network(wpa_s
, ssid
);
2714 * wpas_dbus_getter_network_properties - Get options for a configured network
2715 * @message: Pointer to incoming dbus message
2716 * @net: wpa_supplicant structure for a network interface and
2717 * wpa_ssid structure for a configured network
2718 * Returns: DBus message with network properties or DBus error on failure
2720 * Getter for "Properties" property of a configured network.
2722 DBusMessage
* wpas_dbus_getter_network_properties(
2723 DBusMessage
*message
, struct network_handler_args
*net
)
2725 DBusMessage
*reply
= NULL
;
2726 DBusMessageIter iter
, variant_iter
, dict_iter
;
2728 char **props
= wpa_config_get_all(net
->ssid
, 0);
2730 return dbus_message_new_error(message
, DBUS_ERROR_NO_MEMORY
,
2733 if (message
== NULL
)
2734 reply
= dbus_message_new(DBUS_MESSAGE_TYPE_SIGNAL
);
2736 reply
= dbus_message_new_method_return(message
);
2738 reply
= dbus_message_new_error(message
, DBUS_ERROR_NO_MEMORY
,
2743 dbus_message_iter_init_append(reply
, &iter
);
2745 if (!dbus_message_iter_open_container(&iter
, DBUS_TYPE_VARIANT
,
2746 "a{sv}", &variant_iter
) ||
2747 !wpa_dbus_dict_open_write(&variant_iter
, &dict_iter
)) {
2748 dbus_message_unref(reply
);
2749 reply
= dbus_message_new_error(message
, DBUS_ERROR_NO_MEMORY
,
2756 if (!wpa_dbus_dict_append_string(&dict_iter
, *iterator
,
2758 dbus_message_unref(reply
);
2759 reply
= dbus_message_new_error(message
,
2760 DBUS_ERROR_NO_MEMORY
,
2768 if (!wpa_dbus_dict_close_write(&variant_iter
, &dict_iter
) ||
2769 !dbus_message_iter_close_container(&iter
, &variant_iter
)) {
2770 dbus_message_unref(reply
);
2771 reply
= dbus_message_new_error(message
, DBUS_ERROR_NO_MEMORY
,
2788 * wpas_dbus_setter_network_properties - Set options for a configured network
2789 * @message: Pointer to incoming dbus message
2790 * @net: wpa_supplicant structure for a network interface and
2791 * wpa_ssid structure for a configured network
2792 * Returns: NULL indicating success or DBus error on failure
2794 * Setter for "Properties" property of a configured network.
2796 DBusMessage
* wpas_dbus_setter_network_properties(
2797 DBusMessage
*message
, struct network_handler_args
*net
)
2799 struct wpa_ssid
*ssid
= net
->ssid
;
2801 DBusMessage
*reply
= NULL
;
2802 DBusMessageIter iter
, variant_iter
;
2804 dbus_message_iter_init(message
, &iter
);
2806 dbus_message_iter_next(&iter
);
2807 dbus_message_iter_next(&iter
);
2809 dbus_message_iter_recurse(&iter
, &variant_iter
);
2811 reply
= set_network_properties(message
, ssid
, &variant_iter
);
2813 wpa_printf(MSG_DEBUG
, "dbus control interface couldn't set "
2814 "network properties");