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_invald_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_invald_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_invald_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_invald_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_invald_args(message
, entry
.key
);
309 wpa_dbus_dict_entry_clear(&entry
);
318 * wpas_dbus_handler_create_interface - Request registration of a network iface
319 * @message: Pointer to incoming dbus message
320 * @global: %wpa_supplicant global data structure
321 * Returns: The object path of the new interface object,
322 * or a dbus error message with more information
324 * Handler function for "CreateInterface" method call. Handles requests
325 * by dbus clients to register a network interface that wpa_supplicant
328 DBusMessage
* wpas_dbus_handler_create_interface(DBusMessage
*message
,
329 struct wpa_global
*global
)
331 DBusMessageIter iter_dict
;
332 DBusMessage
*reply
= NULL
;
333 DBusMessageIter iter
;
334 struct wpa_dbus_dict_entry entry
;
337 char *bridge_ifname
= NULL
;
339 dbus_message_iter_init(message
, &iter
);
341 if (!wpa_dbus_dict_open_read(&iter
, &iter_dict
))
343 while (wpa_dbus_dict_has_dict_entry(&iter_dict
)) {
344 if (!wpa_dbus_dict_get_entry(&iter_dict
, &entry
))
346 if (!strcmp(entry
.key
, "Driver") &&
347 (entry
.type
== DBUS_TYPE_STRING
)) {
348 driver
= os_strdup(entry
.str_value
);
349 wpa_dbus_dict_entry_clear(&entry
);
352 } else if (!strcmp(entry
.key
, "Ifname") &&
353 (entry
.type
== DBUS_TYPE_STRING
)) {
354 ifname
= os_strdup(entry
.str_value
);
355 wpa_dbus_dict_entry_clear(&entry
);
358 } else if (!strcmp(entry
.key
, "BridgeIfname") &&
359 (entry
.type
== DBUS_TYPE_STRING
)) {
360 bridge_ifname
= os_strdup(entry
.str_value
);
361 wpa_dbus_dict_entry_clear(&entry
);
362 if (bridge_ifname
== NULL
)
365 wpa_dbus_dict_entry_clear(&entry
);
371 goto error
; /* Required Ifname argument missing */
374 * Try to get the wpa_supplicant record for this iface, return
375 * an error if we already control it.
377 if (wpa_supplicant_get_iface(global
, ifname
) != NULL
) {
378 reply
= dbus_message_new_error(message
,
379 WPAS_DBUS_ERROR_IFACE_EXISTS
,
380 "wpa_supplicant already "
381 "controls this interface.");
383 struct wpa_supplicant
*wpa_s
;
384 struct wpa_interface iface
;
385 os_memset(&iface
, 0, sizeof(iface
));
386 iface
.driver
= driver
;
387 iface
.ifname
= ifname
;
388 iface
.bridge_ifname
= bridge_ifname
;
389 /* Otherwise, have wpa_supplicant attach to it. */
390 if ((wpa_s
= wpa_supplicant_add_iface(global
, &iface
))) {
391 const char *path
= wpas_dbus_get_path(wpa_s
);
392 reply
= dbus_message_new_method_return(message
);
393 dbus_message_append_args(reply
, DBUS_TYPE_OBJECT_PATH
,
394 &path
, DBUS_TYPE_INVALID
);
396 reply
= wpas_dbus_error_unknown_error(
397 message
, "wpa_supplicant couldn't grab this "
405 os_free(bridge_ifname
);
409 reply
= wpas_dbus_error_invald_args(message
, NULL
);
415 * wpas_dbus_handler_remove_interface - Request deregistration of an interface
416 * @message: Pointer to incoming dbus message
417 * @global: wpa_supplicant global data structure
418 * Returns: a dbus message containing a UINT32 indicating success (1) or
419 * failure (0), or returns a dbus error message with more information
421 * Handler function for "removeInterface" method call. Handles requests
422 * by dbus clients to deregister a network interface that wpa_supplicant
425 DBusMessage
* wpas_dbus_handler_remove_interface(DBusMessage
*message
,
426 struct wpa_global
*global
)
428 struct wpa_supplicant
*wpa_s
;
430 DBusMessage
*reply
= NULL
;
432 dbus_message_get_args(message
, NULL
, DBUS_TYPE_OBJECT_PATH
, &path
,
435 wpa_s
= get_iface_by_dbus_path(global
, path
);
437 reply
= wpas_dbus_error_iface_unknown(message
);
438 else if (wpa_supplicant_remove_iface(global
, wpa_s
)) {
439 reply
= wpas_dbus_error_unknown_error(
440 message
, "wpa_supplicant couldn't remove this "
449 * wpas_dbus_handler_get_interface - Get the object path for an interface name
450 * @message: Pointer to incoming dbus message
451 * @global: %wpa_supplicant global data structure
452 * Returns: The object path of the interface object,
453 * or a dbus error message with more information
455 * Handler function for "getInterface" method call.
457 DBusMessage
* wpas_dbus_handler_get_interface(DBusMessage
*message
,
458 struct wpa_global
*global
)
460 DBusMessage
*reply
= NULL
;
463 struct wpa_supplicant
*wpa_s
;
465 dbus_message_get_args(message
, NULL
, DBUS_TYPE_STRING
, &ifname
,
468 wpa_s
= wpa_supplicant_get_iface(global
, ifname
);
470 return wpas_dbus_error_iface_unknown(message
);
472 path
= wpas_dbus_get_path(wpa_s
);
474 wpa_printf(MSG_ERROR
, "wpas_dbus_handler_get_interface[dbus]: "
475 "interface has no dbus object path set");
476 return wpas_dbus_error_unknown_error(message
, "path not set");
479 reply
= dbus_message_new_method_return(message
);
481 perror("wpas_dbus_handler_get_interface[dbus]: out of memory "
482 "when creating reply");
483 return dbus_message_new_error(message
, DBUS_ERROR_NO_MEMORY
,
486 if (!dbus_message_append_args(reply
, DBUS_TYPE_OBJECT_PATH
, &path
,
487 DBUS_TYPE_INVALID
)) {
488 perror("wpas_dbus_handler_get_interface[dbus]: out of memory "
489 "when appending argument to reply");
490 dbus_message_unref(reply
);
491 return dbus_message_new_error(message
, DBUS_ERROR_NO_MEMORY
,
500 * wpas_dbus_getter_debug_params - Get the debug params
501 * @message: Pointer to incoming dbus message
502 * @global: %wpa_supplicant global data structure
503 * Returns: DBus message with struct containing debug params.
505 * Getter for "DebugParams" property.
507 DBusMessage
* wpas_dbus_getter_debug_params(DBusMessage
*message
,
508 struct wpa_global
*global
)
510 DBusMessage
*reply
= NULL
;
511 DBusMessageIter iter
, variant_iter
, struct_iter
;
514 reply
= dbus_message_new(DBUS_MESSAGE_TYPE_SIGNAL
);
516 reply
= dbus_message_new_method_return(message
);
518 perror("wpas_dbus_getter_network_properties[dbus] out of "
519 "memory when trying to initialize return message");
520 reply
= dbus_message_new_error(message
, DBUS_ERROR_NO_MEMORY
,
525 dbus_message_iter_init_append(reply
, &iter
);
527 if (!dbus_message_iter_open_container(&iter
, DBUS_TYPE_VARIANT
,
528 "(ibb)", &variant_iter
)) {
529 perror("wpas_dbus_getter_debug_params[dbus] out of memory "
530 "when trying to open variant");
531 dbus_message_unref(reply
);
532 reply
= dbus_message_new_error(message
, DBUS_ERROR_NO_MEMORY
,
537 if (!dbus_message_iter_open_container(&variant_iter
, DBUS_TYPE_STRUCT
,
538 NULL
, &struct_iter
)) {
539 perror("wpas_dbus_getter_debug_params[dbus] out of memory "
540 "when trying to open struct");
541 dbus_message_unref(reply
);
542 reply
= dbus_message_new_error(message
, DBUS_ERROR_NO_MEMORY
,
547 if (!dbus_message_iter_append_basic(&struct_iter
, DBUS_TYPE_INT32
,
549 perror("wpas_dbus_getter_debug_params[dbus] out of memory "
550 "when trying to append value to struct");
551 dbus_message_unref(reply
);
552 reply
= dbus_message_new_error(message
, DBUS_ERROR_NO_MEMORY
,
557 if (!dbus_message_iter_append_basic(&struct_iter
, DBUS_TYPE_BOOLEAN
,
558 &wpa_debug_timestamp
)) {
559 perror("wpas_dbus_getter_debug_params[dbus] out of memory "
560 "when trying to append value to struct");
561 dbus_message_unref(reply
);
562 reply
= dbus_message_new_error(message
, DBUS_ERROR_NO_MEMORY
,
567 if (!dbus_message_iter_append_basic(&struct_iter
, DBUS_TYPE_BOOLEAN
,
568 &wpa_debug_show_keys
)) {
569 perror("wpas_dbus_getter_debug_params[dbus] out of memory "
570 "when trying to append value to struct");
571 dbus_message_unref(reply
);
572 reply
= dbus_message_new_error(message
, DBUS_ERROR_NO_MEMORY
,
577 if (!dbus_message_iter_close_container(&variant_iter
, &struct_iter
)) {
578 perror("wpas_dbus_getter_debug_params[dbus] out of memory "
579 "when trying to close struct");
580 dbus_message_unref(reply
);
581 reply
= dbus_message_new_error(message
, DBUS_ERROR_NO_MEMORY
,
586 if (!dbus_message_iter_close_container(&iter
, &variant_iter
)) {
587 perror("wpas_dbus_getter_debug_params[dbus] out of memory "
588 "when trying to close variant");
589 dbus_message_unref(reply
);
590 reply
= dbus_message_new_error(message
, DBUS_ERROR_NO_MEMORY
,
601 * wpas_dbus_setter_debugparams - Set the debug params
602 * @message: Pointer to incoming dbus message
603 * @global: %wpa_supplicant global data structure
604 * Returns: NULL indicating success or a dbus error message with more
607 * Setter for "DebugParams" property.
609 DBusMessage
* wpas_dbus_setter_debug_params(DBusMessage
*message
,
610 struct wpa_global
*global
)
612 DBusMessage
*reply
= NULL
;
613 DBusMessageIter iter
, variant_iter
, struct_iter
;
615 dbus_bool_t debug_timestamp
;
616 dbus_bool_t debug_show_keys
;
618 if (!dbus_message_iter_init(message
, &iter
)) {
619 perror("wpas_dbus_handler_add_blob[dbus] out of memory when "
620 "trying to initialize message iterator");
621 reply
= dbus_message_new_error(message
, DBUS_ERROR_NO_MEMORY
,
625 dbus_message_iter_next(&iter
);
626 dbus_message_iter_next(&iter
);
628 dbus_message_iter_recurse(&iter
, &variant_iter
);
630 if (dbus_message_iter_get_arg_type(&variant_iter
) != DBUS_TYPE_STRUCT
)
632 reply
= wpas_dbus_error_invald_args(
633 message
, "Argument must by a structure");
637 dbus_message_iter_recurse(&variant_iter
, &struct_iter
);
640 if (dbus_message_iter_get_arg_type(&struct_iter
) != DBUS_TYPE_INT32
) {
641 reply
= wpas_dbus_error_invald_args(
642 message
, "First struct argument must by an INT32");
646 dbus_message_iter_get_basic(&struct_iter
, &debug_level
);
647 if (!dbus_message_iter_next(&struct_iter
)) {
648 reply
= wpas_dbus_error_invald_args(
649 message
, "Not enough elements in struct");
653 if (dbus_message_iter_get_arg_type(&struct_iter
) != DBUS_TYPE_BOOLEAN
)
655 reply
= wpas_dbus_error_invald_args(
656 message
, "Second struct argument must by a boolean");
659 dbus_message_iter_get_basic(&struct_iter
, &debug_timestamp
);
660 if (!dbus_message_iter_next(&struct_iter
)) {
661 reply
= wpas_dbus_error_invald_args(
662 message
, "Not enough elements in struct");
666 if (dbus_message_iter_get_arg_type(&struct_iter
) != DBUS_TYPE_BOOLEAN
)
668 reply
= wpas_dbus_error_invald_args(
669 message
, "Third struct argument must by an boolean");
672 dbus_message_iter_get_basic(&struct_iter
, &debug_show_keys
);
674 if (wpa_supplicant_set_debug_params(global
, debug_level
,
675 debug_timestamp
? 1 : 0,
676 debug_show_keys
? 1 : 0)) {
677 reply
= wpas_dbus_error_invald_args(
678 message
, "Wrong debug level value");
688 * wpas_dbus_getter_interfaces - Request registered interfaces list
689 * @message: Pointer to incoming dbus message
690 * @global: %wpa_supplicant global data structure
691 * Returns: The object paths array containing registered interfaces
692 * objects paths or DBus error on failure
694 * Getter for "Interfaces" property. Handles requests
695 * by dbus clients to return list of registered interfaces objects
698 DBusMessage
* wpas_dbus_getter_interfaces(DBusMessage
*message
,
699 struct wpa_global
*global
)
701 DBusMessage
*reply
= NULL
;
702 DBusMessageIter iter
, variant_iter
, array_iter
;
704 struct wpa_supplicant
*wpa_s
;
707 reply
= dbus_message_new(DBUS_MESSAGE_TYPE_SIGNAL
);
709 reply
= dbus_message_new_method_return(message
);
711 perror("wpas_dbus_getter_interfaces[dbus] out of memory "
712 "when trying to initialize return message");
713 reply
= dbus_message_new_error(message
, DBUS_ERROR_NO_MEMORY
,
718 dbus_message_iter_init_append(reply
, &iter
);
719 if (!dbus_message_iter_open_container(&iter
, DBUS_TYPE_VARIANT
,
720 "ao", &variant_iter
)) {
721 perror("wpas_dbus_getter_interfaces[dbus] out of memory "
722 "when trying to open variant");
723 dbus_message_unref(reply
);
724 reply
= dbus_message_new_error(message
, DBUS_ERROR_NO_MEMORY
,
728 if (!dbus_message_iter_open_container(&variant_iter
, DBUS_TYPE_ARRAY
,
730 perror("wpas_dbus_getter_interfaces[dbus] out of memory "
731 "when trying to open array");
732 dbus_message_unref(reply
);
733 reply
= dbus_message_new_error(message
, DBUS_ERROR_NO_MEMORY
,
738 for (wpa_s
= global
->ifaces
; wpa_s
; wpa_s
= wpa_s
->next
) {
739 path
= wpas_dbus_get_path(wpa_s
);
740 if (!dbus_message_iter_append_basic(&array_iter
,
741 DBUS_TYPE_OBJECT_PATH
,
743 perror("wpas_dbus_getter_interfaces[dbus] out of "
744 "memory when trying to append interface path");
745 dbus_message_unref(reply
);
746 reply
= dbus_message_new_error(message
,
747 DBUS_ERROR_NO_MEMORY
,
753 if (!dbus_message_iter_close_container(&variant_iter
, &array_iter
)) {
754 perror("wpas_dbus_getter_interfaces[dbus] out of memory "
755 "when trying to close array");
756 reply
= dbus_message_new_error(message
, DBUS_ERROR_NO_MEMORY
,
760 if (!dbus_message_iter_close_container(&iter
, &variant_iter
)) {
761 perror("wpas_dbus_getter_interfaces[dbus] out of memory "
762 "when trying to close variant");
763 dbus_message_unref(reply
);
764 reply
= dbus_message_new_error(message
, DBUS_ERROR_NO_MEMORY
,
775 * wpas_dbus_getter_eap_methods - Request supported EAP methods list
776 * @message: Pointer to incoming dbus message
777 * @nothing: not used argument. may be NULL or anything else
778 * Returns: The object paths array containing supported EAP methods
779 * represented by strings or DBus error on failure
781 * Getter for "EapMethods" property. Handles requests
782 * by dbus clients to return list of strings with supported EAP methods
784 DBusMessage
* wpas_dbus_getter_eap_methods(DBusMessage
*message
, void *nothing
)
786 DBusMessage
*reply
= NULL
;
787 DBusMessageIter iter
, variant_iter
, array_iter
;
792 reply
= dbus_message_new(DBUS_MESSAGE_TYPE_SIGNAL
);
794 reply
= dbus_message_new_method_return(message
);
796 perror("wpas_dbus_getter_eap_methods[dbus] out of memory "
797 "when trying to initialize return message");
798 reply
= dbus_message_new_error(message
, DBUS_ERROR_NO_MEMORY
,
803 dbus_message_iter_init_append(reply
, &iter
);
804 if (!dbus_message_iter_open_container(&iter
, DBUS_TYPE_VARIANT
,
805 "as", &variant_iter
)) {
806 perror("wpas_dbus_getter_eap_methods[dbus] out of memory "
807 "when trying to open variant");
808 dbus_message_unref(reply
);
809 reply
= dbus_message_new_error(message
, DBUS_ERROR_NO_MEMORY
,
814 if (!dbus_message_iter_open_container(&variant_iter
, DBUS_TYPE_ARRAY
,
816 perror("wpas_dbus_getter_eap_methods[dbus] out of memory "
817 "when trying to open variant");
818 dbus_message_unref(reply
);
819 reply
= dbus_message_new_error(message
, DBUS_ERROR_NO_MEMORY
,
824 eap_methods
= eap_get_names_as_string_array(&num_items
);
828 for (i
= 0; i
< num_items
; i
++) {
829 if (!dbus_message_iter_append_basic(&array_iter
,
833 os_free(eap_methods
[i
]);
835 os_free(eap_methods
);
838 wpa_printf(MSG_ERROR
, "wpas_dbus_getter_eap_methods"
839 "[dbus] out of memory when adding to "
841 dbus_message_unref(reply
);
842 reply
= dbus_message_new_error(message
,
843 DBUS_ERROR_NO_MEMORY
,
849 if (!dbus_message_iter_close_container(&variant_iter
, &array_iter
)) {
850 perror("wpas_dbus_getter_eap_methods[dbus] "
851 "out of memory when trying to close array");
852 dbus_message_unref(reply
);
853 reply
= dbus_message_new_error(message
, DBUS_ERROR_NO_MEMORY
,
857 if (!dbus_message_iter_close_container(&iter
, &variant_iter
)) {
858 perror("wpas_dbus_getter_eap_methods[dbus] "
859 "out of memory when trying to close variant");
860 dbus_message_unref(reply
);
861 reply
= dbus_message_new_error(message
, DBUS_ERROR_NO_MEMORY
,
871 static int wpas_dbus_get_scan_type(DBusMessage
*message
, DBusMessageIter
*var
,
872 char **type
, DBusMessage
**reply
)
874 if (dbus_message_iter_get_arg_type(var
) != DBUS_TYPE_STRING
) {
875 wpa_printf(MSG_DEBUG
, "wpas_dbus_handler_scan[dbus]: "
876 "Type must be a string");
877 *reply
= wpas_dbus_error_invald_args(
878 message
, "Wrong Type value type. String required");
881 dbus_message_iter_get_basic(var
, type
);
886 static int wpas_dbus_get_scan_ssids(DBusMessage
*message
, DBusMessageIter
*var
,
887 struct wpa_driver_scan_params
*params
,
890 struct wpa_driver_scan_ssid
*ssids
= params
->ssids
;
891 size_t ssids_num
= 0;
893 DBusMessageIter array_iter
, sub_array_iter
;
897 if (dbus_message_iter_get_arg_type(var
) != DBUS_TYPE_ARRAY
) {
898 wpa_printf(MSG_DEBUG
, "wpas_dbus_handler_scan[dbus]: ssids "
899 "must be an array of arrays of bytes");
900 *reply
= wpas_dbus_error_invald_args(
901 message
, "Wrong SSIDs value type. Array of arrays of "
906 dbus_message_iter_recurse(var
, &array_iter
);
908 if (dbus_message_iter_get_arg_type(&array_iter
) != DBUS_TYPE_ARRAY
||
909 dbus_message_iter_get_element_type(&array_iter
) != DBUS_TYPE_BYTE
)
911 wpa_printf(MSG_DEBUG
, "wpas_dbus_handler_scan[dbus]: ssids "
912 "must be an array of arrays of bytes");
913 *reply
= wpas_dbus_error_invald_args(
914 message
, "Wrong SSIDs value type. Array of arrays of "
919 while (dbus_message_iter_get_arg_type(&array_iter
) == DBUS_TYPE_ARRAY
)
921 if (ssids_num
>= WPAS_MAX_SCAN_SSIDS
) {
922 wpa_printf(MSG_DEBUG
, "wpas_dbus_handler_scan[dbus]: "
923 "Too many ssids specified on scan dbus "
925 *reply
= wpas_dbus_error_invald_args(
926 message
, "Too many ssids specified. Specify "
931 dbus_message_iter_recurse(&array_iter
, &sub_array_iter
);
933 dbus_message_iter_get_fixed_array(&sub_array_iter
, &val
, &len
);
935 dbus_message_iter_next(&array_iter
);
939 ssid
= os_malloc(len
);
941 wpa_printf(MSG_DEBUG
, "wpas_dbus_handler_scan[dbus]: "
942 "out of memory. Cannot allocate memory for "
944 *reply
= dbus_message_new_error(
945 message
, DBUS_ERROR_NO_MEMORY
, NULL
);
948 os_memcpy(ssid
, val
, len
);
949 ssids
[ssids_num
].ssid
= ssid
;
950 ssids
[ssids_num
].ssid_len
= len
;
952 dbus_message_iter_next(&array_iter
);
956 params
->num_ssids
= ssids_num
;
961 static int wpas_dbus_get_scan_ies(DBusMessage
*message
, DBusMessageIter
*var
,
962 struct wpa_driver_scan_params
*params
,
965 u8
*ies
= NULL
, *nies
;
967 DBusMessageIter array_iter
, sub_array_iter
;
971 if (dbus_message_iter_get_arg_type(var
) != DBUS_TYPE_ARRAY
) {
972 wpa_printf(MSG_DEBUG
, "wpas_dbus_handler_scan[dbus]: ies must "
973 "be an array of arrays of bytes");
974 *reply
= wpas_dbus_error_invald_args(
975 message
, "Wrong IEs value type. Array of arrays of "
980 dbus_message_iter_recurse(var
, &array_iter
);
982 if (dbus_message_iter_get_arg_type(&array_iter
) != DBUS_TYPE_ARRAY
||
983 dbus_message_iter_get_element_type(&array_iter
) != DBUS_TYPE_BYTE
)
985 wpa_printf(MSG_DEBUG
, "wpas_dbus_handler_scan[dbus]: ies must "
986 "be an array of arrays of bytes");
987 *reply
= wpas_dbus_error_invald_args(
988 message
, "Wrong IEs value type. Array required");
992 while (dbus_message_iter_get_arg_type(&array_iter
) == DBUS_TYPE_ARRAY
)
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 nies
= os_realloc(ies
, ies_len
+ len
);
1004 wpa_printf(MSG_DEBUG
, "wpas_dbus_handler_scan[dbus]: "
1005 "out of memory. Cannot allocate memory for "
1008 *reply
= dbus_message_new_error(
1009 message
, DBUS_ERROR_NO_MEMORY
, NULL
);
1013 os_memcpy(ies
+ ies_len
, val
, len
);
1016 dbus_message_iter_next(&array_iter
);
1019 params
->extra_ies
= ies
;
1020 params
->extra_ies_len
= ies_len
;
1025 static int wpas_dbus_get_scan_channels(DBusMessage
*message
,
1026 DBusMessageIter
*var
,
1027 struct wpa_driver_scan_params
*params
,
1028 DBusMessage
**reply
)
1030 DBusMessageIter array_iter
, sub_array_iter
;
1031 int *freqs
= NULL
, *nfreqs
;
1034 if (dbus_message_iter_get_arg_type(var
) != DBUS_TYPE_ARRAY
) {
1035 wpa_printf(MSG_DEBUG
, "wpas_dbus_handler_scan[dbus]: "
1036 "Channels must be an array of structs");
1037 *reply
= wpas_dbus_error_invald_args(
1038 message
, "Wrong Channels value type. Array of structs "
1043 dbus_message_iter_recurse(var
, &array_iter
);
1045 if (dbus_message_iter_get_arg_type(&array_iter
) != DBUS_TYPE_STRUCT
) {
1046 wpa_printf(MSG_DEBUG
,
1047 "wpas_dbus_handler_scan[dbus]: Channels must be an "
1048 "array of structs");
1049 *reply
= wpas_dbus_error_invald_args(
1050 message
, "Wrong Channels value type. Array of structs "
1055 while (dbus_message_iter_get_arg_type(&array_iter
) == DBUS_TYPE_STRUCT
)
1059 dbus_message_iter_recurse(&array_iter
, &sub_array_iter
);
1061 if (dbus_message_iter_get_arg_type(&sub_array_iter
) !=
1063 wpa_printf(MSG_DEBUG
, "wpas_dbus_handler_scan[dbus]: "
1064 "Channel must by specified by struct of "
1066 dbus_message_iter_get_arg_type(
1068 *reply
= wpas_dbus_error_invald_args(
1069 message
, "Wrong Channel struct. Two UINT32s "
1074 dbus_message_iter_get_basic(&sub_array_iter
, &freq
);
1076 if (!dbus_message_iter_next(&sub_array_iter
) ||
1077 dbus_message_iter_get_arg_type(&sub_array_iter
) !=
1079 wpa_printf(MSG_DEBUG
, "wpas_dbus_handler_scan[dbus]: "
1080 "Channel must by specified by struct of "
1082 *reply
= wpas_dbus_error_invald_args(
1084 "Wrong Channel struct. Two UINT32s required");
1089 dbus_message_iter_get_basic(&sub_array_iter
, &width
);
1091 #define FREQS_ALLOC_CHUNK 32
1092 if (freqs_num
% FREQS_ALLOC_CHUNK
== 0) {
1093 nfreqs
= os_realloc(freqs
, sizeof(int) *
1094 (freqs_num
+ FREQS_ALLOC_CHUNK
));
1099 if (freqs
== NULL
) {
1100 wpa_printf(MSG_DEBUG
, "wpas_dbus_handler_scan[dbus]: "
1101 "out of memory. can't allocate memory for "
1103 *reply
= dbus_message_new_error(
1104 message
, DBUS_ERROR_NO_MEMORY
, NULL
);
1108 freqs
[freqs_num
] = freq
;
1111 dbus_message_iter_next(&array_iter
);
1114 nfreqs
= os_realloc(freqs
,
1115 sizeof(int) * (freqs_num
+ 1));
1119 if (freqs
== NULL
) {
1120 wpa_printf(MSG_DEBUG
, "wpas_dbus_handler_scan[dbus]: "
1121 "out of memory. Can't allocate memory for freqs");
1122 *reply
= dbus_message_new_error(
1123 message
, DBUS_ERROR_NO_MEMORY
, NULL
);
1126 freqs
[freqs_num
] = 0;
1128 params
->freqs
= freqs
;
1134 * wpas_dbus_handler_scan - Request a wireless scan on an interface
1135 * @message: Pointer to incoming dbus message
1136 * @wpa_s: wpa_supplicant structure for a network interface
1137 * Returns: NULL indicating success or DBus error message on failure
1139 * Handler function for "Scan" method call of a network device. Requests
1140 * that wpa_supplicant perform a wireless scan as soon as possible
1141 * on a particular wireless interface.
1143 DBusMessage
* wpas_dbus_handler_scan(DBusMessage
*message
,
1144 struct wpa_supplicant
*wpa_s
)
1146 DBusMessage
*reply
= NULL
;
1147 DBusMessageIter iter
, dict_iter
, entry_iter
, variant_iter
;
1148 char *key
= NULL
, *type
= NULL
;
1149 struct wpa_driver_scan_params params
;
1152 os_memset(¶ms
, 0, sizeof(params
));
1154 dbus_message_iter_init(message
, &iter
);
1156 dbus_message_iter_recurse(&iter
, &dict_iter
);
1158 while (dbus_message_iter_get_arg_type(&dict_iter
) ==
1159 DBUS_TYPE_DICT_ENTRY
) {
1160 dbus_message_iter_recurse(&dict_iter
, &entry_iter
);
1161 dbus_message_iter_get_basic(&entry_iter
, &key
);
1162 dbus_message_iter_next(&entry_iter
);
1163 dbus_message_iter_recurse(&entry_iter
, &variant_iter
);
1165 if (os_strcmp(key
, "Type") == 0) {
1166 if (wpas_dbus_get_scan_type(message
, &variant_iter
,
1169 } else if (os_strcmp(key
, "SSIDs") == 0) {
1170 if (wpas_dbus_get_scan_ssids(message
, &variant_iter
,
1171 ¶ms
, &reply
) < 0)
1173 } else if (os_strcmp(key
, "IEs") == 0) {
1174 if (wpas_dbus_get_scan_ies(message
, &variant_iter
,
1175 ¶ms
, &reply
) < 0)
1177 } else if (os_strcmp(key
, "Channels") == 0) {
1178 if (wpas_dbus_get_scan_channels(message
, &variant_iter
,
1179 ¶ms
, &reply
) < 0)
1182 wpa_printf(MSG_DEBUG
, "wpas_dbus_handler_scan[dbus]: "
1183 "Unknown argument %s", key
);
1184 reply
= wpas_dbus_error_invald_args(message
, key
);
1188 dbus_message_iter_next(&dict_iter
);
1192 wpa_printf(MSG_DEBUG
, "wpas_dbus_handler_scan[dbus]: "
1193 "Scan type not specified");
1194 reply
= wpas_dbus_error_invald_args(message
, key
);
1198 if (!os_strcmp(type
, "passive")) {
1199 if (params
.num_ssids
|| params
.extra_ies_len
) {
1200 wpa_printf(MSG_DEBUG
, "wpas_dbus_handler_scan[dbus]: "
1201 "SSIDs or IEs specified for passive scan.");
1202 reply
= wpas_dbus_error_invald_args(
1203 message
, "You can specify only Channels in "
1206 } else if (params
.freqs
&& params
.freqs
[0]) {
1209 wpa_supplicant_trigger_scan(wpa_s
, ¶ms
);
1211 wpa_s
->scan_req
= 2;
1212 wpa_supplicant_req_scan(wpa_s
, 0, 0);
1214 } else if (!os_strcmp(type
, "active")) {
1215 wpa_supplicant_trigger_scan(wpa_s
, ¶ms
);
1217 wpa_printf(MSG_DEBUG
, "wpas_dbus_handler_scan[dbus]: "
1218 "Unknown scan type: %s", type
);
1219 reply
= wpas_dbus_error_invald_args(message
,
1225 for (i
= 0; i
< WPAS_MAX_SCAN_SSIDS
; i
++)
1226 os_free((u8
*) params
.ssids
[i
].ssid
);
1227 os_free((u8
*) params
.extra_ies
);
1228 os_free(params
.freqs
);
1234 * wpas_dbus_handler_disconnect - Terminate the current connection
1235 * @message: Pointer to incoming dbus message
1236 * @wpa_s: wpa_supplicant structure for a network interface
1237 * Returns: NotConnected DBus error message if already not connected
1238 * or NULL otherwise.
1240 * Handler function for "Disconnect" method call of network interface.
1242 DBusMessage
* wpas_dbus_handler_disconnect(DBusMessage
*message
,
1243 struct wpa_supplicant
*wpa_s
)
1245 if (wpa_s
->current_ssid
!= NULL
) {
1246 wpa_s
->disconnected
= 1;
1247 wpa_supplicant_disassociate(wpa_s
, WLAN_REASON_DEAUTH_LEAVING
);
1252 return dbus_message_new_error(message
, WPAS_DBUS_ERROR_NOT_CONNECTED
,
1253 "This interface is not connected");
1258 * wpas_dbus_new_iface_add_network - Add a new configured network
1259 * @message: Pointer to incoming dbus message
1260 * @wpa_s: wpa_supplicant structure for a network interface
1261 * Returns: A dbus message containing the object path of the new network
1263 * Handler function for "AddNetwork" method call of a network interface.
1265 DBusMessage
* wpas_dbus_handler_add_network(DBusMessage
*message
,
1266 struct wpa_supplicant
*wpa_s
)
1268 DBusMessage
*reply
= NULL
;
1269 DBusMessageIter iter
;
1270 struct wpa_ssid
*ssid
= NULL
;
1273 path
= os_zalloc(WPAS_DBUS_OBJECT_PATH_MAX
);
1275 perror("wpas_dbus_handler_add_network[dbus]: out of "
1277 reply
= dbus_message_new_error(message
, DBUS_ERROR_NO_MEMORY
,
1282 dbus_message_iter_init(message
, &iter
);
1284 ssid
= wpa_config_add_network(wpa_s
->conf
);
1286 wpa_printf(MSG_ERROR
, "wpas_dbus_handler_add_network[dbus]: "
1287 "can't add new interface.");
1288 reply
= wpas_dbus_error_unknown_error(
1290 "wpa_supplicant could not add "
1291 "a network on this interface.");
1294 wpas_notify_network_added(wpa_s
, ssid
);
1296 wpa_config_set_network_defaults(ssid
);
1298 reply
= set_network_properties(message
, ssid
, &iter
);
1300 wpa_printf(MSG_DEBUG
, "wpas_dbus_handler_add_network[dbus]:"
1301 "control interface couldn't set network "
1306 /* Construct the object path for this network. */
1307 os_snprintf(path
, WPAS_DBUS_OBJECT_PATH_MAX
,
1308 "%s/" WPAS_DBUS_NEW_NETWORKS_PART
"/%d",
1309 wpas_dbus_get_path(wpa_s
),
1312 reply
= dbus_message_new_method_return(message
);
1313 if (reply
== NULL
) {
1314 perror("wpas_dbus_handler_add_network[dbus]: out of memory "
1315 "when creating reply");
1316 reply
= dbus_message_new_error(message
, DBUS_ERROR_NO_MEMORY
,
1320 if (!dbus_message_append_args(reply
, DBUS_TYPE_OBJECT_PATH
, &path
,
1321 DBUS_TYPE_INVALID
)) {
1322 perror("wpas_dbus_handler_add_network[dbus]: out of memory "
1323 "when appending argument to reply");
1324 dbus_message_unref(reply
);
1325 reply
= dbus_message_new_error(message
, DBUS_ERROR_NO_MEMORY
,
1335 wpas_notify_network_removed(wpa_s
, ssid
);
1336 wpa_config_remove_network(wpa_s
->conf
, ssid
->id
);
1344 * wpas_dbus_handler_remove_network - Remove a configured network
1345 * @message: Pointer to incoming dbus message
1346 * @wpa_s: wpa_supplicant structure for a network interface
1347 * Returns: NULL on success or dbus error on failure
1349 * Handler function for "RemoveNetwork" method call of a network interface.
1351 DBusMessage
* wpas_dbus_handler_remove_network(DBusMessage
*message
,
1352 struct wpa_supplicant
*wpa_s
)
1354 DBusMessage
*reply
= NULL
;
1356 char *iface
= NULL
, *net_id
= NULL
;
1358 struct wpa_ssid
*ssid
;
1360 dbus_message_get_args(message
, NULL
, DBUS_TYPE_OBJECT_PATH
, &op
,
1363 /* Extract the network ID and ensure the network */
1364 /* is actually a child of this interface */
1365 iface
= wpas_dbus_new_decompose_object_path(op
, &net_id
, NULL
);
1366 if (iface
== NULL
|| strcmp(iface
, wpas_dbus_get_path(wpa_s
)) != 0) {
1367 reply
= wpas_dbus_error_invald_args(message
, op
);
1371 id
= strtoul(net_id
, NULL
, 10);
1372 if (errno
== EINVAL
) {
1373 reply
= wpas_dbus_error_invald_args(message
, op
);
1377 ssid
= wpa_config_get_network(wpa_s
->conf
, id
);
1379 reply
= wpas_dbus_error_network_unknown(message
);
1383 wpas_notify_network_removed(wpa_s
, ssid
);
1385 if (wpa_config_remove_network(wpa_s
->conf
, id
) < 0) {
1386 wpa_printf(MSG_ERROR
,
1387 "wpas_dbus_handler_remove_network[dbus]: "
1388 "error occurred when removing network %d", id
);
1389 reply
= wpas_dbus_error_unknown_error(
1390 message
, "error removing the specified network on "
1395 if (ssid
== wpa_s
->current_ssid
)
1396 wpa_supplicant_disassociate(wpa_s
, WLAN_REASON_DEAUTH_LEAVING
);
1406 * wpas_dbus_handler_select_network - Attempt association with a network
1407 * @message: Pointer to incoming dbus message
1408 * @wpa_s: wpa_supplicant structure for a network interface
1409 * Returns: NULL on success or dbus error on failure
1411 * Handler function for "SelectNetwork" method call of network interface.
1413 DBusMessage
* wpas_dbus_handler_select_network(DBusMessage
*message
,
1414 struct wpa_supplicant
*wpa_s
)
1416 DBusMessage
*reply
= NULL
;
1418 char *iface
= NULL
, *net_id
= NULL
;
1420 struct wpa_ssid
*ssid
;
1422 dbus_message_get_args(message
, NULL
, DBUS_TYPE_OBJECT_PATH
, &op
,
1425 /* Extract the network ID and ensure the network */
1426 /* is actually a child of this interface */
1427 iface
= wpas_dbus_new_decompose_object_path(op
, &net_id
, NULL
);
1428 if (iface
== NULL
|| strcmp(iface
, wpas_dbus_get_path(wpa_s
)) != 0) {
1429 reply
= wpas_dbus_error_invald_args(message
, op
);
1433 id
= strtoul(net_id
, NULL
, 10);
1434 if (errno
== EINVAL
) {
1435 reply
= wpas_dbus_error_invald_args(message
, op
);
1439 ssid
= wpa_config_get_network(wpa_s
->conf
, id
);
1441 reply
= wpas_dbus_error_network_unknown(message
);
1445 /* Finally, associate with the network */
1446 wpa_supplicant_select_network(wpa_s
, ssid
);
1456 * wpas_dbus_handler_add_blob - Store named binary blob (ie, for certificates)
1457 * @message: Pointer to incoming dbus message
1458 * @wpa_s: %wpa_supplicant data structure
1459 * Returns: A dbus message containing an error on failure or NULL on success
1461 * Asks wpa_supplicant to internally store a binary blobs.
1463 DBusMessage
* wpas_dbus_handler_add_blob(DBusMessage
*message
,
1464 struct wpa_supplicant
*wpa_s
)
1466 DBusMessage
*reply
= NULL
;
1467 DBusMessageIter iter
, array_iter
;
1472 struct wpa_config_blob
*blob
= NULL
;
1474 dbus_message_iter_init(message
, &iter
);
1475 dbus_message_iter_get_basic(&iter
, &blob_name
);
1477 if (wpa_config_get_blob(wpa_s
->conf
, blob_name
)) {
1478 return dbus_message_new_error(message
,
1479 WPAS_DBUS_ERROR_BLOB_EXISTS
,
1483 dbus_message_iter_next(&iter
);
1484 dbus_message_iter_recurse(&iter
, &array_iter
);
1486 dbus_message_iter_get_fixed_array(&array_iter
, &blob_data
, &blob_len
);
1488 blob
= os_zalloc(sizeof(*blob
));
1490 perror("wpas_dbus_handler_add_blob[dbus] out of memory when "
1491 "trying to allocate blob struct");
1492 reply
= dbus_message_new_error(message
, DBUS_ERROR_NO_MEMORY
,
1497 blob
->data
= os_malloc(blob_len
);
1499 perror("wpas_dbus_handler_add_blob[dbus] out of memory when "
1500 "trying to allocate blob data");
1501 reply
= dbus_message_new_error(message
, DBUS_ERROR_NO_MEMORY
,
1505 os_memcpy(blob
->data
, blob_data
, blob_len
);
1507 blob
->len
= blob_len
;
1508 blob
->name
= os_strdup(blob_name
);
1510 perror("wpas_dbus_handler_add_blob[dbus] out of memory when "
1511 "trying to copy blob name");
1512 reply
= dbus_message_new_error(message
, DBUS_ERROR_NO_MEMORY
,
1517 wpa_config_set_blob(wpa_s
->conf
, blob
);
1518 wpas_notify_blob_added(wpa_s
, blob
->name
);
1524 os_free(blob
->name
);
1525 os_free(blob
->data
);
1533 * wpas_dbus_handler_get_blob - Get named binary blob (ie, for certificates)
1534 * @message: Pointer to incoming dbus message
1535 * @wpa_s: %wpa_supplicant data structure
1536 * Returns: A dbus message containing array of bytes (blob)
1538 * Gets one wpa_supplicant's binary blobs.
1540 DBusMessage
* wpas_dbus_handler_get_blob(DBusMessage
*message
,
1541 struct wpa_supplicant
*wpa_s
)
1543 DBusMessage
*reply
= NULL
;
1544 DBusMessageIter iter
, array_iter
;
1547 const struct wpa_config_blob
*blob
;
1549 dbus_message_get_args(message
, NULL
, DBUS_TYPE_STRING
, &blob_name
,
1552 blob
= wpa_config_get_blob(wpa_s
->conf
, blob_name
);
1554 return dbus_message_new_error(message
,
1555 WPAS_DBUS_ERROR_BLOB_UNKNOWN
,
1559 reply
= dbus_message_new_method_return(message
);
1561 perror("wpas_dbus_handler_get_blob[dbus] out of memory when "
1562 "trying to allocate return message");
1563 reply
= dbus_message_new_error(message
, DBUS_ERROR_NO_MEMORY
,
1568 dbus_message_iter_init_append(reply
, &iter
);
1570 if (!dbus_message_iter_open_container(&iter
, DBUS_TYPE_ARRAY
,
1571 DBUS_TYPE_BYTE_AS_STRING
,
1573 dbus_message_unref(reply
);
1574 perror("wpas_dbus_handler_get_blob[dbus] out of memory when "
1575 "trying to open array");
1576 reply
= dbus_message_new_error(message
, DBUS_ERROR_NO_MEMORY
,
1581 if (!dbus_message_iter_append_fixed_array(&array_iter
, DBUS_TYPE_BYTE
,
1582 &(blob
->data
), blob
->len
)) {
1583 dbus_message_unref(reply
);
1584 perror("wpas_dbus_handler_get_blob[dbus] out of memory when "
1585 "trying to append data to array");
1586 reply
= dbus_message_new_error(message
, DBUS_ERROR_NO_MEMORY
,
1591 if (!dbus_message_iter_close_container(&iter
, &array_iter
)) {
1592 dbus_message_unref(reply
);
1593 perror("wpas_dbus_handler_get_blob[dbus] out of memory when "
1594 "trying to close array");
1595 reply
= dbus_message_new_error(message
, DBUS_ERROR_NO_MEMORY
,
1606 * wpas_remove_handler_remove_blob - Remove named binary blob
1607 * @message: Pointer to incoming dbus message
1608 * @wpa_s: %wpa_supplicant data structure
1609 * Returns: NULL on success or dbus error
1611 * Asks wpa_supplicant to internally remove a binary blobs.
1613 DBusMessage
* wpas_dbus_handler_remove_blob(DBusMessage
*message
,
1614 struct wpa_supplicant
*wpa_s
)
1616 DBusMessage
*reply
= NULL
;
1619 dbus_message_get_args(message
, NULL
, DBUS_TYPE_STRING
, &blob_name
,
1622 if (wpa_config_remove_blob(wpa_s
->conf
, blob_name
)) {
1623 return dbus_message_new_error(message
,
1624 WPAS_DBUS_ERROR_BLOB_UNKNOWN
,
1627 wpas_notify_blob_removed(wpa_s
, blob_name
);
1635 * wpas_dbus_getter_capabilities - Return interface capabilities
1636 * @message: Pointer to incoming dbus message
1637 * @wpa_s: wpa_supplicant structure for a network interface
1638 * Returns: A dbus message containing a dict of strings
1640 * Getter for "Capabilities" property of an interface.
1642 DBusMessage
* wpas_dbus_getter_capabilities(DBusMessage
*message
,
1643 struct wpa_supplicant
*wpa_s
)
1645 DBusMessage
*reply
= NULL
;
1646 struct wpa_driver_capa capa
;
1648 DBusMessageIter iter
, iter_dict
;
1649 DBusMessageIter iter_dict_entry
, iter_dict_val
, iter_array
,
1651 const char *scans
[] = { "active", "passive", "ssid" };
1652 const char *modes
[] = { "infrastructure", "ad-hoc", "ap" };
1653 int n
= sizeof(modes
) / sizeof(char *);
1655 if (message
== NULL
)
1656 reply
= dbus_message_new(DBUS_MESSAGE_TYPE_SIGNAL
);
1658 reply
= dbus_message_new_method_return(message
);
1662 dbus_message_iter_init_append(reply
, &iter
);
1663 if (!dbus_message_iter_open_container(&iter
, DBUS_TYPE_VARIANT
,
1664 "a{sv}", &variant_iter
))
1667 if (!wpa_dbus_dict_open_write(&variant_iter
, &iter_dict
))
1670 res
= wpa_drv_get_capa(wpa_s
, &capa
);
1672 /***** pairwise cipher */
1674 const char *args
[] = {"ccmp", "tkip", "none"};
1675 if (!wpa_dbus_dict_append_string_array(
1676 &iter_dict
, "Pairwise", args
,
1677 sizeof(args
) / sizeof(char*)))
1680 if (!wpa_dbus_dict_begin_string_array(&iter_dict
, "Pairwise",
1686 if (capa
.enc
& WPA_DRIVER_CAPA_ENC_CCMP
) {
1687 if (!wpa_dbus_dict_string_array_add_element(
1688 &iter_array
, "ccmp"))
1692 if (capa
.enc
& WPA_DRIVER_CAPA_ENC_TKIP
) {
1693 if (!wpa_dbus_dict_string_array_add_element(
1694 &iter_array
, "tkip"))
1698 if (capa
.key_mgmt
& WPA_DRIVER_CAPA_KEY_MGMT_WPA_NONE
) {
1699 if (!wpa_dbus_dict_string_array_add_element(
1700 &iter_array
, "none"))
1704 if (!wpa_dbus_dict_end_string_array(&iter_dict
,
1711 /***** group cipher */
1713 const char *args
[] = {
1714 "ccmp", "tkip", "wep104", "wep40"
1716 if (!wpa_dbus_dict_append_string_array(
1717 &iter_dict
, "Group", args
,
1718 sizeof(args
) / sizeof(char*)))
1721 if (!wpa_dbus_dict_begin_string_array(&iter_dict
, "Group",
1727 if (capa
.enc
& WPA_DRIVER_CAPA_ENC_CCMP
) {
1728 if (!wpa_dbus_dict_string_array_add_element(
1729 &iter_array
, "ccmp"))
1733 if (capa
.enc
& WPA_DRIVER_CAPA_ENC_TKIP
) {
1734 if (!wpa_dbus_dict_string_array_add_element(
1735 &iter_array
, "tkip"))
1739 if (capa
.enc
& WPA_DRIVER_CAPA_ENC_WEP104
) {
1740 if (!wpa_dbus_dict_string_array_add_element(
1741 &iter_array
, "wep104"))
1745 if (capa
.enc
& WPA_DRIVER_CAPA_ENC_WEP40
) {
1746 if (!wpa_dbus_dict_string_array_add_element(
1747 &iter_array
, "wep40"))
1751 if (!wpa_dbus_dict_end_string_array(&iter_dict
,
1758 /***** key management */
1760 const char *args
[] = {
1761 "wpa-psk", "wpa-eap", "ieee8021x", "wpa-none",
1764 #endif /* CONFIG_WPS */
1767 if (!wpa_dbus_dict_append_string_array(
1768 &iter_dict
, "KeyMgmt", args
,
1769 sizeof(args
) / sizeof(char*)))
1772 if (!wpa_dbus_dict_begin_string_array(&iter_dict
, "KeyMgmt",
1778 if (!wpa_dbus_dict_string_array_add_element(&iter_array
,
1782 if (!wpa_dbus_dict_string_array_add_element(&iter_array
,
1786 if (capa
.key_mgmt
& (WPA_DRIVER_CAPA_KEY_MGMT_WPA
|
1787 WPA_DRIVER_CAPA_KEY_MGMT_WPA2
)) {
1788 if (!wpa_dbus_dict_string_array_add_element(
1789 &iter_array
, "wpa-eap"))
1793 if (capa
.key_mgmt
& (WPA_DRIVER_CAPA_KEY_MGMT_WPA_PSK
|
1794 WPA_DRIVER_CAPA_KEY_MGMT_WPA2_PSK
)) {
1795 if (!wpa_dbus_dict_string_array_add_element(
1796 &iter_array
, "wpa-psk"))
1800 if (capa
.key_mgmt
& WPA_DRIVER_CAPA_KEY_MGMT_WPA_NONE
) {
1801 if (!wpa_dbus_dict_string_array_add_element(
1802 &iter_array
, "wpa-none"))
1808 if (!wpa_dbus_dict_string_array_add_element(&iter_array
,
1811 #endif /* CONFIG_WPS */
1813 if (!wpa_dbus_dict_end_string_array(&iter_dict
,
1820 /***** WPA protocol */
1822 const char *args
[] = { "rsn", "wpa" };
1823 if (!wpa_dbus_dict_append_string_array(
1824 &iter_dict
, "Protocol", args
,
1825 sizeof(args
) / sizeof(char*)))
1828 if (!wpa_dbus_dict_begin_string_array(&iter_dict
, "Protocol",
1834 if (capa
.key_mgmt
& (WPA_DRIVER_CAPA_KEY_MGMT_WPA2
|
1835 WPA_DRIVER_CAPA_KEY_MGMT_WPA2_PSK
)) {
1836 if (!wpa_dbus_dict_string_array_add_element(
1837 &iter_array
, "rsn"))
1841 if (capa
.key_mgmt
& (WPA_DRIVER_CAPA_KEY_MGMT_WPA
|
1842 WPA_DRIVER_CAPA_KEY_MGMT_WPA_PSK
)) {
1843 if (!wpa_dbus_dict_string_array_add_element(
1844 &iter_array
, "wpa"))
1848 if (!wpa_dbus_dict_end_string_array(&iter_dict
,
1857 const char *args
[] = { "open", "shared", "leap" };
1858 if (!wpa_dbus_dict_append_string_array(
1859 &iter_dict
, "AuthAlg", args
,
1860 sizeof(args
) / sizeof(char*)))
1863 if (!wpa_dbus_dict_begin_string_array(&iter_dict
, "AuthAlg",
1869 if (capa
.auth
& (WPA_DRIVER_AUTH_OPEN
)) {
1870 if (!wpa_dbus_dict_string_array_add_element(
1871 &iter_array
, "open"))
1875 if (capa
.auth
& (WPA_DRIVER_AUTH_SHARED
)) {
1876 if (!wpa_dbus_dict_string_array_add_element(
1877 &iter_array
, "shared"))
1881 if (capa
.auth
& (WPA_DRIVER_AUTH_LEAP
)) {
1882 if (!wpa_dbus_dict_string_array_add_element(
1883 &iter_array
, "leap"))
1887 if (!wpa_dbus_dict_end_string_array(&iter_dict
,
1895 if (!wpa_dbus_dict_append_string_array(&iter_dict
, "Scan", scans
,
1896 sizeof(scans
) / sizeof(char *)))
1900 if (res
< 0 || !(capa
.flags
& WPA_DRIVER_FLAGS_AP
))
1901 n
--; /* exclude ap mode if it is not supported by the driver */
1902 if (!wpa_dbus_dict_append_string_array(&iter_dict
, "Modes", modes
, n
))
1905 if (!wpa_dbus_dict_close_write(&variant_iter
, &iter_dict
))
1907 if (!dbus_message_iter_close_container(&iter
, &variant_iter
))
1914 dbus_message_unref(reply
);
1916 return dbus_message_new_error(message
, DBUS_ERROR_NO_MEMORY
, NULL
);
1921 * wpas_dbus_getter_state - Get interface state
1922 * @message: Pointer to incoming dbus message
1923 * @wpa_s: wpa_supplicant structure for a network interface
1924 * Returns: A dbus message containing a STRING representing the current
1927 * Getter for "State" property.
1929 DBusMessage
* wpas_dbus_getter_state(DBusMessage
*message
,
1930 struct wpa_supplicant
*wpa_s
)
1932 DBusMessage
*reply
= NULL
;
1933 DBusMessageIter iter
, variant_iter
;
1934 const char *str_state
;
1935 char *state_ls
, *tmp
;
1937 if (message
== NULL
)
1938 reply
= dbus_message_new(DBUS_MESSAGE_TYPE_SIGNAL
);
1940 reply
= dbus_message_new_method_return(message
);
1941 if (reply
!= NULL
) {
1942 dbus_message_iter_init_append(reply
, &iter
);
1943 if (!dbus_message_iter_open_container(&iter
, DBUS_TYPE_VARIANT
,
1944 "s", &variant_iter
)) {
1945 perror("wpas_dbus_getter_state[dbus] out of memory "
1946 "when trying to open variant");
1947 dbus_message_unref(reply
);
1948 reply
= dbus_message_new_error(message
,
1949 DBUS_ERROR_NO_MEMORY
,
1954 str_state
= wpa_supplicant_state_txt(wpa_s
->wpa_state
);
1956 /* make state string lowercase to fit new DBus API convention
1958 state_ls
= tmp
= os_strdup(str_state
);
1960 perror("wpas_dbus_getter_state[dbus] out of memory "
1961 "when trying read state");
1962 dbus_message_unref(reply
);
1963 reply
= dbus_message_new_error(message
,
1964 DBUS_ERROR_NO_MEMORY
,
1969 *tmp
= tolower(*tmp
);
1973 if (!dbus_message_iter_append_basic(&variant_iter
,
1976 perror("wpas_dbus_getter_state[dbus] out of memory "
1977 "when trying append state");
1978 dbus_message_unref(reply
);
1979 reply
= dbus_message_new_error(message
,
1980 DBUS_ERROR_NO_MEMORY
,
1984 if (!dbus_message_iter_close_container(&iter
, &variant_iter
)) {
1985 perror("wpas_dbus_getter_state[dbus] out of memory "
1986 "when trying close variant");
1987 dbus_message_unref(reply
);
1988 reply
= dbus_message_new_error(message
,
1989 DBUS_ERROR_NO_MEMORY
,
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 DBusMessage
*reply
= NULL
;
2013 DBusMessageIter iter
, variant_iter
;
2014 dbus_bool_t scanning
= wpa_s
->scanning
? TRUE
: FALSE
;
2016 if (message
== NULL
)
2017 reply
= dbus_message_new(DBUS_MESSAGE_TYPE_SIGNAL
);
2019 reply
= dbus_message_new_method_return(message
);
2021 if (reply
!= NULL
) {
2022 dbus_message_iter_init_append(reply
, &iter
);
2023 if (!dbus_message_iter_open_container(&iter
, DBUS_TYPE_VARIANT
,
2024 "b", &variant_iter
) ||
2025 !dbus_message_iter_append_basic(&variant_iter
,
2028 !dbus_message_iter_close_container(&iter
, &variant_iter
)) {
2029 perror("wpas_dbus_getter_scanning[dbus]: out of "
2030 "memory to put scanning state into message.");
2031 dbus_message_unref(reply
);
2032 reply
= dbus_message_new_error(message
,
2033 DBUS_ERROR_NO_MEMORY
,
2037 perror("wpas_dbus_getter_scanning[dbus]: out of "
2038 "memory to return scanning state.");
2039 reply
= dbus_message_new_error(message
, DBUS_ERROR_NO_MEMORY
,
2048 * wpas_dbus_getter_ap_scan - Control roaming mode
2049 * @message: Pointer to incoming dbus message
2050 * @wpa_s: wpa_supplicant structure for a network interface
2051 * Returns: A message containong value of ap_scan variable
2053 * Getter function for "ApScan" property.
2055 DBusMessage
* wpas_dbus_getter_ap_scan(DBusMessage
*message
,
2056 struct wpa_supplicant
*wpa_s
)
2058 DBusMessage
*reply
= NULL
;
2059 DBusMessageIter iter
, variant_iter
;
2060 dbus_uint32_t ap_scan
= wpa_s
->conf
->ap_scan
;
2062 if (message
== NULL
)
2063 reply
= dbus_message_new(DBUS_MESSAGE_TYPE_SIGNAL
);
2065 reply
= dbus_message_new_method_return(message
);
2067 if (reply
!= NULL
) {
2068 dbus_message_iter_init_append(reply
, &iter
);
2069 if (!dbus_message_iter_open_container(&iter
, DBUS_TYPE_VARIANT
,
2070 "u", &variant_iter
) ||
2071 !dbus_message_iter_append_basic(&variant_iter
,
2074 !dbus_message_iter_close_container(&iter
, &variant_iter
)) {
2075 perror("wpas_dbus_getter_ap_scan[dbus]: out of "
2076 "memory to put scanning state into message.");
2077 dbus_message_unref(reply
);
2078 reply
= dbus_message_new_error(message
,
2079 DBUS_ERROR_NO_MEMORY
,
2083 perror("wpas_dbus_getter_ap_scan[dbus]: out of "
2084 "memory to return scanning state.");
2085 reply
= dbus_message_new_error(message
, DBUS_ERROR_NO_MEMORY
,
2094 * wpas_dbus_setter_ap_scan - Control roaming mode
2095 * @message: Pointer to incoming dbus message
2096 * @wpa_s: wpa_supplicant structure for a network interface
2099 * Setter function for "ApScan" property.
2101 DBusMessage
* wpas_dbus_setter_ap_scan(DBusMessage
*message
,
2102 struct wpa_supplicant
*wpa_s
)
2104 DBusMessage
*reply
= NULL
;
2105 DBusMessageIter iter
, variant_iter
;
2106 dbus_uint32_t ap_scan
;
2108 if (!dbus_message_iter_init(message
, &iter
)) {
2109 perror("wpas_dbus_getter_ap_scan[dbus]: out of "
2110 "memory to return scanning state.");
2111 reply
= dbus_message_new_error(message
, DBUS_ERROR_NO_MEMORY
,
2116 /* omit first and second argument and get value from third*/
2117 dbus_message_iter_next(&iter
);
2118 dbus_message_iter_next(&iter
);
2119 dbus_message_iter_recurse(&iter
, &variant_iter
);
2121 if (dbus_message_iter_get_arg_type(&variant_iter
) != DBUS_TYPE_UINT32
)
2123 reply
= wpas_dbus_error_invald_args(message
,
2127 dbus_message_iter_get_basic(&variant_iter
, &ap_scan
);
2129 if (wpa_supplicant_set_ap_scan(wpa_s
, ap_scan
)) {
2130 reply
= wpas_dbus_error_invald_args(
2132 "ap_scan must equal 0, 1 or 2");
2142 * wpas_dbus_getter_ifname - Get interface name
2143 * @message: Pointer to incoming dbus message
2144 * @wpa_s: wpa_supplicant structure for a network interface
2145 * Returns: A dbus message containing a name of network interface
2146 * associated with with wpa_s
2148 * Getter for "Ifname" property.
2150 DBusMessage
* wpas_dbus_getter_ifname(DBusMessage
*message
,
2151 struct wpa_supplicant
*wpa_s
)
2153 DBusMessage
*reply
= NULL
;
2154 DBusMessageIter iter
, variant_iter
;
2155 const char *ifname
= NULL
;
2157 ifname
= wpa_s
->ifname
;
2158 if (ifname
== NULL
) {
2159 wpa_printf(MSG_DEBUG
, "wpas_dbus_getter_ifname[dbus]: "
2160 "wpa_s has no interface name set"");");
2161 return wpas_dbus_error_unknown_error(message
,
2165 if (message
== NULL
)
2166 reply
= dbus_message_new(DBUS_MESSAGE_TYPE_SIGNAL
);
2168 reply
= dbus_message_new_method_return(message
);
2170 if (reply
!= NULL
) {
2171 dbus_message_iter_init_append(reply
, &iter
);
2172 if (!dbus_message_iter_open_container(&iter
, DBUS_TYPE_VARIANT
,
2173 "s", &variant_iter
) ||
2174 !dbus_message_iter_append_basic(&variant_iter
,
2177 !dbus_message_iter_close_container(&iter
, &variant_iter
)) {
2178 perror("wpas_dbus_getter_ifname[dbus]: out of "
2179 "memory to put ifname into message.");
2180 dbus_message_unref(reply
);
2181 reply
= dbus_message_new_error(message
,
2182 DBUS_ERROR_NO_MEMORY
,
2186 perror("wpas_dbus_getter_ifname[dbus]: out of "
2187 "memory to return ifname state.");
2188 reply
= dbus_message_new_error(message
, DBUS_ERROR_NO_MEMORY
,
2197 * wpas_dbus_getter_driver - Get interface name
2198 * @message: Pointer to incoming dbus message
2199 * @wpa_s: wpa_supplicant structure for a network interface
2200 * Returns: A dbus message containing a name of network interface
2201 * driver associated with with wpa_s
2203 * Getter for "Driver" property.
2205 DBusMessage
* wpas_dbus_getter_driver(DBusMessage
*message
,
2206 struct wpa_supplicant
*wpa_s
)
2208 DBusMessage
*reply
= NULL
;
2209 DBusMessageIter iter
, variant_iter
;
2210 const char *driver
= NULL
;
2212 if (wpa_s
->driver
== NULL
|| wpa_s
->driver
->name
== NULL
) {
2213 wpa_printf(MSG_DEBUG
, "wpas_dbus_getter_driver[dbus]: "
2214 "wpa_s has no driver set"");");
2215 return wpas_dbus_error_unknown_error(message
, NULL
);
2218 driver
= wpa_s
->driver
->name
;
2220 if (message
== NULL
)
2221 reply
= dbus_message_new(DBUS_MESSAGE_TYPE_SIGNAL
);
2223 reply
= dbus_message_new_method_return(message
);
2225 if (reply
!= NULL
) {
2226 dbus_message_iter_init_append(reply
, &iter
);
2227 if (!dbus_message_iter_open_container(&iter
, DBUS_TYPE_VARIANT
,
2228 "s", &variant_iter
) ||
2229 !dbus_message_iter_append_basic(&variant_iter
,
2232 !dbus_message_iter_close_container(&iter
, &variant_iter
)) {
2233 perror("wpas_dbus_getter_driver[dbus]: out of "
2234 "memory to put driver into message.");
2235 dbus_message_unref(reply
);
2236 reply
= dbus_message_new_error(message
,
2237 DBUS_ERROR_NO_MEMORY
,
2241 perror("wpas_dbus_getter_driver[dbus]: out of "
2242 "memory to return driver.");
2243 reply
= dbus_message_new_error(message
, DBUS_ERROR_NO_MEMORY
,
2252 * wpas_dbus_getter_current_bss - Get current bss object path
2253 * @message: Pointer to incoming dbus message
2254 * @wpa_s: wpa_supplicant structure for a network interface
2255 * Returns: A dbus message containing a DBus object path to
2258 * Getter for "CurrentBSS" property.
2260 DBusMessage
* wpas_dbus_getter_current_bss(DBusMessage
*message
,
2261 struct wpa_supplicant
*wpa_s
)
2263 DBusMessage
*reply
= NULL
;
2264 DBusMessageIter iter
, variant_iter
;
2265 const char *path
= wpas_dbus_get_path(wpa_s
);
2266 char *bss_obj_path
= os_zalloc(WPAS_DBUS_OBJECT_PATH_MAX
);
2267 struct wpa_bss
*bss
= NULL
;
2269 if (bss_obj_path
== NULL
) {
2270 perror("wpas_dbus_getter_current_bss[dbus]: out of "
2271 "memory to allocate result argument.");
2272 return dbus_message_new_error(message
, DBUS_ERROR_NO_MEMORY
,
2276 /* TODO: store current BSS or BSS id in wpa_s */
2277 if (!is_zero_ether_addr(wpa_s
->bssid
))
2278 bss
= wpa_bss_get_bssid(wpa_s
, wpa_s
->bssid
);
2281 os_snprintf(bss_obj_path
, WPAS_DBUS_OBJECT_PATH_MAX
,
2282 "%s/" WPAS_DBUS_NEW_BSSIDS_PART
"/%u",
2285 os_snprintf(bss_obj_path
, WPAS_DBUS_OBJECT_PATH_MAX
, "/");
2287 if (message
== NULL
)
2288 reply
= dbus_message_new(DBUS_MESSAGE_TYPE_SIGNAL
);
2290 reply
= dbus_message_new_method_return(message
);
2292 if (reply
!= NULL
) {
2293 dbus_message_iter_init_append(reply
, &iter
);
2294 if (!dbus_message_iter_open_container(&iter
, DBUS_TYPE_VARIANT
,
2295 "o", &variant_iter
) ||
2296 !dbus_message_iter_append_basic(&variant_iter
,
2297 DBUS_TYPE_OBJECT_PATH
,
2299 !dbus_message_iter_close_container(&iter
, &variant_iter
)) {
2300 perror("wpas_dbus_getter_current_bss[dbus]: out of "
2301 "memory to put path into message.");
2302 dbus_message_unref(reply
);
2303 reply
= dbus_message_new_error(message
,
2304 DBUS_ERROR_NO_MEMORY
,
2308 perror("wpas_dbus_getter_current_bss[dbus]: out of "
2309 "memory when creating reply.");
2310 reply
= dbus_message_new_error(message
, DBUS_ERROR_NO_MEMORY
,
2314 os_free(bss_obj_path
);
2320 * wpas_dbus_getter_current_network - Get current network object path
2321 * @message: Pointer to incoming dbus message
2322 * @wpa_s: wpa_supplicant structure for a network interface
2323 * Returns: A dbus message containing a DBus object path to
2326 * Getter for "CurrentNetwork" property.
2328 DBusMessage
* wpas_dbus_getter_current_network(DBusMessage
*message
,
2329 struct wpa_supplicant
*wpa_s
)
2331 DBusMessage
*reply
= NULL
;
2332 DBusMessageIter iter
, variant_iter
;
2333 const char *path
= wpas_dbus_get_path(wpa_s
);
2334 char *net_obj_path
= os_zalloc(WPAS_DBUS_OBJECT_PATH_MAX
);
2336 if (net_obj_path
== NULL
) {
2337 perror("wpas_dbus_getter_current_network[dbus]: out of "
2338 "memory to allocate result argument.");
2339 return dbus_message_new_error(message
, DBUS_ERROR_NO_MEMORY
,
2343 if (wpa_s
->current_ssid
)
2344 os_snprintf(net_obj_path
, WPAS_DBUS_OBJECT_PATH_MAX
,
2345 "%s/" WPAS_DBUS_NEW_NETWORKS_PART
"/%u", path
,
2346 wpa_s
->current_ssid
->id
);
2348 os_snprintf(net_obj_path
, WPAS_DBUS_OBJECT_PATH_MAX
, "/");
2350 if (message
== NULL
)
2351 reply
= dbus_message_new(DBUS_MESSAGE_TYPE_SIGNAL
);
2353 reply
= dbus_message_new_method_return(message
);
2355 if (reply
!= NULL
) {
2356 dbus_message_iter_init_append(reply
, &iter
);
2357 if (!dbus_message_iter_open_container(&iter
, DBUS_TYPE_VARIANT
,
2358 "o", &variant_iter
) ||
2359 !dbus_message_iter_append_basic(&variant_iter
,
2360 DBUS_TYPE_OBJECT_PATH
,
2362 !dbus_message_iter_close_container(&iter
, &variant_iter
)) {
2363 perror("wpas_dbus_getter_current_network[dbus]: out "
2364 "of memory to put path into message.");
2365 dbus_message_unref(reply
);
2366 reply
= dbus_message_new_error(message
,
2367 DBUS_ERROR_NO_MEMORY
,
2371 perror("wpas_dbus_getter_current_network[dbus]: out of "
2372 "memory when creating reply.");
2373 reply
= dbus_message_new_error(message
, DBUS_ERROR_NO_MEMORY
,
2377 os_free(net_obj_path
);
2383 * wpas_dbus_getter_bridge_ifname - Get interface name
2384 * @message: Pointer to incoming dbus message
2385 * @wpa_s: wpa_supplicant structure for a network interface
2386 * Returns: A dbus message containing a name of bridge network
2387 * interface associated with with wpa_s
2389 * Getter for "BridgeIfname" property.
2391 DBusMessage
* wpas_dbus_getter_bridge_ifname(DBusMessage
*message
,
2392 struct wpa_supplicant
*wpa_s
)
2394 DBusMessage
*reply
= NULL
;
2395 DBusMessageIter iter
, variant_iter
;
2396 const char *bridge_ifname
= NULL
;
2398 bridge_ifname
= wpa_s
->bridge_ifname
;
2399 if (bridge_ifname
== NULL
) {
2400 wpa_printf(MSG_ERROR
, "wpas_dbus_getter_bridge_ifname[dbus]: "
2401 "wpa_s has no bridge interface name set"");");
2402 return wpas_dbus_error_unknown_error(message
, NULL
);
2405 if (message
== NULL
)
2406 reply
= dbus_message_new(DBUS_MESSAGE_TYPE_SIGNAL
);
2408 reply
= dbus_message_new_method_return(message
);
2410 if (reply
!= NULL
) {
2411 dbus_message_iter_init_append(reply
, &iter
);
2412 if (!dbus_message_iter_open_container(&iter
, DBUS_TYPE_VARIANT
,
2413 "s", &variant_iter
) ||
2414 !dbus_message_iter_append_basic(&variant_iter
,
2417 !dbus_message_iter_close_container(&iter
, &variant_iter
)) {
2418 perror("wpas_dbus_getter_bridge_ifname[dbus]: out of "
2419 "memory to put bridge ifname into message.");
2420 dbus_message_unref(reply
);
2421 reply
= dbus_message_new_error(message
,
2422 DBUS_ERROR_NO_MEMORY
,
2426 perror("wpas_dbus_getter_bridge_ifname[dbus]: out of "
2427 "memory to return bridge ifname.");
2428 reply
= dbus_message_new_error(message
, DBUS_ERROR_NO_MEMORY
,
2437 * wpas_dbus_getter_bsss - Get array of BSSs objects
2438 * @message: Pointer to incoming dbus message
2439 * @wpa_s: wpa_supplicant structure for a network interface
2440 * Returns: a dbus message containing an array of all known BSS objects
2443 * Getter for "BSSs" property.
2445 DBusMessage
* wpas_dbus_getter_bsss(DBusMessage
*message
,
2446 struct wpa_supplicant
*wpa_s
)
2448 DBusMessage
*reply
= NULL
;
2449 DBusMessageIter iter
, variant_iter
, array_iter
;
2450 struct wpa_bss
*bss
;
2452 /* Create and initialize the return message */
2453 if (message
== NULL
)
2454 reply
= dbus_message_new(DBUS_MESSAGE_TYPE_SIGNAL
);
2456 reply
= dbus_message_new_method_return(message
);
2457 if (reply
== NULL
) {
2458 perror("wpas_dbus_getter_bsss[dbus]: out of "
2459 "memory to create return message.");
2460 reply
= dbus_message_new_error(message
, DBUS_ERROR_NO_MEMORY
,
2465 dbus_message_iter_init_append(reply
, &iter
);
2467 if (!dbus_message_iter_open_container(&iter
, DBUS_TYPE_VARIANT
,
2468 "ao", &variant_iter
) ||
2469 !dbus_message_iter_open_container(&variant_iter
, DBUS_TYPE_ARRAY
,
2470 DBUS_TYPE_OBJECT_PATH_AS_STRING
,
2472 perror("wpas_dbus_getter_bsss[dbus]: out of "
2473 "memory to open container.");
2474 dbus_message_unref(reply
);
2475 reply
= dbus_message_new_error(message
, DBUS_ERROR_NO_MEMORY
,
2480 /* Loop through scan results and append each result's object path */
2481 dl_list_for_each(bss
, &wpa_s
->bss_id
, struct wpa_bss
, list_id
) {
2484 path
= os_zalloc(WPAS_DBUS_OBJECT_PATH_MAX
);
2486 perror("wpas_dbus_getter_bsss[dbus]: out of "
2488 dbus_message_unref(reply
);
2489 reply
= dbus_message_new_error(message
,
2490 DBUS_ERROR_NO_MEMORY
,
2494 /* Construct the object path for this BSS. */
2495 os_snprintf(path
, WPAS_DBUS_OBJECT_PATH_MAX
,
2496 "%s/" WPAS_DBUS_NEW_BSSIDS_PART
"/%u",
2497 wpas_dbus_get_path(wpa_s
), bss
->id
);
2498 dbus_message_iter_append_basic(&array_iter
,
2499 DBUS_TYPE_OBJECT_PATH
, &path
);
2503 if (!dbus_message_iter_close_container(&variant_iter
, &array_iter
) ||
2504 !dbus_message_iter_close_container(&iter
, &variant_iter
)) {
2505 perror("wpas_dbus_getter_bsss[dbus]: out of "
2506 "memory to close container.");
2507 dbus_message_unref(reply
);
2508 reply
= dbus_message_new_error(message
, DBUS_ERROR_NO_MEMORY
,
2519 * wpas_dbus_getter_networks - Get array of networks objects
2520 * @message: Pointer to incoming dbus message
2521 * @wpa_s: wpa_supplicant structure for a network interface
2522 * Returns: a dbus message containing an array of all configured
2523 * networks dbus object paths.
2525 * Getter for "Networks" property.
2527 DBusMessage
* wpas_dbus_getter_networks(DBusMessage
*message
,
2528 struct wpa_supplicant
*wpa_s
)
2530 DBusMessage
*reply
= NULL
;
2531 DBusMessageIter iter
, variant_iter
, array_iter
;
2532 struct wpa_ssid
*ssid
;
2534 if (wpa_s
->conf
== NULL
) {
2535 wpa_printf(MSG_ERROR
, "wpas_dbus_getter_networks[dbus]: "
2536 "An error occurred getting networks list.");
2537 return wpas_dbus_error_unknown_error(message
, NULL
);
2540 /* Create and initialize the return message */
2541 if (message
== NULL
)
2542 reply
= dbus_message_new(DBUS_MESSAGE_TYPE_SIGNAL
);
2544 reply
= dbus_message_new_method_return(message
);
2545 if (reply
== NULL
) {
2546 perror("wpas_dbus_getter_networks[dbus]: out of "
2547 "memory to create return message.");
2548 reply
= dbus_message_new_error(message
, DBUS_ERROR_NO_MEMORY
,
2553 dbus_message_iter_init_append(reply
, &iter
);
2555 if (!dbus_message_iter_open_container(&iter
, DBUS_TYPE_VARIANT
,
2556 "ao", &variant_iter
) ||
2557 !dbus_message_iter_open_container(&variant_iter
, DBUS_TYPE_ARRAY
,
2558 DBUS_TYPE_OBJECT_PATH_AS_STRING
,
2560 perror("wpas_dbus_getter_networks[dbus]: out of "
2561 "memory to open container.");
2562 dbus_message_unref(reply
);
2563 reply
= dbus_message_new_error(message
, DBUS_ERROR_NO_MEMORY
,
2568 /* Loop through configured networks and append object path if each */
2569 for (ssid
= wpa_s
->conf
->ssid
; ssid
; ssid
= ssid
->next
) {
2572 path
= os_zalloc(WPAS_DBUS_OBJECT_PATH_MAX
);
2574 perror("wpas_dbus_getter_networks[dbus]: out of "
2576 dbus_message_unref(reply
);
2577 reply
= dbus_message_new_error(message
,
2578 DBUS_ERROR_NO_MEMORY
,
2583 /* Construct the object path for this network. */
2584 os_snprintf(path
, WPAS_DBUS_OBJECT_PATH_MAX
,
2585 "%s/" WPAS_DBUS_NEW_NETWORKS_PART
"/%d",
2586 wpas_dbus_get_path(wpa_s
), ssid
->id
);
2587 dbus_message_iter_append_basic(&array_iter
,
2588 DBUS_TYPE_OBJECT_PATH
, &path
);
2592 if (!dbus_message_iter_close_container(&variant_iter
, &array_iter
) ||
2593 !dbus_message_iter_close_container(&iter
, &variant_iter
)) {
2594 perror("wpas_dbus_getter_networks[dbus]: out of "
2595 "memory to close container.");
2596 dbus_message_unref(reply
);
2597 reply
= dbus_message_new_error(message
, DBUS_ERROR_NO_MEMORY
,
2608 * wpas_dbus_getter_blobs - Get all blobs defined for this interface
2609 * @message: Pointer to incoming dbus message
2610 * @wpa_s: wpa_supplicant structure for a network interface
2611 * Returns: a dbus message containing a dictionary of pairs (blob_name, blob)
2613 * Getter for "Blobs" property.
2615 DBusMessage
* wpas_dbus_getter_blobs(DBusMessage
*message
,
2616 struct wpa_supplicant
*wpa_s
)
2618 DBusMessage
*reply
= NULL
;
2619 DBusMessageIter iter
, variant_iter
, dict_iter
, entry_iter
, array_iter
;
2620 struct wpa_config_blob
*blob
;
2622 if (message
== NULL
)
2623 reply
= dbus_message_new(DBUS_MESSAGE_TYPE_SIGNAL
);
2625 reply
= dbus_message_new_method_return(message
);
2627 perror("wpas_dbus_getter_blobs[dbus] out of memory when "
2628 "trying to initialize return message");
2629 reply
= dbus_message_new_error(message
, DBUS_ERROR_NO_MEMORY
,
2634 dbus_message_iter_init_append(reply
, &iter
);
2636 if (!dbus_message_iter_open_container(&iter
, DBUS_TYPE_VARIANT
,
2637 "a{say}", &variant_iter
)) {
2638 dbus_message_unref(reply
);
2639 perror("wpas_dbus_getter_blobs[dbus] out of memory when "
2640 "trying to open variant");
2641 reply
= dbus_message_new_error(message
, DBUS_ERROR_NO_MEMORY
,
2646 if (!dbus_message_iter_open_container(&variant_iter
, DBUS_TYPE_ARRAY
,
2647 "{say}", &dict_iter
)) {
2648 dbus_message_unref(reply
);
2649 perror("wpas_dbus_getter_blobs[dbus] out of memory when "
2650 "trying to open dictionary");
2651 reply
= dbus_message_new_error(message
, DBUS_ERROR_NO_MEMORY
,
2656 blob
= wpa_s
->conf
->blobs
;
2658 if (!dbus_message_iter_open_container(&dict_iter
,
2659 DBUS_TYPE_DICT_ENTRY
,
2660 NULL
, &entry_iter
)) {
2661 dbus_message_unref(reply
);
2662 perror("wpas_dbus_getter_blobs[dbus] out of memory "
2663 "when trying to open entry");
2664 reply
= dbus_message_new_error(message
,
2665 DBUS_ERROR_NO_MEMORY
,
2670 if (!dbus_message_iter_append_basic(&entry_iter
,
2673 dbus_message_unref(reply
);
2674 perror("wpas_dbus_getter_blobs[dbus] out of memory "
2675 "when trying to append blob name");
2676 reply
= dbus_message_new_error(message
,
2677 DBUS_ERROR_NO_MEMORY
,
2682 if (!dbus_message_iter_open_container(&entry_iter
,
2684 DBUS_TYPE_BYTE_AS_STRING
,
2686 dbus_message_unref(reply
);
2687 perror("wpas_dbus_getter_blobs[dbus] out of memory "
2688 "when trying to open array");
2689 reply
= dbus_message_new_error(message
,
2690 DBUS_ERROR_NO_MEMORY
,
2695 if (!dbus_message_iter_append_fixed_array(&array_iter
,
2699 dbus_message_unref(reply
);
2700 perror("wpas_dbus_getter_blobs[dbus] out of memory "
2701 "when trying to append blob data");
2702 reply
= dbus_message_new_error(message
,
2703 DBUS_ERROR_NO_MEMORY
,
2708 if (!dbus_message_iter_close_container(&entry_iter
,
2710 dbus_message_unref(reply
);
2711 perror("wpas_dbus_getter_blobs[dbus] out of memory "
2712 "when trying to close array");
2713 reply
= dbus_message_new_error(message
,
2714 DBUS_ERROR_NO_MEMORY
,
2719 if (!dbus_message_iter_close_container(&dict_iter
,
2721 dbus_message_unref(reply
);
2722 perror("wpas_dbus_getter_blobs[dbus] out of memory "
2723 "when trying to close entry");
2724 reply
= dbus_message_new_error(message
,
2725 DBUS_ERROR_NO_MEMORY
,
2733 if (!dbus_message_iter_close_container(&variant_iter
, &dict_iter
)) {
2734 dbus_message_unref(reply
);
2735 perror("wpas_dbus_getter_blobs[dbus] out of memory when "
2736 "trying to close dictionary");
2737 reply
= dbus_message_new_error(message
, DBUS_ERROR_NO_MEMORY
,
2742 if (!dbus_message_iter_close_container(&iter
, &variant_iter
)) {
2743 dbus_message_unref(reply
);
2744 perror("wpas_dbus_getter_blobs[dbus] out of memory when "
2745 "trying to close variant");
2746 reply
= dbus_message_new_error(message
, DBUS_ERROR_NO_MEMORY
,
2757 * wpas_dbus_getter_bss_properties - Return the properties of a scanned bss
2758 * @message: Pointer to incoming dbus message
2759 * @bss: a pair of interface describing structure and bss' bssid
2760 * Returns: a dbus message containing the properties for the requested bss
2762 * Getter for "Properties" property.
2764 DBusMessage
* wpas_dbus_getter_bss_properties(DBusMessage
*message
,
2765 struct bss_handler_args
*bss
)
2767 DBusMessage
*reply
= NULL
;
2768 DBusMessageIter iter
, iter_dict
, variant_iter
;
2770 struct wpa_bss
*res
= wpa_bss_get_id(bss
->wpa_s
, bss
->id
);
2775 /* Dump the properties into a dbus message */
2776 if (message
== NULL
)
2777 reply
= dbus_message_new(DBUS_MESSAGE_TYPE_SIGNAL
);
2779 reply
= dbus_message_new_method_return(message
);
2784 dbus_message_iter_init_append(reply
, &iter
);
2786 if (!dbus_message_iter_open_container(&iter
, DBUS_TYPE_VARIANT
,
2787 "a{sv}", &variant_iter
))
2790 if (!wpa_dbus_dict_open_write(&variant_iter
, &iter_dict
))
2793 if (!wpa_dbus_dict_append_byte_array(&iter_dict
, "BSSID",
2794 (const char *) res
->bssid
,
2798 ie
= wpa_bss_get_ie(res
, WLAN_EID_SSID
);
2800 if (!wpa_dbus_dict_append_byte_array(&iter_dict
, "SSID",
2801 (const char *) (ie
+ 2),
2806 ie
= wpa_bss_get_vendor_ie(res
, WPA_IE_VENDOR_TYPE
);
2808 if (!wpa_dbus_dict_append_byte_array(&iter_dict
, "WPAIE",
2814 ie
= wpa_bss_get_ie(res
, WLAN_EID_RSN
);
2816 if (!wpa_dbus_dict_append_byte_array(&iter_dict
, "RSNIE",
2822 ie
= wpa_bss_get_vendor_ie(res
, WPS_IE_VENDOR_TYPE
);
2824 if (!wpa_dbus_dict_append_byte_array(&iter_dict
, "WPSIE",
2831 if (!wpa_dbus_dict_append_int32(&iter_dict
, "Frequency",
2835 if (!wpa_dbus_dict_append_uint16(&iter_dict
, "Capabilities",
2838 if (!(res
->flags
& WPA_SCAN_QUAL_INVALID
) &&
2839 !wpa_dbus_dict_append_int32(&iter_dict
, "Quality", res
->qual
))
2841 if (!(res
->flags
& WPA_SCAN_NOISE_INVALID
) &&
2842 !wpa_dbus_dict_append_int32(&iter_dict
, "Noise", res
->noise
))
2844 if (!(res
->flags
& WPA_SCAN_LEVEL_INVALID
) &&
2845 !wpa_dbus_dict_append_int32(&iter_dict
, "Level", res
->level
))
2847 if (!wpa_dbus_dict_append_int32(&iter_dict
, "MaxRate",
2848 wpa_bss_get_max_rate(res
) * 500000))
2851 if (!wpa_dbus_dict_close_write(&iter
, &iter_dict
))
2858 dbus_message_unref(reply
);
2859 return dbus_message_new_error(message
, DBUS_ERROR_NO_MEMORY
, NULL
);
2864 * wpas_dbus_getter_enabled - Check whether network is enabled or disabled
2865 * @message: Pointer to incoming dbus message
2866 * @wpas_dbus_setter_enabled: wpa_supplicant structure for a network interface
2867 * and wpa_ssid structure for a configured network
2868 * Returns: DBus message with boolean indicating state of configured network
2869 * or DBus error on failure
2871 * Getter for "enabled" property of a configured network.
2873 DBusMessage
* wpas_dbus_getter_enabled(DBusMessage
*message
,
2874 struct network_handler_args
*net
)
2876 DBusMessage
*reply
= NULL
;
2877 DBusMessageIter iter
, variant_iter
;
2879 dbus_bool_t enabled
= net
->ssid
->disabled
? FALSE
: TRUE
;
2881 if (message
== NULL
)
2882 reply
= dbus_message_new(DBUS_MESSAGE_TYPE_SIGNAL
);
2884 reply
= dbus_message_new_method_return(message
);
2886 perror("wpas_dbus_getter_enabled[dbus] out of memory when "
2887 "trying to initialize return message");
2888 reply
= dbus_message_new_error(message
, DBUS_ERROR_NO_MEMORY
,
2893 dbus_message_iter_init_append(reply
, &iter
);
2895 if (!dbus_message_iter_open_container(&iter
, DBUS_TYPE_VARIANT
,
2896 "b", &variant_iter
)) {
2897 dbus_message_unref(reply
);
2898 perror("wpas_dbus_getter_enabled[dbus] out of memory when "
2899 "trying to open variant");
2900 reply
= dbus_message_new_error(message
, DBUS_ERROR_NO_MEMORY
,
2905 if (!dbus_message_iter_append_basic(&variant_iter
,
2906 DBUS_TYPE_BOOLEAN
, &enabled
)) {
2907 dbus_message_unref(reply
);
2908 perror("wpas_dbus_getter_enabled[dbus] out of memory when "
2909 "trying to append value");
2910 reply
= dbus_message_new_error(message
, DBUS_ERROR_NO_MEMORY
,
2915 if (!dbus_message_iter_close_container(&iter
, &variant_iter
)) {
2916 dbus_message_unref(reply
);
2917 perror("wpas_dbus_getter_blobs[dbus] out of memory when "
2918 "trying to close variant");
2919 reply
= dbus_message_new_error(message
, DBUS_ERROR_NO_MEMORY
,
2930 * wpas_dbus_setter_enabled - Mark a configured network as enabled or disabled
2931 * @message: Pointer to incoming dbus message
2932 * @wpas_dbus_setter_enabled: wpa_supplicant structure for a network interface
2933 * and wpa_ssid structure for a configured network
2934 * Returns: NULL indicating success or DBus error on failure
2936 * Setter for "Enabled" property of a configured network.
2938 DBusMessage
* wpas_dbus_setter_enabled(DBusMessage
*message
,
2939 struct network_handler_args
*net
)
2941 DBusMessage
*reply
= NULL
;
2942 DBusMessageIter iter
, variant_iter
;
2944 struct wpa_supplicant
*wpa_s
;
2945 struct wpa_ssid
*ssid
;
2949 if (!dbus_message_iter_init(message
, &iter
)) {
2950 perror("wpas_dbus_setter_enabled[dbus] out of memory when "
2951 "trying to init iterator");
2952 reply
= dbus_message_new_error(message
, DBUS_ERROR_NO_MEMORY
,
2957 dbus_message_iter_next(&iter
);
2958 dbus_message_iter_next(&iter
);
2960 dbus_message_iter_recurse(&iter
, &variant_iter
);
2961 if (dbus_message_iter_get_arg_type(&variant_iter
) !=
2962 DBUS_TYPE_BOOLEAN
) {
2963 perror("wpas_dbus_setter_enabled[dbus] "
2964 "variant content should be boolean");
2965 reply
= dbus_message_new_error(message
,
2966 DBUS_ERROR_INVALID_ARGS
,
2967 "value should be a boolean");
2970 dbus_message_iter_get_basic(&variant_iter
, &enable
);
2976 wpa_supplicant_enable_network(wpa_s
, ssid
);
2978 wpa_supplicant_disable_network(wpa_s
, ssid
);
2986 * wpas_dbus_getter_network_properties - Get options for a configured network
2987 * @message: Pointer to incoming dbus message
2988 * @net: wpa_supplicant structure for a network interface and
2989 * wpa_ssid structure for a configured network
2990 * Returns: DBus message with network properties or DBus error on failure
2992 * Getter for "Properties" property of a configured network.
2994 DBusMessage
* wpas_dbus_getter_network_properties(
2995 DBusMessage
*message
, struct network_handler_args
*net
)
2997 DBusMessage
*reply
= NULL
;
2998 DBusMessageIter iter
, variant_iter
, dict_iter
;
3000 char **props
= wpa_config_get_all(net
->ssid
, 0);
3002 perror("wpas_dbus_getter_network_properties[dbus] couldn't "
3003 "read network properties. out of memory.");
3004 return dbus_message_new_error(message
, DBUS_ERROR_NO_MEMORY
,
3008 if (message
== NULL
)
3009 reply
= dbus_message_new(DBUS_MESSAGE_TYPE_SIGNAL
);
3011 reply
= dbus_message_new_method_return(message
);
3013 perror("wpas_dbus_getter_network_properties[dbus] out of "
3014 "memory when trying to initialize return message");
3015 reply
= dbus_message_new_error(message
, DBUS_ERROR_NO_MEMORY
,
3020 dbus_message_iter_init_append(reply
, &iter
);
3022 if (!dbus_message_iter_open_container(&iter
, DBUS_TYPE_VARIANT
,
3023 "a{sv}", &variant_iter
)) {
3024 perror("wpas_dbus_getter_network_properties[dbus] out of "
3025 "memory when trying to open variant container");
3026 dbus_message_unref(reply
);
3027 reply
= dbus_message_new_error(message
, DBUS_ERROR_NO_MEMORY
,
3032 if (!wpa_dbus_dict_open_write(&variant_iter
, &dict_iter
)) {
3033 perror("wpas_dbus_getter_network_properties[dbus] out of "
3034 "memory when trying to open dict");
3035 dbus_message_unref(reply
);
3036 reply
= dbus_message_new_error(message
, DBUS_ERROR_NO_MEMORY
,
3043 if (!wpa_dbus_dict_append_string(&dict_iter
, *iterator
,
3045 perror("wpas_dbus_getter_network_properties[dbus] out "
3046 "of memory when trying to add entry");
3047 dbus_message_unref(reply
);
3048 reply
= dbus_message_new_error(message
,
3049 DBUS_ERROR_NO_MEMORY
,
3057 if (!wpa_dbus_dict_close_write(&variant_iter
, &dict_iter
)) {
3058 perror("wpas_dbus_getter_network_properties[dbus] out of "
3059 "memory when trying to close dictionary");
3060 dbus_message_unref(reply
);
3061 reply
= dbus_message_new_error(message
, DBUS_ERROR_NO_MEMORY
,
3066 if (!dbus_message_iter_close_container(&iter
, &variant_iter
)) {
3067 perror("wpas_dbus_getter_network_properties[dbus] out of "
3068 "memory when trying to close variant container");
3069 dbus_message_unref(reply
);
3070 reply
= dbus_message_new_error(message
, DBUS_ERROR_NO_MEMORY
,
3087 * wpas_dbus_setter_network_properties - Set options for a configured network
3088 * @message: Pointer to incoming dbus message
3089 * @net: wpa_supplicant structure for a network interface and
3090 * wpa_ssid structure for a configured network
3091 * Returns: NULL indicating success or DBus error on failure
3093 * Setter for "Properties" property of a configured network.
3095 DBusMessage
* wpas_dbus_setter_network_properties(
3096 DBusMessage
*message
, struct network_handler_args
*net
)
3098 struct wpa_ssid
*ssid
= net
->ssid
;
3100 DBusMessage
*reply
= NULL
;
3101 DBusMessageIter iter
, variant_iter
;
3103 dbus_message_iter_init(message
, &iter
);
3105 dbus_message_iter_next(&iter
);
3106 dbus_message_iter_next(&iter
);
3108 dbus_message_iter_recurse(&iter
, &variant_iter
);
3110 reply
= set_network_properties(message
, ssid
, &variant_iter
);
3112 wpa_printf(MSG_DEBUG
, "dbus control interface couldn't set "
3113 "network properties");