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);
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 return wpas_dbus_error_invald_args(message,
437 "wrong property type");
439 dbus_message_iter_get_basic(&variant_iter, val);
446 * wpas_dbus_simple_array_property_getter - Get array type property
447 * @message: Pointer to incoming dbus message
448 * @type: DBus type of property array elements (must be basic type)
449 * @array: pointer to array of elements to put into response message
450 * @array_len: length of above array
451 * Returns: The DBus message containing response for Properties.Get call
452 * or DBus error message if error occurred.
454 * Generic getter for array type properties. Array elements type is
455 * required to be basic.
457 DBusMessage * wpas_dbus_simple_array_property_getter(DBusMessage *message,
462 DBusMessage *reply = NULL;
463 DBusMessageIter iter, variant_iter, array_iter;
464 char type_str[] = "a?"; /* ? will be replaced with subtype letter; */
465 const char *sub_type_str;
466 size_t element_size, i;
468 if (!dbus_type_is_basic(type)) {
469 wpa_printf(MSG_ERROR, "dbus: "
470 "wpas_dbus_simple_array_property_getter: given "
471 "type is not basic");
472 return wpas_dbus_error_unknown_error(message, NULL);
475 sub_type_str = _get_dbus_type_as_string(type);
476 type_str[1] = sub_type_str[0];
479 reply = dbus_message_new(DBUS_MESSAGE_TYPE_SIGNAL);
481 reply = dbus_message_new_method_return(message);
483 wpa_printf(MSG_ERROR, "dbus: "
484 "wpas_dbus_simple_array_property_getter: out of "
485 "memory to create return message");
486 return dbus_message_new_error(message, DBUS_ERROR_NO_MEMORY,
490 dbus_message_iter_init_append(reply, &iter);
492 if (!dbus_message_iter_open_container(&iter, DBUS_TYPE_VARIANT,
493 type_str, &variant_iter) ||
494 !dbus_message_iter_open_container(&variant_iter, DBUS_TYPE_ARRAY,
495 sub_type_str, &array_iter)) {
496 wpa_printf(MSG_ERROR, "dbus: "
497 "wpas_dbus_simple_array_property_getter: out of "
498 "memory to open container");
499 dbus_message_unref(reply);
500 return dbus_message_new_error(message, DBUS_ERROR_NO_MEMORY,
506 case DBUS_TYPE_BOOLEAN:
509 case DBUS_TYPE_INT16:
510 case DBUS_TYPE_UINT16:
511 element_size = sizeof(uint16_t);
513 case DBUS_TYPE_INT32:
514 case DBUS_TYPE_UINT32:
515 element_size = sizeof(uint32_t);
517 case DBUS_TYPE_INT64:
518 case DBUS_TYPE_UINT64:
519 element_size = sizeof(uint64_t);
521 case DBUS_TYPE_DOUBLE:
522 element_size = sizeof(double);
524 case DBUS_TYPE_STRING:
525 case DBUS_TYPE_OBJECT_PATH:
526 element_size = sizeof(char *);
529 wpa_printf(MSG_ERROR, "dbus: "
530 "wpas_dbus_simple_array_property_getter: "
531 "fatal: unknown element type");
536 for (i = 0; i < array_len; i++) {
537 dbus_message_iter_append_basic(&array_iter, type,
538 array + i * element_size);
541 if (!dbus_message_iter_close_container(&variant_iter, &array_iter) ||
542 !dbus_message_iter_close_container(&iter, &variant_iter)) {
543 wpa_printf(MSG_ERROR, "dbus: "
544 "wpas_dbus_simple_array_property_getter: out of "
545 "memory to close container");
546 dbus_message_unref(reply);
547 return dbus_message_new_error(message, DBUS_ERROR_NO_MEMORY,
556 * wpas_dbus_handler_create_interface - Request registration of a network iface
557 * @message: Pointer to incoming dbus message
558 * @global: %wpa_supplicant global data structure
559 * Returns: The object path of the new interface object,
560 * or a dbus error message with more information
562 * Handler function for "CreateInterface" method call. Handles requests
563 * by dbus clients to register a network interface that wpa_supplicant
566 DBusMessage * wpas_dbus_handler_create_interface(DBusMessage *message,
567 struct wpa_global *global)
569 DBusMessageIter iter_dict;
570 DBusMessage *reply = NULL;
571 DBusMessageIter iter;
572 struct wpa_dbus_dict_entry entry;
575 char *bridge_ifname = NULL;
577 dbus_message_iter_init(message, &iter);
579 if (!wpa_dbus_dict_open_read(&iter, &iter_dict))
581 while (wpa_dbus_dict_has_dict_entry(&iter_dict)) {
582 if (!wpa_dbus_dict_get_entry(&iter_dict, &entry))
584 if (!strcmp(entry.key, "Driver") &&
585 (entry.type == DBUS_TYPE_STRING)) {
586 driver = os_strdup(entry.str_value);
587 wpa_dbus_dict_entry_clear(&entry);
590 } else if (!strcmp(entry.key, "Ifname") &&
591 (entry.type == DBUS_TYPE_STRING)) {
592 ifname = os_strdup(entry.str_value);
593 wpa_dbus_dict_entry_clear(&entry);
596 } else if (!strcmp(entry.key, "BridgeIfname") &&
597 (entry.type == DBUS_TYPE_STRING)) {
598 bridge_ifname = os_strdup(entry.str_value);
599 wpa_dbus_dict_entry_clear(&entry);
600 if (bridge_ifname == NULL)
603 wpa_dbus_dict_entry_clear(&entry);
609 goto error; /* Required Ifname argument missing */
612 * Try to get the wpa_supplicant record for this iface, return
613 * an error if we already control it.
615 if (wpa_supplicant_get_iface(global, ifname) != NULL) {
616 reply = dbus_message_new_error(message,
617 WPAS_DBUS_ERROR_IFACE_EXISTS,
618 "wpa_supplicant already "
619 "controls this interface.");
621 struct wpa_supplicant *wpa_s;
622 struct wpa_interface iface;
623 os_memset(&iface, 0, sizeof(iface));
624 iface.driver = driver;
625 iface.ifname = ifname;
626 iface.bridge_ifname = bridge_ifname;
627 /* Otherwise, have wpa_supplicant attach to it. */
628 if ((wpa_s = wpa_supplicant_add_iface(global, &iface))) {
629 const char *path = wpas_dbus_get_path(wpa_s);
630 reply = dbus_message_new_method_return(message);
631 dbus_message_append_args(reply, DBUS_TYPE_OBJECT_PATH,
632 &path, DBUS_TYPE_INVALID);
634 reply = wpas_dbus_error_unknown_error(
635 message, "wpa_supplicant couldn't grab this "
643 os_free(bridge_ifname);
647 reply = wpas_dbus_error_invald_args(message, NULL);
653 * wpas_dbus_handler_remove_interface - Request deregistration of an interface
654 * @message: Pointer to incoming dbus message
655 * @global: wpa_supplicant global data structure
656 * Returns: a dbus message containing a UINT32 indicating success (1) or
657 * failure (0), or returns a dbus error message with more information
659 * Handler function for "removeInterface" method call. Handles requests
660 * by dbus clients to deregister a network interface that wpa_supplicant
663 DBusMessage * wpas_dbus_handler_remove_interface(DBusMessage *message,
664 struct wpa_global *global)
666 struct wpa_supplicant *wpa_s;
668 DBusMessage *reply = NULL;
670 dbus_message_get_args(message, NULL, DBUS_TYPE_OBJECT_PATH, &path,
673 wpa_s = get_iface_by_dbus_path(global, path);
675 reply = wpas_dbus_error_iface_unknown(message);
676 else if (wpa_supplicant_remove_iface(global, wpa_s)) {
677 reply = wpas_dbus_error_unknown_error(
678 message, "wpa_supplicant couldn't remove this "
687 * wpas_dbus_handler_get_interface - Get the object path for an interface name
688 * @message: Pointer to incoming dbus message
689 * @global: %wpa_supplicant global data structure
690 * Returns: The object path of the interface object,
691 * or a dbus error message with more information
693 * Handler function for "getInterface" method call.
695 DBusMessage * wpas_dbus_handler_get_interface(DBusMessage *message,
696 struct wpa_global *global)
698 DBusMessage *reply = NULL;
701 struct wpa_supplicant *wpa_s;
703 dbus_message_get_args(message, NULL, DBUS_TYPE_STRING, &ifname,
706 wpa_s = wpa_supplicant_get_iface(global, ifname);
708 return wpas_dbus_error_iface_unknown(message);
710 path = wpas_dbus_get_path(wpa_s);
712 wpa_printf(MSG_ERROR, "wpas_dbus_handler_get_interface[dbus]: "
713 "interface has no dbus object path set");
714 return wpas_dbus_error_unknown_error(message, "path not set");
717 reply = dbus_message_new_method_return(message);
719 perror("wpas_dbus_handler_get_interface[dbus]: out of memory "
720 "when creating reply");
721 return dbus_message_new_error(message, DBUS_ERROR_NO_MEMORY,
724 if (!dbus_message_append_args(reply, DBUS_TYPE_OBJECT_PATH, &path,
725 DBUS_TYPE_INVALID)) {
726 perror("wpas_dbus_handler_get_interface[dbus]: out of memory "
727 "when appending argument to reply");
728 dbus_message_unref(reply);
729 return dbus_message_new_error(message, DBUS_ERROR_NO_MEMORY,
738 * wpas_dbus_getter_debug_level - Get debug level
739 * @message: Pointer to incoming dbus message
740 * @global: %wpa_supplicant global data structure
741 * Returns: DBus message with value of debug level
743 * Getter for "DebugLevel" property.
745 DBusMessage * wpas_dbus_getter_debug_level(DBusMessage *message,
746 struct wpa_global *global)
748 return wpas_dbus_simple_property_getter(message, DBUS_TYPE_BYTE,
755 * wpas_dbus_getter_debug_timestamp - Get debug timestamp
756 * @message: Pointer to incoming dbus message
757 * @global: %wpa_supplicant global data structure
758 * Returns: DBus message with value of debug timestamp
760 * Getter for "DebugTimestamp" property.
762 DBusMessage * wpas_dbus_getter_debug_timestamp(DBusMessage *message,
763 struct wpa_global *global)
765 return wpas_dbus_simple_property_getter(message, DBUS_TYPE_BOOLEAN,
766 &wpa_debug_timestamp);
772 * wpas_dbus_getter_debug_show_keys - Get debug show keys
773 * @message: Pointer to incoming dbus message
774 * @global: %wpa_supplicant global data structure
775 * Returns: DBus message with value of debug show_keys
777 * Getter for "DebugShowKeys" property.
779 DBusMessage * wpas_dbus_getter_debug_show_keys(DBusMessage *message,
780 struct wpa_global *global)
782 return wpas_dbus_simple_property_getter(message, DBUS_TYPE_BOOLEAN,
783 &wpa_debug_show_keys);
788 * wpas_dbus_setter_debug_level - Set debug level
789 * @message: Pointer to incoming dbus message
790 * @global: %wpa_supplicant global data structure
791 * Returns: %NULL or DBus error message
793 * Setter for "DebugLevel" property.
795 DBusMessage * wpas_dbus_setter_debug_level(DBusMessage *message,
796 struct wpa_global *global)
798 DBusMessage *reply = NULL;
801 reply = wpas_dbus_simple_property_setter(message, DBUS_TYPE_INT16,
806 if (wpa_supplicant_set_debug_params(global, val, wpa_debug_timestamp,
807 wpa_debug_show_keys)) {
808 dbus_message_unref(reply);
809 return wpas_dbus_error_invald_args(
810 message, "Wrong debug level value");
818 * wpas_dbus_setter_debug_timestamp - Set debug timestamp
819 * @message: Pointer to incoming dbus message
820 * @global: %wpa_supplicant global data structure
821 * Returns: %NULL or DBus error message
823 * Setter for "DebugTimestamp" property.
825 DBusMessage * wpas_dbus_setter_debug_timestamp(DBusMessage *message,
826 struct wpa_global *global)
828 DBusMessage *reply = NULL;
831 reply = wpas_dbus_simple_property_setter(message, DBUS_TYPE_BOOLEAN,
836 wpa_supplicant_set_debug_params(global, wpa_debug_level, val ? 1 : 0,
837 wpa_debug_show_keys);
844 * wpas_dbus_setter_debug_show_keys - Set debug show keys
845 * @message: Pointer to incoming dbus message
846 * @global: %wpa_supplicant global data structure
847 * Returns: %NULL or DBus error message
849 * Setter for "DebugShowKeys" property.
851 DBusMessage * wpas_dbus_setter_debug_show_keys(DBusMessage *message,
852 struct wpa_global *global)
854 DBusMessage *reply = NULL;
857 reply = wpas_dbus_simple_property_setter(message, DBUS_TYPE_BOOLEAN,
862 wpa_supplicant_set_debug_params(global, wpa_debug_level,
871 * wpas_dbus_getter_interfaces - Request registered interfaces list
872 * @message: Pointer to incoming dbus message
873 * @global: %wpa_supplicant global data structure
874 * Returns: The object paths array containing registered interfaces
875 * objects paths or DBus error on failure
877 * Getter for "Interfaces" property. Handles requests
878 * by dbus clients to return list of registered interfaces objects
881 DBusMessage * wpas_dbus_getter_interfaces(DBusMessage *message,
882 struct wpa_global *global)
884 DBusMessage *reply = NULL;
885 struct wpa_supplicant *wpa_s;
887 unsigned int i = 0, num = 0;
889 for (wpa_s = global->ifaces; wpa_s; wpa_s = wpa_s->next)
892 paths = os_zalloc(num * sizeof(char*));
894 return dbus_message_new_error(message, DBUS_ERROR_NO_MEMORY,
898 for (wpa_s = global->ifaces; wpa_s; wpa_s = wpa_s->next)
899 paths[i] = wpas_dbus_get_path(wpa_s);
901 reply = wpas_dbus_simple_array_property_getter(message,
902 DBUS_TYPE_OBJECT_PATH,
911 * wpas_dbus_getter_eap_methods - Request supported EAP methods list
912 * @message: Pointer to incoming dbus message
913 * @nothing: not used argument. may be NULL or anything else
914 * Returns: The object paths array containing supported EAP methods
915 * represented by strings or DBus error on failure
917 * Getter for "EapMethods" property. Handles requests
918 * by dbus clients to return list of strings with supported EAP methods
920 DBusMessage * wpas_dbus_getter_eap_methods(DBusMessage *message, void *nothing)
922 DBusMessage *reply = NULL;
924 size_t num_items = 0;
926 eap_methods = eap_get_names_as_string_array(&num_items);
928 return dbus_message_new_error(message, DBUS_ERROR_NO_MEMORY,
932 reply = wpas_dbus_simple_array_property_getter(message,
934 eap_methods, num_items);
937 os_free(eap_methods[--num_items]);
938 os_free(eap_methods);
943 static int wpas_dbus_get_scan_type(DBusMessage *message, DBusMessageIter *var,
944 char **type, DBusMessage **reply)
946 if (dbus_message_iter_get_arg_type(var) != DBUS_TYPE_STRING) {
947 wpa_printf(MSG_DEBUG, "wpas_dbus_handler_scan[dbus]: "
948 "Type must be a string");
949 *reply = wpas_dbus_error_invald_args(
950 message, "Wrong Type value type. String required");
953 dbus_message_iter_get_basic(var, type);
958 static int wpas_dbus_get_scan_ssids(DBusMessage *message, DBusMessageIter *var,
959 struct wpa_driver_scan_params *params,
962 struct wpa_driver_scan_ssid *ssids = params->ssids;
963 size_t ssids_num = 0;
965 DBusMessageIter array_iter, sub_array_iter;
969 if (dbus_message_iter_get_arg_type(var) != DBUS_TYPE_ARRAY) {
970 wpa_printf(MSG_DEBUG, "wpas_dbus_handler_scan[dbus]: ssids "
971 "must be an array of arrays of bytes");
972 *reply = wpas_dbus_error_invald_args(
973 message, "Wrong SSIDs value type. Array of arrays of "
978 dbus_message_iter_recurse(var, &array_iter);
980 if (dbus_message_iter_get_arg_type(&array_iter) != DBUS_TYPE_ARRAY ||
981 dbus_message_iter_get_element_type(&array_iter) != DBUS_TYPE_BYTE)
983 wpa_printf(MSG_DEBUG, "wpas_dbus_handler_scan[dbus]: ssids "
984 "must be an array of arrays of bytes");
985 *reply = wpas_dbus_error_invald_args(
986 message, "Wrong SSIDs value type. Array of arrays of "
991 while (dbus_message_iter_get_arg_type(&array_iter) == DBUS_TYPE_ARRAY)
993 if (ssids_num >= WPAS_MAX_SCAN_SSIDS) {
994 wpa_printf(MSG_DEBUG, "wpas_dbus_handler_scan[dbus]: "
995 "Too many ssids specified on scan dbus "
997 *reply = wpas_dbus_error_invald_args(
998 message, "Too many ssids specified. Specify "
1003 dbus_message_iter_recurse(&array_iter, &sub_array_iter);
1005 dbus_message_iter_get_fixed_array(&sub_array_iter, &val, &len);
1007 dbus_message_iter_next(&array_iter);
1011 ssid = os_malloc(len);
1013 wpa_printf(MSG_DEBUG, "wpas_dbus_handler_scan[dbus]: "
1014 "out of memory. Cannot allocate memory for "
1016 *reply = dbus_message_new_error(
1017 message, DBUS_ERROR_NO_MEMORY, NULL);
1020 os_memcpy(ssid, val, len);
1021 ssids[ssids_num].ssid = ssid;
1022 ssids[ssids_num].ssid_len = len;
1024 dbus_message_iter_next(&array_iter);
1028 params->num_ssids = ssids_num;
1033 static int wpas_dbus_get_scan_ies(DBusMessage *message, DBusMessageIter *var,
1034 struct wpa_driver_scan_params *params,
1035 DBusMessage **reply)
1037 u8 *ies = NULL, *nies;
1039 DBusMessageIter array_iter, sub_array_iter;
1043 if (dbus_message_iter_get_arg_type(var) != DBUS_TYPE_ARRAY) {
1044 wpa_printf(MSG_DEBUG, "wpas_dbus_handler_scan[dbus]: ies must "
1045 "be an array of arrays of bytes");
1046 *reply = wpas_dbus_error_invald_args(
1047 message, "Wrong IEs value type. Array of arrays of "
1052 dbus_message_iter_recurse(var, &array_iter);
1054 if (dbus_message_iter_get_arg_type(&array_iter) != DBUS_TYPE_ARRAY ||
1055 dbus_message_iter_get_element_type(&array_iter) != DBUS_TYPE_BYTE)
1057 wpa_printf(MSG_DEBUG, "wpas_dbus_handler_scan[dbus]: ies must "
1058 "be an array of arrays of bytes");
1059 *reply = wpas_dbus_error_invald_args(
1060 message, "Wrong IEs value type. Array required");
1064 while (dbus_message_iter_get_arg_type(&array_iter) == DBUS_TYPE_ARRAY)
1066 dbus_message_iter_recurse(&array_iter, &sub_array_iter);
1068 dbus_message_iter_get_fixed_array(&sub_array_iter, &val, &len);
1070 dbus_message_iter_next(&array_iter);
1074 nies = os_realloc(ies, ies_len + len);
1076 wpa_printf(MSG_DEBUG, "wpas_dbus_handler_scan[dbus]: "
1077 "out of memory. Cannot allocate memory for "
1080 *reply = dbus_message_new_error(
1081 message, DBUS_ERROR_NO_MEMORY, NULL);
1085 os_memcpy(ies + ies_len, val, len);
1088 dbus_message_iter_next(&array_iter);
1091 params->extra_ies = ies;
1092 params->extra_ies_len = ies_len;
1097 static int wpas_dbus_get_scan_channels(DBusMessage *message,
1098 DBusMessageIter *var,
1099 struct wpa_driver_scan_params *params,
1100 DBusMessage **reply)
1102 DBusMessageIter array_iter, sub_array_iter;
1103 int *freqs = NULL, *nfreqs;
1106 if (dbus_message_iter_get_arg_type(var) != DBUS_TYPE_ARRAY) {
1107 wpa_printf(MSG_DEBUG, "wpas_dbus_handler_scan[dbus]: "
1108 "Channels must be an array of structs");
1109 *reply = wpas_dbus_error_invald_args(
1110 message, "Wrong Channels value type. Array of structs "
1115 dbus_message_iter_recurse(var, &array_iter);
1117 if (dbus_message_iter_get_arg_type(&array_iter) != DBUS_TYPE_STRUCT) {
1118 wpa_printf(MSG_DEBUG,
1119 "wpas_dbus_handler_scan[dbus]: Channels must be an "
1120 "array of structs");
1121 *reply = wpas_dbus_error_invald_args(
1122 message, "Wrong Channels value type. Array of structs "
1127 while (dbus_message_iter_get_arg_type(&array_iter) == DBUS_TYPE_STRUCT)
1131 dbus_message_iter_recurse(&array_iter, &sub_array_iter);
1133 if (dbus_message_iter_get_arg_type(&sub_array_iter) !=
1135 wpa_printf(MSG_DEBUG, "wpas_dbus_handler_scan[dbus]: "
1136 "Channel must by specified by struct of "
1138 dbus_message_iter_get_arg_type(
1140 *reply = wpas_dbus_error_invald_args(
1141 message, "Wrong Channel struct. Two UINT32s "
1146 dbus_message_iter_get_basic(&sub_array_iter, &freq);
1148 if (!dbus_message_iter_next(&sub_array_iter) ||
1149 dbus_message_iter_get_arg_type(&sub_array_iter) !=
1151 wpa_printf(MSG_DEBUG, "wpas_dbus_handler_scan[dbus]: "
1152 "Channel must by specified by struct of "
1154 *reply = wpas_dbus_error_invald_args(
1156 "Wrong Channel struct. Two UINT32s required");
1161 dbus_message_iter_get_basic(&sub_array_iter, &width);
1163 #define FREQS_ALLOC_CHUNK 32
1164 if (freqs_num % FREQS_ALLOC_CHUNK == 0) {
1165 nfreqs = os_realloc(freqs, sizeof(int) *
1166 (freqs_num + FREQS_ALLOC_CHUNK));
1171 if (freqs == NULL) {
1172 wpa_printf(MSG_DEBUG, "wpas_dbus_handler_scan[dbus]: "
1173 "out of memory. can't allocate memory for "
1175 *reply = dbus_message_new_error(
1176 message, DBUS_ERROR_NO_MEMORY, NULL);
1180 freqs[freqs_num] = freq;
1183 dbus_message_iter_next(&array_iter);
1186 nfreqs = os_realloc(freqs,
1187 sizeof(int) * (freqs_num + 1));
1191 if (freqs == NULL) {
1192 wpa_printf(MSG_DEBUG, "wpas_dbus_handler_scan[dbus]: "
1193 "out of memory. Can't allocate memory for freqs");
1194 *reply = dbus_message_new_error(
1195 message, DBUS_ERROR_NO_MEMORY, NULL);
1198 freqs[freqs_num] = 0;
1200 params->freqs = freqs;
1206 * wpas_dbus_handler_scan - Request a wireless scan on an interface
1207 * @message: Pointer to incoming dbus message
1208 * @wpa_s: wpa_supplicant structure for a network interface
1209 * Returns: NULL indicating success or DBus error message on failure
1211 * Handler function for "Scan" method call of a network device. Requests
1212 * that wpa_supplicant perform a wireless scan as soon as possible
1213 * on a particular wireless interface.
1215 DBusMessage * wpas_dbus_handler_scan(DBusMessage *message,
1216 struct wpa_supplicant *wpa_s)
1218 DBusMessage *reply = NULL;
1219 DBusMessageIter iter, dict_iter, entry_iter, variant_iter;
1220 char *key = NULL, *type = NULL;
1221 struct wpa_driver_scan_params params;
1224 os_memset(¶ms, 0, sizeof(params));
1226 dbus_message_iter_init(message, &iter);
1228 dbus_message_iter_recurse(&iter, &dict_iter);
1230 while (dbus_message_iter_get_arg_type(&dict_iter) ==
1231 DBUS_TYPE_DICT_ENTRY) {
1232 dbus_message_iter_recurse(&dict_iter, &entry_iter);
1233 dbus_message_iter_get_basic(&entry_iter, &key);
1234 dbus_message_iter_next(&entry_iter);
1235 dbus_message_iter_recurse(&entry_iter, &variant_iter);
1237 if (os_strcmp(key, "Type") == 0) {
1238 if (wpas_dbus_get_scan_type(message, &variant_iter,
1241 } else if (os_strcmp(key, "SSIDs") == 0) {
1242 if (wpas_dbus_get_scan_ssids(message, &variant_iter,
1243 ¶ms, &reply) < 0)
1245 } else if (os_strcmp(key, "IEs") == 0) {
1246 if (wpas_dbus_get_scan_ies(message, &variant_iter,
1247 ¶ms, &reply) < 0)
1249 } else if (os_strcmp(key, "Channels") == 0) {
1250 if (wpas_dbus_get_scan_channels(message, &variant_iter,
1251 ¶ms, &reply) < 0)
1254 wpa_printf(MSG_DEBUG, "wpas_dbus_handler_scan[dbus]: "
1255 "Unknown argument %s", key);
1256 reply = wpas_dbus_error_invald_args(message, key);
1260 dbus_message_iter_next(&dict_iter);
1264 wpa_printf(MSG_DEBUG, "wpas_dbus_handler_scan[dbus]: "
1265 "Scan type not specified");
1266 reply = wpas_dbus_error_invald_args(message, key);
1270 if (!os_strcmp(type, "passive")) {
1271 if (params.num_ssids || params.extra_ies_len) {
1272 wpa_printf(MSG_DEBUG, "wpas_dbus_handler_scan[dbus]: "
1273 "SSIDs or IEs specified for passive scan.");
1274 reply = wpas_dbus_error_invald_args(
1275 message, "You can specify only Channels in "
1278 } else if (params.freqs && params.freqs[0]) {
1281 wpa_supplicant_trigger_scan(wpa_s, ¶ms);
1283 wpa_s->scan_req = 2;
1284 wpa_supplicant_req_scan(wpa_s, 0, 0);
1286 } else if (!os_strcmp(type, "active")) {
1287 wpa_supplicant_trigger_scan(wpa_s, ¶ms);
1289 wpa_printf(MSG_DEBUG, "wpas_dbus_handler_scan[dbus]: "
1290 "Unknown scan type: %s", type);
1291 reply = wpas_dbus_error_invald_args(message,
1297 for (i = 0; i < WPAS_MAX_SCAN_SSIDS; i++)
1298 os_free((u8 *) params.ssids[i].ssid);
1299 os_free((u8 *) params.extra_ies);
1300 os_free(params.freqs);
1306 * wpas_dbus_handler_disconnect - Terminate the current connection
1307 * @message: Pointer to incoming dbus message
1308 * @wpa_s: wpa_supplicant structure for a network interface
1309 * Returns: NotConnected DBus error message if already not connected
1310 * or NULL otherwise.
1312 * Handler function for "Disconnect" method call of network interface.
1314 DBusMessage * wpas_dbus_handler_disconnect(DBusMessage *message,
1315 struct wpa_supplicant *wpa_s)
1317 if (wpa_s->current_ssid != NULL) {
1318 wpa_s->disconnected = 1;
1319 wpa_supplicant_disassociate(wpa_s, WLAN_REASON_DEAUTH_LEAVING);
1324 return dbus_message_new_error(message, WPAS_DBUS_ERROR_NOT_CONNECTED,
1325 "This interface is not connected");
1330 * wpas_dbus_new_iface_add_network - Add a new configured network
1331 * @message: Pointer to incoming dbus message
1332 * @wpa_s: wpa_supplicant structure for a network interface
1333 * Returns: A dbus message containing the object path of the new network
1335 * Handler function for "AddNetwork" method call of a network interface.
1337 DBusMessage * wpas_dbus_handler_add_network(DBusMessage *message,
1338 struct wpa_supplicant *wpa_s)
1340 DBusMessage *reply = NULL;
1341 DBusMessageIter iter;
1342 struct wpa_ssid *ssid = NULL;
1345 path = os_zalloc(WPAS_DBUS_OBJECT_PATH_MAX);
1347 perror("wpas_dbus_handler_add_network[dbus]: out of "
1349 reply = dbus_message_new_error(message, DBUS_ERROR_NO_MEMORY,
1354 dbus_message_iter_init(message, &iter);
1356 ssid = wpa_config_add_network(wpa_s->conf);
1358 wpa_printf(MSG_ERROR, "wpas_dbus_handler_add_network[dbus]: "
1359 "can't add new interface.");
1360 reply = wpas_dbus_error_unknown_error(
1362 "wpa_supplicant could not add "
1363 "a network on this interface.");
1366 wpas_notify_network_added(wpa_s, ssid);
1368 wpa_config_set_network_defaults(ssid);
1370 reply = set_network_properties(message, ssid, &iter);
1372 wpa_printf(MSG_DEBUG, "wpas_dbus_handler_add_network[dbus]:"
1373 "control interface couldn't set network "
1378 /* Construct the object path for this network. */
1379 os_snprintf(path, WPAS_DBUS_OBJECT_PATH_MAX,
1380 "%s/" WPAS_DBUS_NEW_NETWORKS_PART "/%d",
1381 wpas_dbus_get_path(wpa_s),
1384 reply = dbus_message_new_method_return(message);
1385 if (reply == NULL) {
1386 perror("wpas_dbus_handler_add_network[dbus]: out of memory "
1387 "when creating reply");
1388 reply = dbus_message_new_error(message, DBUS_ERROR_NO_MEMORY,
1392 if (!dbus_message_append_args(reply, DBUS_TYPE_OBJECT_PATH, &path,
1393 DBUS_TYPE_INVALID)) {
1394 perror("wpas_dbus_handler_add_network[dbus]: out of memory "
1395 "when appending argument to reply");
1396 dbus_message_unref(reply);
1397 reply = dbus_message_new_error(message, DBUS_ERROR_NO_MEMORY,
1407 wpas_notify_network_removed(wpa_s, ssid);
1408 wpa_config_remove_network(wpa_s->conf, ssid->id);
1416 * wpas_dbus_handler_remove_network - Remove a configured network
1417 * @message: Pointer to incoming dbus message
1418 * @wpa_s: wpa_supplicant structure for a network interface
1419 * Returns: NULL on success or dbus error on failure
1421 * Handler function for "RemoveNetwork" method call of a network interface.
1423 DBusMessage * wpas_dbus_handler_remove_network(DBusMessage *message,
1424 struct wpa_supplicant *wpa_s)
1426 DBusMessage *reply = NULL;
1428 char *iface = NULL, *net_id = NULL;
1430 struct wpa_ssid *ssid;
1432 dbus_message_get_args(message, NULL, DBUS_TYPE_OBJECT_PATH, &op,
1435 /* Extract the network ID and ensure the network */
1436 /* is actually a child of this interface */
1437 iface = wpas_dbus_new_decompose_object_path(op, &net_id, NULL);
1438 if (iface == NULL || strcmp(iface, wpas_dbus_get_path(wpa_s)) != 0) {
1439 reply = wpas_dbus_error_invald_args(message, op);
1443 id = strtoul(net_id, NULL, 10);
1444 if (errno == EINVAL) {
1445 reply = wpas_dbus_error_invald_args(message, op);
1449 ssid = wpa_config_get_network(wpa_s->conf, id);
1451 reply = wpas_dbus_error_network_unknown(message);
1455 wpas_notify_network_removed(wpa_s, ssid);
1457 if (wpa_config_remove_network(wpa_s->conf, id) < 0) {
1458 wpa_printf(MSG_ERROR,
1459 "wpas_dbus_handler_remove_network[dbus]: "
1460 "error occurred when removing network %d", id);
1461 reply = wpas_dbus_error_unknown_error(
1462 message, "error removing the specified network on "
1467 if (ssid == wpa_s->current_ssid)
1468 wpa_supplicant_disassociate(wpa_s, WLAN_REASON_DEAUTH_LEAVING);
1478 * wpas_dbus_handler_select_network - Attempt association with a network
1479 * @message: Pointer to incoming dbus message
1480 * @wpa_s: wpa_supplicant structure for a network interface
1481 * Returns: NULL on success or dbus error on failure
1483 * Handler function for "SelectNetwork" method call of network interface.
1485 DBusMessage * wpas_dbus_handler_select_network(DBusMessage *message,
1486 struct wpa_supplicant *wpa_s)
1488 DBusMessage *reply = NULL;
1490 char *iface = NULL, *net_id = NULL;
1492 struct wpa_ssid *ssid;
1494 dbus_message_get_args(message, NULL, DBUS_TYPE_OBJECT_PATH, &op,
1497 /* Extract the network ID and ensure the network */
1498 /* is actually a child of this interface */
1499 iface = wpas_dbus_new_decompose_object_path(op, &net_id, NULL);
1500 if (iface == NULL || strcmp(iface, wpas_dbus_get_path(wpa_s)) != 0) {
1501 reply = wpas_dbus_error_invald_args(message, op);
1505 id = strtoul(net_id, NULL, 10);
1506 if (errno == EINVAL) {
1507 reply = wpas_dbus_error_invald_args(message, op);
1511 ssid = wpa_config_get_network(wpa_s->conf, id);
1513 reply = wpas_dbus_error_network_unknown(message);
1517 /* Finally, associate with the network */
1518 wpa_supplicant_select_network(wpa_s, ssid);
1528 * wpas_dbus_handler_add_blob - Store named binary blob (ie, for certificates)
1529 * @message: Pointer to incoming dbus message
1530 * @wpa_s: %wpa_supplicant data structure
1531 * Returns: A dbus message containing an error on failure or NULL on success
1533 * Asks wpa_supplicant to internally store a binary blobs.
1535 DBusMessage * wpas_dbus_handler_add_blob(DBusMessage *message,
1536 struct wpa_supplicant *wpa_s)
1538 DBusMessage *reply = NULL;
1539 DBusMessageIter iter, array_iter;
1544 struct wpa_config_blob *blob = NULL;
1546 dbus_message_iter_init(message, &iter);
1547 dbus_message_iter_get_basic(&iter, &blob_name);
1549 if (wpa_config_get_blob(wpa_s->conf, blob_name)) {
1550 return dbus_message_new_error(message,
1551 WPAS_DBUS_ERROR_BLOB_EXISTS,
1555 dbus_message_iter_next(&iter);
1556 dbus_message_iter_recurse(&iter, &array_iter);
1558 dbus_message_iter_get_fixed_array(&array_iter, &blob_data, &blob_len);
1560 blob = os_zalloc(sizeof(*blob));
1562 perror("wpas_dbus_handler_add_blob[dbus] out of memory when "
1563 "trying to allocate blob struct");
1564 reply = dbus_message_new_error(message, DBUS_ERROR_NO_MEMORY,
1569 blob->data = os_malloc(blob_len);
1571 perror("wpas_dbus_handler_add_blob[dbus] out of memory when "
1572 "trying to allocate blob data");
1573 reply = dbus_message_new_error(message, DBUS_ERROR_NO_MEMORY,
1577 os_memcpy(blob->data, blob_data, blob_len);
1579 blob->len = blob_len;
1580 blob->name = os_strdup(blob_name);
1582 perror("wpas_dbus_handler_add_blob[dbus] out of memory when "
1583 "trying to copy blob name");
1584 reply = dbus_message_new_error(message, DBUS_ERROR_NO_MEMORY,
1589 wpa_config_set_blob(wpa_s->conf, blob);
1590 wpas_notify_blob_added(wpa_s, blob->name);
1596 os_free(blob->name);
1597 os_free(blob->data);
1605 * wpas_dbus_handler_get_blob - Get named binary blob (ie, for certificates)
1606 * @message: Pointer to incoming dbus message
1607 * @wpa_s: %wpa_supplicant data structure
1608 * Returns: A dbus message containing array of bytes (blob)
1610 * Gets one wpa_supplicant's binary blobs.
1612 DBusMessage * wpas_dbus_handler_get_blob(DBusMessage *message,
1613 struct wpa_supplicant *wpa_s)
1615 DBusMessage *reply = NULL;
1616 DBusMessageIter iter, array_iter;
1619 const struct wpa_config_blob *blob;
1621 dbus_message_get_args(message, NULL, DBUS_TYPE_STRING, &blob_name,
1624 blob = wpa_config_get_blob(wpa_s->conf, blob_name);
1626 return dbus_message_new_error(message,
1627 WPAS_DBUS_ERROR_BLOB_UNKNOWN,
1631 reply = dbus_message_new_method_return(message);
1633 perror("wpas_dbus_handler_get_blob[dbus] out of memory when "
1634 "trying to allocate return message");
1635 reply = dbus_message_new_error(message, DBUS_ERROR_NO_MEMORY,
1640 dbus_message_iter_init_append(reply, &iter);
1642 if (!dbus_message_iter_open_container(&iter, DBUS_TYPE_ARRAY,
1643 DBUS_TYPE_BYTE_AS_STRING,
1645 dbus_message_unref(reply);
1646 perror("wpas_dbus_handler_get_blob[dbus] out of memory when "
1647 "trying to open array");
1648 reply = dbus_message_new_error(message, DBUS_ERROR_NO_MEMORY,
1653 if (!dbus_message_iter_append_fixed_array(&array_iter, DBUS_TYPE_BYTE,
1654 &(blob->data), blob->len)) {
1655 dbus_message_unref(reply);
1656 perror("wpas_dbus_handler_get_blob[dbus] out of memory when "
1657 "trying to append data to array");
1658 reply = dbus_message_new_error(message, DBUS_ERROR_NO_MEMORY,
1663 if (!dbus_message_iter_close_container(&iter, &array_iter)) {
1664 dbus_message_unref(reply);
1665 perror("wpas_dbus_handler_get_blob[dbus] out of memory when "
1666 "trying to close array");
1667 reply = dbus_message_new_error(message, DBUS_ERROR_NO_MEMORY,
1678 * wpas_remove_handler_remove_blob - Remove named binary blob
1679 * @message: Pointer to incoming dbus message
1680 * @wpa_s: %wpa_supplicant data structure
1681 * Returns: NULL on success or dbus error
1683 * Asks wpa_supplicant to internally remove a binary blobs.
1685 DBusMessage * wpas_dbus_handler_remove_blob(DBusMessage *message,
1686 struct wpa_supplicant *wpa_s)
1688 DBusMessage *reply = NULL;
1691 dbus_message_get_args(message, NULL, DBUS_TYPE_STRING, &blob_name,
1694 if (wpa_config_remove_blob(wpa_s->conf, blob_name)) {
1695 return dbus_message_new_error(message,
1696 WPAS_DBUS_ERROR_BLOB_UNKNOWN,
1699 wpas_notify_blob_removed(wpa_s, blob_name);
1707 * wpas_dbus_getter_capabilities - Return interface capabilities
1708 * @message: Pointer to incoming dbus message
1709 * @wpa_s: wpa_supplicant structure for a network interface
1710 * Returns: A dbus message containing a dict of strings
1712 * Getter for "Capabilities" property of an interface.
1714 DBusMessage * wpas_dbus_getter_capabilities(DBusMessage *message,
1715 struct wpa_supplicant *wpa_s)
1717 DBusMessage *reply = NULL;
1718 struct wpa_driver_capa capa;
1720 DBusMessageIter iter, iter_dict;
1721 DBusMessageIter iter_dict_entry, iter_dict_val, iter_array,
1723 const char *scans[] = { "active", "passive", "ssid" };
1724 const char *modes[] = { "infrastructure", "ad-hoc", "ap" };
1725 int n = sizeof(modes) / sizeof(char *);
1727 if (message == NULL)
1728 reply = dbus_message_new(DBUS_MESSAGE_TYPE_SIGNAL);
1730 reply = dbus_message_new_method_return(message);
1734 dbus_message_iter_init_append(reply, &iter);
1735 if (!dbus_message_iter_open_container(&iter, DBUS_TYPE_VARIANT,
1736 "a{sv}", &variant_iter))
1739 if (!wpa_dbus_dict_open_write(&variant_iter, &iter_dict))
1742 res = wpa_drv_get_capa(wpa_s, &capa);
1744 /***** pairwise cipher */
1746 const char *args[] = {"ccmp", "tkip", "none"};
1747 if (!wpa_dbus_dict_append_string_array(
1748 &iter_dict, "Pairwise", args,
1749 sizeof(args) / sizeof(char*)))
1752 if (!wpa_dbus_dict_begin_string_array(&iter_dict, "Pairwise",
1758 if (capa.enc & WPA_DRIVER_CAPA_ENC_CCMP) {
1759 if (!wpa_dbus_dict_string_array_add_element(
1760 &iter_array, "ccmp"))
1764 if (capa.enc & WPA_DRIVER_CAPA_ENC_TKIP) {
1765 if (!wpa_dbus_dict_string_array_add_element(
1766 &iter_array, "tkip"))
1770 if (capa.key_mgmt & WPA_DRIVER_CAPA_KEY_MGMT_WPA_NONE) {
1771 if (!wpa_dbus_dict_string_array_add_element(
1772 &iter_array, "none"))
1776 if (!wpa_dbus_dict_end_string_array(&iter_dict,
1783 /***** group cipher */
1785 const char *args[] = {
1786 "ccmp", "tkip", "wep104", "wep40"
1788 if (!wpa_dbus_dict_append_string_array(
1789 &iter_dict, "Group", args,
1790 sizeof(args) / sizeof(char*)))
1793 if (!wpa_dbus_dict_begin_string_array(&iter_dict, "Group",
1799 if (capa.enc & WPA_DRIVER_CAPA_ENC_CCMP) {
1800 if (!wpa_dbus_dict_string_array_add_element(
1801 &iter_array, "ccmp"))
1805 if (capa.enc & WPA_DRIVER_CAPA_ENC_TKIP) {
1806 if (!wpa_dbus_dict_string_array_add_element(
1807 &iter_array, "tkip"))
1811 if (capa.enc & WPA_DRIVER_CAPA_ENC_WEP104) {
1812 if (!wpa_dbus_dict_string_array_add_element(
1813 &iter_array, "wep104"))
1817 if (capa.enc & WPA_DRIVER_CAPA_ENC_WEP40) {
1818 if (!wpa_dbus_dict_string_array_add_element(
1819 &iter_array, "wep40"))
1823 if (!wpa_dbus_dict_end_string_array(&iter_dict,
1830 /***** key management */
1832 const char *args[] = {
1833 "wpa-psk", "wpa-eap", "ieee8021x", "wpa-none",
1836 #endif /* CONFIG_WPS */
1839 if (!wpa_dbus_dict_append_string_array(
1840 &iter_dict, "KeyMgmt", args,
1841 sizeof(args) / sizeof(char*)))
1844 if (!wpa_dbus_dict_begin_string_array(&iter_dict, "KeyMgmt",
1850 if (!wpa_dbus_dict_string_array_add_element(&iter_array,
1854 if (!wpa_dbus_dict_string_array_add_element(&iter_array,
1858 if (capa.key_mgmt & (WPA_DRIVER_CAPA_KEY_MGMT_WPA |
1859 WPA_DRIVER_CAPA_KEY_MGMT_WPA2)) {
1860 if (!wpa_dbus_dict_string_array_add_element(
1861 &iter_array, "wpa-eap"))
1865 if (capa.key_mgmt & (WPA_DRIVER_CAPA_KEY_MGMT_WPA_PSK |
1866 WPA_DRIVER_CAPA_KEY_MGMT_WPA2_PSK)) {
1867 if (!wpa_dbus_dict_string_array_add_element(
1868 &iter_array, "wpa-psk"))
1872 if (capa.key_mgmt & WPA_DRIVER_CAPA_KEY_MGMT_WPA_NONE) {
1873 if (!wpa_dbus_dict_string_array_add_element(
1874 &iter_array, "wpa-none"))
1880 if (!wpa_dbus_dict_string_array_add_element(&iter_array,
1883 #endif /* CONFIG_WPS */
1885 if (!wpa_dbus_dict_end_string_array(&iter_dict,
1892 /***** WPA protocol */
1894 const char *args[] = { "rsn", "wpa" };
1895 if (!wpa_dbus_dict_append_string_array(
1896 &iter_dict, "Protocol", args,
1897 sizeof(args) / sizeof(char*)))
1900 if (!wpa_dbus_dict_begin_string_array(&iter_dict, "Protocol",
1906 if (capa.key_mgmt & (WPA_DRIVER_CAPA_KEY_MGMT_WPA2 |
1907 WPA_DRIVER_CAPA_KEY_MGMT_WPA2_PSK)) {
1908 if (!wpa_dbus_dict_string_array_add_element(
1909 &iter_array, "rsn"))
1913 if (capa.key_mgmt & (WPA_DRIVER_CAPA_KEY_MGMT_WPA |
1914 WPA_DRIVER_CAPA_KEY_MGMT_WPA_PSK)) {
1915 if (!wpa_dbus_dict_string_array_add_element(
1916 &iter_array, "wpa"))
1920 if (!wpa_dbus_dict_end_string_array(&iter_dict,
1929 const char *args[] = { "open", "shared", "leap" };
1930 if (!wpa_dbus_dict_append_string_array(
1931 &iter_dict, "AuthAlg", args,
1932 sizeof(args) / sizeof(char*)))
1935 if (!wpa_dbus_dict_begin_string_array(&iter_dict, "AuthAlg",
1941 if (capa.auth & (WPA_DRIVER_AUTH_OPEN)) {
1942 if (!wpa_dbus_dict_string_array_add_element(
1943 &iter_array, "open"))
1947 if (capa.auth & (WPA_DRIVER_AUTH_SHARED)) {
1948 if (!wpa_dbus_dict_string_array_add_element(
1949 &iter_array, "shared"))
1953 if (capa.auth & (WPA_DRIVER_AUTH_LEAP)) {
1954 if (!wpa_dbus_dict_string_array_add_element(
1955 &iter_array, "leap"))
1959 if (!wpa_dbus_dict_end_string_array(&iter_dict,
1967 if (!wpa_dbus_dict_append_string_array(&iter_dict, "Scan", scans,
1968 sizeof(scans) / sizeof(char *)))
1972 if (res < 0 || !(capa.flags & WPA_DRIVER_FLAGS_AP))
1973 n--; /* exclude ap mode if it is not supported by the driver */
1974 if (!wpa_dbus_dict_append_string_array(&iter_dict, "Modes", modes, n))
1977 if (!wpa_dbus_dict_close_write(&variant_iter, &iter_dict))
1979 if (!dbus_message_iter_close_container(&iter, &variant_iter))
1986 dbus_message_unref(reply);
1988 return dbus_message_new_error(message, DBUS_ERROR_NO_MEMORY, NULL);
1993 * wpas_dbus_getter_state - Get interface state
1994 * @message: Pointer to incoming dbus message
1995 * @wpa_s: wpa_supplicant structure for a network interface
1996 * Returns: A dbus message containing a STRING representing the current
1999 * Getter for "State" property.
2001 DBusMessage * wpas_dbus_getter_state(DBusMessage *message,
2002 struct wpa_supplicant *wpa_s)
2004 DBusMessage *reply = NULL;
2005 const char *str_state;
2006 char *state_ls, *tmp;
2008 str_state = wpa_supplicant_state_txt(wpa_s->wpa_state);
2010 /* make state string lowercase to fit new DBus API convention
2012 state_ls = tmp = os_strdup(str_state);
2014 return dbus_message_new_error(message, DBUS_ERROR_NO_MEMORY,
2018 *tmp = tolower(*tmp);
2022 reply = wpas_dbus_simple_property_getter(message, DBUS_TYPE_STRING,
2032 * wpas_dbus_new_iface_get_scanning - Get interface scanning state
2033 * @message: Pointer to incoming dbus message
2034 * @wpa_s: wpa_supplicant structure for a network interface
2035 * Returns: A dbus message containing whether the interface is scanning
2037 * Getter for "scanning" property.
2039 DBusMessage * wpas_dbus_getter_scanning(DBusMessage *message,
2040 struct wpa_supplicant *wpa_s)
2042 dbus_bool_t scanning = wpa_s->scanning ? TRUE : FALSE;
2043 return wpas_dbus_simple_property_getter(message, DBUS_TYPE_BOOLEAN,
2049 * wpas_dbus_getter_ap_scan - Control roaming mode
2050 * @message: Pointer to incoming dbus message
2051 * @wpa_s: wpa_supplicant structure for a network interface
2052 * Returns: A message containong value of ap_scan variable
2054 * Getter function for "ApScan" property.
2056 DBusMessage * wpas_dbus_getter_ap_scan(DBusMessage *message,
2057 struct wpa_supplicant *wpa_s)
2059 dbus_uint32_t ap_scan = wpa_s->conf->ap_scan;
2060 return wpas_dbus_simple_property_getter(message, DBUS_TYPE_UINT32,
2066 * wpas_dbus_setter_ap_scan - Control roaming mode
2067 * @message: Pointer to incoming dbus message
2068 * @wpa_s: wpa_supplicant structure for a network interface
2071 * Setter function for "ApScan" property.
2073 DBusMessage * wpas_dbus_setter_ap_scan(DBusMessage *message,
2074 struct wpa_supplicant *wpa_s)
2076 DBusMessage *reply = NULL;
2077 dbus_uint32_t ap_scan;
2079 reply = wpas_dbus_simple_property_setter(message, DBUS_TYPE_UINT32,
2084 if (wpa_supplicant_set_ap_scan(wpa_s, ap_scan)) {
2085 return wpas_dbus_error_invald_args(
2086 message, "ap_scan must equal 0, 1 or 2");
2093 * wpas_dbus_getter_ifname - Get interface name
2094 * @message: Pointer to incoming dbus message
2095 * @wpa_s: wpa_supplicant structure for a network interface
2096 * Returns: A dbus message containing a name of network interface
2097 * associated with with wpa_s
2099 * Getter for "Ifname" property.
2101 DBusMessage * wpas_dbus_getter_ifname(DBusMessage *message,
2102 struct wpa_supplicant *wpa_s)
2104 const char *ifname = wpa_s->ifname;
2105 return wpas_dbus_simple_property_getter(message, DBUS_TYPE_STRING,
2111 * wpas_dbus_getter_driver - Get interface name
2112 * @message: Pointer to incoming dbus message
2113 * @wpa_s: wpa_supplicant structure for a network interface
2114 * Returns: A dbus message containing a name of network interface
2115 * driver associated with with wpa_s
2117 * Getter for "Driver" property.
2119 DBusMessage * wpas_dbus_getter_driver(DBusMessage *message,
2120 struct wpa_supplicant *wpa_s)
2124 if (wpa_s->driver == NULL || wpa_s->driver->name == NULL) {
2125 wpa_printf(MSG_DEBUG, "wpas_dbus_getter_driver[dbus]: "
2126 "wpa_s has no driver set");
2127 return wpas_dbus_error_unknown_error(message, NULL);
2130 driver = wpa_s->driver->name;
2131 return wpas_dbus_simple_property_getter(message, DBUS_TYPE_STRING,
2137 * wpas_dbus_getter_current_bss - Get current bss object path
2138 * @message: Pointer to incoming dbus message
2139 * @wpa_s: wpa_supplicant structure for a network interface
2140 * Returns: A dbus message containing a DBus object path to
2143 * Getter for "CurrentBSS" property.
2145 DBusMessage * wpas_dbus_getter_current_bss(DBusMessage *message,
2146 struct wpa_supplicant *wpa_s)
2148 DBusMessage *reply = NULL;
2149 const char *path = wpas_dbus_get_path(wpa_s);
2150 char *bss_obj_path = os_zalloc(WPAS_DBUS_OBJECT_PATH_MAX);
2151 struct wpa_bss *bss = NULL;
2153 if (bss_obj_path == NULL) {
2154 perror("wpas_dbus_getter_current_bss[dbus]: out of "
2155 "memory to allocate result argument.");
2156 return dbus_message_new_error(message, DBUS_ERROR_NO_MEMORY,
2160 /* TODO: store current BSS or BSS id in wpa_s */
2161 if (!is_zero_ether_addr(wpa_s->bssid))
2162 bss = wpa_bss_get_bssid(wpa_s, wpa_s->bssid);
2165 os_snprintf(bss_obj_path, WPAS_DBUS_OBJECT_PATH_MAX,
2166 "%s/" WPAS_DBUS_NEW_BSSIDS_PART "/%u",
2169 os_snprintf(bss_obj_path, WPAS_DBUS_OBJECT_PATH_MAX, "/");
2171 reply = wpas_dbus_simple_property_getter(message,
2172 DBUS_TYPE_OBJECT_PATH,
2175 os_free(bss_obj_path);
2181 * wpas_dbus_getter_current_network - Get current network object path
2182 * @message: Pointer to incoming dbus message
2183 * @wpa_s: wpa_supplicant structure for a network interface
2184 * Returns: A dbus message containing a DBus object path to
2187 * Getter for "CurrentNetwork" property.
2189 DBusMessage * wpas_dbus_getter_current_network(DBusMessage *message,
2190 struct wpa_supplicant *wpa_s)
2192 DBusMessage *reply = NULL;
2193 const char *path = wpas_dbus_get_path(wpa_s);
2194 char *net_obj_path = os_zalloc(WPAS_DBUS_OBJECT_PATH_MAX);
2196 if (net_obj_path == NULL) {
2197 perror("wpas_dbus_getter_current_network[dbus]: out of "
2198 "memory to allocate result argument.");
2199 return dbus_message_new_error(message, DBUS_ERROR_NO_MEMORY,
2203 if (wpa_s->current_ssid)
2204 os_snprintf(net_obj_path, WPAS_DBUS_OBJECT_PATH_MAX,
2205 "%s/" WPAS_DBUS_NEW_NETWORKS_PART "/%u", path,
2206 wpa_s->current_ssid->id);
2208 os_snprintf(net_obj_path, WPAS_DBUS_OBJECT_PATH_MAX, "/");
2210 reply = wpas_dbus_simple_property_getter(message,
2211 DBUS_TYPE_OBJECT_PATH,
2214 os_free(net_obj_path);
2220 * wpas_dbus_getter_bridge_ifname - Get interface name
2221 * @message: Pointer to incoming dbus message
2222 * @wpa_s: wpa_supplicant structure for a network interface
2223 * Returns: A dbus message containing a name of bridge network
2224 * interface associated with with wpa_s
2226 * Getter for "BridgeIfname" property.
2228 DBusMessage * wpas_dbus_getter_bridge_ifname(DBusMessage *message,
2229 struct wpa_supplicant *wpa_s)
2231 const char *bridge_ifname = NULL;
2233 bridge_ifname = wpa_s->bridge_ifname;
2234 if (bridge_ifname == NULL) {
2235 wpa_printf(MSG_ERROR, "wpas_dbus_getter_bridge_ifname[dbus]: "
2236 "wpa_s has no bridge interface name set");
2237 return wpas_dbus_error_unknown_error(message, NULL);
2240 return wpas_dbus_simple_property_getter(message, DBUS_TYPE_STRING,
2246 * wpas_dbus_getter_bsss - Get array of BSSs objects
2247 * @message: Pointer to incoming dbus message
2248 * @wpa_s: wpa_supplicant structure for a network interface
2249 * Returns: a dbus message containing an array of all known BSS objects
2252 * Getter for "BSSs" property.
2254 DBusMessage * wpas_dbus_getter_bsss(DBusMessage *message,
2255 struct wpa_supplicant *wpa_s)
2257 DBusMessage *reply = NULL;
2258 struct wpa_bss *bss;
2262 paths = os_zalloc(wpa_s->num_bss * sizeof(char *));
2264 return dbus_message_new_error(message, DBUS_ERROR_NO_MEMORY,
2268 /* Loop through scan results and append each result's object path */
2269 dl_list_for_each(bss, &wpa_s->bss_id, struct wpa_bss, list_id) {
2270 paths[i] = os_zalloc(WPAS_DBUS_OBJECT_PATH_MAX);
2271 if (paths[i] == NULL) {
2272 perror("wpas_dbus_getter_bsss[dbus]: out of "
2274 reply = dbus_message_new_error(message,
2275 DBUS_ERROR_NO_MEMORY,
2279 /* Construct the object path for this BSS. */
2280 os_snprintf(paths[i++], WPAS_DBUS_OBJECT_PATH_MAX,
2281 "%s/" WPAS_DBUS_NEW_BSSIDS_PART "/%u",
2282 wpas_dbus_get_path(wpa_s), bss->id);
2285 reply = wpas_dbus_simple_array_property_getter(message,
2286 DBUS_TYPE_OBJECT_PATH,
2287 paths, wpa_s->num_bss);
2291 os_free(paths[--i]);
2298 * wpas_dbus_getter_networks - Get array of networks objects
2299 * @message: Pointer to incoming dbus message
2300 * @wpa_s: wpa_supplicant structure for a network interface
2301 * Returns: a dbus message containing an array of all configured
2302 * networks dbus object paths.
2304 * Getter for "Networks" property.
2306 DBusMessage * wpas_dbus_getter_networks(DBusMessage *message,
2307 struct wpa_supplicant *wpa_s)
2309 DBusMessage *reply = NULL;
2310 struct wpa_ssid *ssid;
2312 unsigned int i = 0, num = 0;
2314 if (wpa_s->conf == NULL) {
2315 wpa_printf(MSG_ERROR, "wpas_dbus_getter_networks[dbus]: "
2316 "An error occurred getting networks list.");
2317 return wpas_dbus_error_unknown_error(message, NULL);
2320 for (ssid = wpa_s->conf->ssid; ssid; ssid = ssid->next)
2323 paths = os_zalloc(num * sizeof(char *));
2325 return dbus_message_new_error(message, DBUS_ERROR_NO_MEMORY,
2329 /* Loop through configured networks and append object path of each */
2330 for (ssid = wpa_s->conf->ssid; ssid; ssid = ssid->next) {
2332 paths[i] = os_zalloc(WPAS_DBUS_OBJECT_PATH_MAX);
2333 if (paths[i] == NULL) {
2334 perror("wpas_dbus_getter_networks[dbus]: out of "
2336 reply = dbus_message_new_error(message,
2337 DBUS_ERROR_NO_MEMORY,
2342 /* Construct the object path for this network. */
2343 os_snprintf(paths[i++], WPAS_DBUS_OBJECT_PATH_MAX,
2344 "%s/" WPAS_DBUS_NEW_NETWORKS_PART "/%d",
2345 wpas_dbus_get_path(wpa_s), ssid->id);
2348 reply = wpas_dbus_simple_array_property_getter(message,
2349 DBUS_TYPE_OBJECT_PATH,
2354 os_free(paths[--i]);
2361 * wpas_dbus_getter_blobs - Get all blobs defined for this interface
2362 * @message: Pointer to incoming dbus message
2363 * @wpa_s: wpa_supplicant structure for a network interface
2364 * Returns: a dbus message containing a dictionary of pairs (blob_name, blob)
2366 * Getter for "Blobs" property.
2368 DBusMessage * wpas_dbus_getter_blobs(DBusMessage *message,
2369 struct wpa_supplicant *wpa_s)
2371 DBusMessage *reply = NULL;
2372 DBusMessageIter iter, variant_iter, dict_iter, entry_iter, array_iter;
2373 struct wpa_config_blob *blob;
2375 if (message == NULL)
2376 reply = dbus_message_new(DBUS_MESSAGE_TYPE_SIGNAL);
2378 reply = dbus_message_new_method_return(message);
2380 perror("wpas_dbus_getter_blobs[dbus] out of memory when "
2381 "trying to initialize return message");
2382 reply = dbus_message_new_error(message, DBUS_ERROR_NO_MEMORY,
2387 dbus_message_iter_init_append(reply, &iter);
2389 if (!dbus_message_iter_open_container(&iter, DBUS_TYPE_VARIANT,
2390 "a{say}", &variant_iter)) {
2391 dbus_message_unref(reply);
2392 perror("wpas_dbus_getter_blobs[dbus] out of memory when "
2393 "trying to open variant");
2394 reply = dbus_message_new_error(message, DBUS_ERROR_NO_MEMORY,
2399 if (!dbus_message_iter_open_container(&variant_iter, DBUS_TYPE_ARRAY,
2400 "{say}", &dict_iter)) {
2401 dbus_message_unref(reply);
2402 perror("wpas_dbus_getter_blobs[dbus] out of memory when "
2403 "trying to open dictionary");
2404 reply = dbus_message_new_error(message, DBUS_ERROR_NO_MEMORY,
2409 blob = wpa_s->conf->blobs;
2411 if (!dbus_message_iter_open_container(&dict_iter,
2412 DBUS_TYPE_DICT_ENTRY,
2413 NULL, &entry_iter)) {
2414 dbus_message_unref(reply);
2415 perror("wpas_dbus_getter_blobs[dbus] out of memory "
2416 "when trying to open entry");
2417 reply = dbus_message_new_error(message,
2418 DBUS_ERROR_NO_MEMORY,
2423 if (!dbus_message_iter_append_basic(&entry_iter,
2426 dbus_message_unref(reply);
2427 perror("wpas_dbus_getter_blobs[dbus] out of memory "
2428 "when trying to append blob name");
2429 reply = dbus_message_new_error(message,
2430 DBUS_ERROR_NO_MEMORY,
2435 if (!dbus_message_iter_open_container(&entry_iter,
2437 DBUS_TYPE_BYTE_AS_STRING,
2439 dbus_message_unref(reply);
2440 perror("wpas_dbus_getter_blobs[dbus] out of memory "
2441 "when trying to open array");
2442 reply = dbus_message_new_error(message,
2443 DBUS_ERROR_NO_MEMORY,
2448 if (!dbus_message_iter_append_fixed_array(&array_iter,
2452 dbus_message_unref(reply);
2453 perror("wpas_dbus_getter_blobs[dbus] out of memory "
2454 "when trying to append blob data");
2455 reply = dbus_message_new_error(message,
2456 DBUS_ERROR_NO_MEMORY,
2461 if (!dbus_message_iter_close_container(&entry_iter,
2463 dbus_message_unref(reply);
2464 perror("wpas_dbus_getter_blobs[dbus] out of memory "
2465 "when trying to close array");
2466 reply = dbus_message_new_error(message,
2467 DBUS_ERROR_NO_MEMORY,
2472 if (!dbus_message_iter_close_container(&dict_iter,
2474 dbus_message_unref(reply);
2475 perror("wpas_dbus_getter_blobs[dbus] out of memory "
2476 "when trying to close entry");
2477 reply = dbus_message_new_error(message,
2478 DBUS_ERROR_NO_MEMORY,
2486 if (!dbus_message_iter_close_container(&variant_iter, &dict_iter)) {
2487 dbus_message_unref(reply);
2488 perror("wpas_dbus_getter_blobs[dbus] out of memory when "
2489 "trying to close dictionary");
2490 reply = dbus_message_new_error(message, DBUS_ERROR_NO_MEMORY,
2495 if (!dbus_message_iter_close_container(&iter, &variant_iter)) {
2496 dbus_message_unref(reply);
2497 perror("wpas_dbus_getter_blobs[dbus] out of memory when "
2498 "trying to close variant");
2499 reply = dbus_message_new_error(message, DBUS_ERROR_NO_MEMORY,
2510 * wpas_dbus_getter_bss_bssid - Return the BSSID of a BSS
2511 * @message: Pointer to incoming dbus message
2512 * @bss: a pair of interface describing structure and bss's id
2513 * Returns: a dbus message containing the bssid for the requested bss
2515 * Getter for "BSSID" property.
2517 DBusMessage * wpas_dbus_getter_bss_bssid(DBusMessage *message,
2518 struct bss_handler_args *bss)
2520 struct wpa_bss *res = wpa_bss_get_id(bss->wpa_s, bss->id);
2523 wpa_printf(MSG_ERROR, "wpas_dbus_getter_bss_bssid[dbus]: no "
2524 "bss with id %d found", bss->id);
2528 return wpas_dbus_simple_array_property_getter(message, DBUS_TYPE_BYTE,
2529 res->bssid, ETH_ALEN);
2534 * wpas_dbus_getter_bss_ssid - Return the SSID of a BSS
2535 * @message: Pointer to incoming dbus message
2536 * @bss: a pair of interface describing structure and bss's id
2537 * Returns: a dbus message containing the ssid for the requested bss
2539 * Getter for "SSID" property.
2541 DBusMessage * wpas_dbus_getter_bss_ssid(DBusMessage *message,
2542 struct bss_handler_args *bss)
2544 struct wpa_bss *res = wpa_bss_get_id(bss->wpa_s, bss->id);
2547 wpa_printf(MSG_ERROR, "wpas_dbus_getter_bss_ssid[dbus]: no "
2548 "bss with id %d found", bss->id);
2552 return wpas_dbus_simple_array_property_getter(message, DBUS_TYPE_BYTE,
2559 * wpas_dbus_getter_bss_privacy - Return the privacy flag of a BSS
2560 * @message: Pointer to incoming dbus message
2561 * @bss: a pair of interface describing structure and bss's id
2562 * Returns: a dbus message containing the privacy flag value of requested bss
2564 * Getter for "Privacy" property.
2566 DBusMessage * wpas_dbus_getter_bss_privacy(DBusMessage *message,
2567 struct bss_handler_args *bss)
2569 struct wpa_bss *res = wpa_bss_get_id(bss->wpa_s, bss->id);
2570 dbus_bool_t privacy;
2573 wpa_printf(MSG_ERROR, "wpas_dbus_getter_bss_privacy[dbus]: no "
2574 "bss with id %d found", bss->id);
2578 privacy = res->caps && IEEE80211_CAP_PRIVACY ? TRUE : FALSE;
2579 return wpas_dbus_simple_property_getter(message, DBUS_TYPE_BOOLEAN,
2585 * wpas_dbus_getter_bss_mode - Return the mode of a BSS
2586 * @message: Pointer to incoming dbus message
2587 * @bss: a pair of interface describing structure and bss's id
2588 * Returns: a dbus message containing the mode of requested bss
2590 * Getter for "Mode" property.
2592 DBusMessage * wpas_dbus_getter_bss_mode(DBusMessage *message,
2593 struct bss_handler_args *bss)
2595 struct wpa_bss *res = wpa_bss_get_id(bss->wpa_s, bss->id);
2599 wpa_printf(MSG_ERROR, "wpas_dbus_getter_bss_mode[dbus]: no "
2600 "bss with id %d found", bss->id);
2604 if (res->caps & IEEE80211_CAP_IBSS)
2607 mode = "infrastructure";
2609 return wpas_dbus_simple_property_getter(message, DBUS_TYPE_STRING,
2615 * wpas_dbus_getter_bss_level - Return the signal strength of a BSS
2616 * @message: Pointer to incoming dbus message
2617 * @bss: a pair of interface describing structure and bss's id
2618 * Returns: a dbus message containing the signal strength of requested bss
2620 * Getter for "Level" property.
2622 DBusMessage * wpas_dbus_getter_bss_signal(DBusMessage *message,
2623 struct bss_handler_args *bss)
2625 struct wpa_bss *res = wpa_bss_get_id(bss->wpa_s, bss->id);
2628 wpa_printf(MSG_ERROR, "wpas_dbus_getter_bss_signal[dbus]: no "
2629 "bss with id %d found", bss->id);
2633 return wpas_dbus_simple_property_getter(message, DBUS_TYPE_INT16,
2639 * wpas_dbus_getter_bss_frequency - Return the frequency of a BSS
2640 * @message: Pointer to incoming dbus message
2641 * @bss: a pair of interface describing structure and bss's id
2642 * Returns: a dbus message containing the frequency of requested bss
2644 * Getter for "Frequency" property.
2646 DBusMessage * wpas_dbus_getter_bss_frequency(DBusMessage *message,
2647 struct bss_handler_args *bss)
2649 struct wpa_bss *res = wpa_bss_get_id(bss->wpa_s, bss->id);
2652 wpa_printf(MSG_ERROR, "wpas_dbus_getter_bss_frequency[dbus]: "
2653 "no bss with id %d found", bss->id);
2657 return wpas_dbus_simple_property_getter(message, DBUS_TYPE_UINT16,
2663 * wpas_dbus_getter_bss_max_rate - Return the maximal rate of a BSS
2664 * @message: Pointer to incoming dbus message
2665 * @bss: a pair of interface describing structure and bss's id
2666 * Returns: a dbus message containing the maximal data rate of requested bss
2668 * Getter for "MaxRate" property.
2670 DBusMessage * wpas_dbus_getter_bss_max_rate(DBusMessage *message,
2671 struct bss_handler_args *bss)
2673 struct wpa_bss *res = wpa_bss_get_id(bss->wpa_s, bss->id);
2677 wpa_printf(MSG_ERROR, "wpas_dbus_getter_bss_max_rate[dbus]: "
2678 "no bss with id %d found", bss->id);
2682 max_rate = wpa_bss_get_max_rate(res);
2683 return wpas_dbus_simple_property_getter(message, DBUS_TYPE_UINT16,
2689 * wpas_dbus_getter_bss_wpaie - Return the WPA IE of a BSS
2690 * @message: Pointer to incoming dbus message
2691 * @bss: a pair of interface describing structure and bss's id
2692 * Returns: a dbus message containing the WPA information elements
2695 * Getter for "WPAIE" property.
2697 DBusMessage * wpas_dbus_getter_bss_wpaie(DBusMessage *message,
2698 struct bss_handler_args *bss)
2700 struct wpa_bss *res = wpa_bss_get_id(bss->wpa_s, bss->id);
2704 wpa_printf(MSG_ERROR, "wpas_dbus_getter_bss_wpaie[dbus]: no "
2705 "bss with id %d found", bss->id);
2709 ie = wpa_bss_get_vendor_ie(res, WPA_IE_VENDOR_TYPE);
2712 return wpas_dbus_simple_array_property_getter(message, DBUS_TYPE_BYTE,
2718 * wpas_dbus_getter_bss_rsnie - Return the RSN IE of a BSS
2719 * @message: Pointer to incoming dbus message
2720 * @bss: a pair of interface describing structure and bss's id
2721 * Returns: a dbus message containing the RSN information elements
2724 * Getter for "RSNIE" property.
2726 DBusMessage * wpas_dbus_getter_bss_rsnie(DBusMessage *message,
2727 struct bss_handler_args *bss)
2729 struct wpa_bss *res = wpa_bss_get_id(bss->wpa_s, bss->id);
2733 wpa_printf(MSG_ERROR, "wpas_dbus_getter_bss_rsnie[dbus]: no "
2734 "bss with id %d found", bss->id);
2738 ie = wpa_bss_get_ie(res, WLAN_EID_RSN);
2741 return wpas_dbus_simple_array_property_getter(message, DBUS_TYPE_BYTE,
2747 * wpas_dbus_getter_bss_wpsie - Return the WPS IE of a BSS
2748 * @message: Pointer to incoming dbus message
2749 * @bss: a pair of interface describing structure and bss's id
2750 * Returns: a dbus message containing the WPS information elements
2753 * Getter for "WPSIE" property.
2755 DBusMessage * wpas_dbus_getter_bss_wpsie(DBusMessage *message,
2756 struct bss_handler_args *bss)
2758 struct wpa_bss *res = wpa_bss_get_id(bss->wpa_s, bss->id);
2762 wpa_printf(MSG_ERROR, "wpas_dbus_getter_bss_wpsie[dbus]: no "
2763 "bss with id %d found", bss->id);
2767 ie = wpa_bss_get_vendor_ie(res, WPS_IE_VENDOR_TYPE);
2770 return wpas_dbus_simple_array_property_getter(message, DBUS_TYPE_BYTE,
2776 * wpas_dbus_getter_enabled - Check whether network is enabled or disabled
2777 * @message: Pointer to incoming dbus message
2778 * @wpas_dbus_setter_enabled: wpa_supplicant structure for a network interface
2779 * and wpa_ssid structure for a configured network
2780 * Returns: DBus message with boolean indicating state of configured network
2781 * or DBus error on failure
2783 * Getter for "enabled" property of a configured network.
2785 DBusMessage * wpas_dbus_getter_enabled(DBusMessage *message,
2786 struct network_handler_args *net)
2788 dbus_bool_t enabled = net->ssid->disabled ? FALSE : TRUE;
2789 return wpas_dbus_simple_property_getter(message, DBUS_TYPE_BOOLEAN,
2795 * wpas_dbus_setter_enabled - Mark a configured network as enabled or disabled
2796 * @message: Pointer to incoming dbus message
2797 * @wpas_dbus_setter_enabled: wpa_supplicant structure for a network interface
2798 * and wpa_ssid structure for a configured network
2799 * Returns: NULL indicating success or DBus error on failure
2801 * Setter for "Enabled" property of a configured network.
2803 DBusMessage * wpas_dbus_setter_enabled(DBusMessage *message,
2804 struct network_handler_args *net)
2806 DBusMessage *reply = NULL;
2808 struct wpa_supplicant *wpa_s;
2809 struct wpa_ssid *ssid;
2813 reply = wpas_dbus_simple_property_setter(message, DBUS_TYPE_BOOLEAN,
2823 wpa_supplicant_enable_network(wpa_s, ssid);
2825 wpa_supplicant_disable_network(wpa_s, ssid);
2832 * wpas_dbus_getter_network_properties - Get options for a configured network
2833 * @message: Pointer to incoming dbus message
2834 * @net: wpa_supplicant structure for a network interface and
2835 * wpa_ssid structure for a configured network
2836 * Returns: DBus message with network properties or DBus error on failure
2838 * Getter for "Properties" property of a configured network.
2840 DBusMessage * wpas_dbus_getter_network_properties(
2841 DBusMessage *message, struct network_handler_args *net)
2843 DBusMessage *reply = NULL;
2844 DBusMessageIter iter, variant_iter, dict_iter;
2846 char **props = wpa_config_get_all(net->ssid, 0);
2848 perror("wpas_dbus_getter_network_properties[dbus] couldn't "
2849 "read network properties. out of memory.");
2850 return dbus_message_new_error(message, DBUS_ERROR_NO_MEMORY,
2854 if (message == NULL)
2855 reply = dbus_message_new(DBUS_MESSAGE_TYPE_SIGNAL);
2857 reply = dbus_message_new_method_return(message);
2859 perror("wpas_dbus_getter_network_properties[dbus] out of "
2860 "memory when trying to initialize return message");
2861 reply = dbus_message_new_error(message, DBUS_ERROR_NO_MEMORY,
2866 dbus_message_iter_init_append(reply, &iter);
2868 if (!dbus_message_iter_open_container(&iter, DBUS_TYPE_VARIANT,
2869 "a{sv}", &variant_iter)) {
2870 perror("wpas_dbus_getter_network_properties[dbus] out of "
2871 "memory when trying to open variant container");
2872 dbus_message_unref(reply);
2873 reply = dbus_message_new_error(message, DBUS_ERROR_NO_MEMORY,
2878 if (!wpa_dbus_dict_open_write(&variant_iter, &dict_iter)) {
2879 perror("wpas_dbus_getter_network_properties[dbus] out of "
2880 "memory when trying to open dict");
2881 dbus_message_unref(reply);
2882 reply = dbus_message_new_error(message, DBUS_ERROR_NO_MEMORY,
2889 if (!wpa_dbus_dict_append_string(&dict_iter, *iterator,
2891 perror("wpas_dbus_getter_network_properties[dbus] out "
2892 "of memory when trying to add entry");
2893 dbus_message_unref(reply);
2894 reply = dbus_message_new_error(message,
2895 DBUS_ERROR_NO_MEMORY,
2903 if (!wpa_dbus_dict_close_write(&variant_iter, &dict_iter)) {
2904 perror("wpas_dbus_getter_network_properties[dbus] out of "
2905 "memory when trying to close dictionary");
2906 dbus_message_unref(reply);
2907 reply = dbus_message_new_error(message, DBUS_ERROR_NO_MEMORY,
2912 if (!dbus_message_iter_close_container(&iter, &variant_iter)) {
2913 perror("wpas_dbus_getter_network_properties[dbus] out of "
2914 "memory when trying to close variant container");
2915 dbus_message_unref(reply);
2916 reply = dbus_message_new_error(message, DBUS_ERROR_NO_MEMORY,
2933 * wpas_dbus_setter_network_properties - Set options for a configured network
2934 * @message: Pointer to incoming dbus message
2935 * @net: wpa_supplicant structure for a network interface and
2936 * wpa_ssid structure for a configured network
2937 * Returns: NULL indicating success or DBus error on failure
2939 * Setter for "Properties" property of a configured network.
2941 DBusMessage * wpas_dbus_setter_network_properties(
2942 DBusMessage *message, struct network_handler_args *net)
2944 struct wpa_ssid *ssid = net->ssid;
2946 DBusMessage *reply = NULL;
2947 DBusMessageIter iter, variant_iter;
2949 dbus_message_iter_init(message, &iter);
2951 dbus_message_iter_next(&iter);
2952 dbus_message_iter_next(&iter);
2954 dbus_message_iter_recurse(&iter, &variant_iter);
2956 reply = set_network_properties(message, ssid, &variant_iter);
2958 wpa_printf(MSG_DEBUG, "dbus control interface couldn't set "
2959 "network properties");