dbus_new_handlers: Don't send NULL to dbus_message_new_error
[libeap.git] / wpa_supplicant / dbus / dbus_new_handlers.c
index 0b6f7ea..0ad51a0 100644 (file)
@@ -1,7 +1,8 @@
 /*
  * WPA Supplicant / dbus-based control interface
  * Copyright (c) 2006, Dan Williams <dcbw@redhat.com> and Red Hat, Inc.
- * Copyright (c) 2009, Witold Sowa <witold.sowa@gmail.com>
+ * Copyright (c) 2009-2010, Witold Sowa <witold.sowa@gmail.com>
+ * Copyright (c) 2009, Jouni Malinen <j@w1.fi>
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License version 2 as
 #include "common/ieee802_11_defs.h"
 #include "eap_peer/eap_methods.h"
 #include "eapol_supp/eapol_supp_sm.h"
+#include "rsn_supp/wpa.h"
 #include "../config.h"
 #include "../wpa_supplicant_i.h"
 #include "../driver_i.h"
 #include "../notify.h"
 #include "../wpas_glue.h"
+#include "../bss.h"
+#include "../scan.h"
 #include "dbus_new_helpers.h"
 #include "dbus_new.h"
 #include "dbus_new_handlers.h"
@@ -33,6 +37,10 @@ extern int wpa_debug_level;
 extern int wpa_debug_show_keys;
 extern int wpa_debug_timestamp;
 
+static const char *debug_strings[] = {
+       "msgdump", "debug", "info", "warning", "error", NULL
+};
+
 
 /**
  * wpas_dbus_new_decompose_object_path - Decompose an interface object path into parts
@@ -109,6 +117,20 @@ static char * wpas_dbus_new_decompose_object_path(const char *path,
 DBusMessage * wpas_dbus_error_unknown_error(DBusMessage *message,
                                            const char *arg)
 {
+       /*
+        * This function can be called as a result of a failure
+        * within internal getter calls, which will call this function
+        * with a NULL message parameter.  However, dbus_message_new_error
+        * looks very unkindly (i.e, abort()) on a NULL message, so
+        * in this case, we should not call it.
+        */
+       if (message == NULL) {
+               wpa_printf(MSG_INFO, "dbus: wpas_dbus_error_unknown_error "
+                          "called with NULL message (arg=%s)",
+                          arg ? arg : "N/A");
+               return NULL;
+       }
+
        return dbus_message_new_error(message, WPAS_DBUS_ERROR_UNKNOWN_ERROR,
                                      arg);
 }
@@ -145,13 +167,13 @@ static DBusMessage * wpas_dbus_error_network_unknown(DBusMessage *message)
 
 
 /**
- * wpas_dbus_error_invald_args - Return a new InvalidArgs error message
+ * wpas_dbus_error_invalid_args - Return a new InvalidArgs error message
  * @message: Pointer to incoming dbus message this error refers to
  * Returns: a dbus error message
  *
  * Convenience function to create and return an invalid options error
  */
-DBusMessage * wpas_dbus_error_invald_args(DBusMessage *message,
+DBusMessage * wpas_dbus_error_invalid_args(DBusMessage *message,
                                          const char *arg)
 {
        DBusMessage *reply;
@@ -184,18 +206,6 @@ static dbus_bool_t should_quote_opt(const char *key)
        return TRUE;
 }
 
-static struct wpa_scan_res * find_scan_result(struct bss_handler_args *bss)
-{
-       struct wpa_scan_results *results = bss->wpa_s->scan_res;
-       size_t i;
-       for (i = 0; results && i < results->num; i++) {
-               if (!os_memcmp(results->res[i]->bssid, bss->bssid, ETH_ALEN))
-                       return results->res[i];
-       }
-       return NULL;
-}
-
-
 /**
  * get_iface_by_dbus_path - Get a new network interface
  * @global: Pointer to global data from wpa_supplicant_init()
@@ -218,6 +228,7 @@ static struct wpa_supplicant * get_iface_by_dbus_path(
 /**
  * set_network_properties - Set properties of a configured network
  * @message: Pointer to incoming dbus message
+ * @wpa_s: wpa_supplicant structure for a network interface
  * @ssid: wpa_ssid structure for a configured network
  * @iter: DBus message iterator containing dictionary of network
  * properties to set.
@@ -226,6 +237,7 @@ static struct wpa_supplicant * get_iface_by_dbus_path(
  * Sets network configuration with parameters given id DBus dictionary
  */
 static DBusMessage * set_network_properties(DBusMessage *message,
+                                           struct wpa_supplicant *wpa_s,
                                            struct wpa_ssid *ssid,
                                            DBusMessageIter *iter)
 {
@@ -234,18 +246,16 @@ static DBusMessage * set_network_properties(DBusMessage *message,
        DBusMessage *reply = NULL;
        DBusMessageIter iter_dict;
 
-       if (!wpa_dbus_dict_open_read(iter, &iter_dict)) {
-               reply = wpas_dbus_error_invald_args(message, NULL);
-               goto out;
-       }
+       if (!wpa_dbus_dict_open_read(iter, &iter_dict))
+               return wpas_dbus_error_invalid_args(message, NULL);
 
        while (wpa_dbus_dict_has_dict_entry(&iter_dict)) {
                char *value = NULL;
                size_t size = 50;
                int ret;
                if (!wpa_dbus_dict_get_entry(&iter_dict, &entry)) {
-                       reply = wpas_dbus_error_invald_args(message, NULL);
-                       goto out;
+                       reply = wpas_dbus_error_invalid_args(message, NULL);
+                       break;
                }
                if (entry.type == DBUS_TYPE_ARRAY &&
                    entry.array_type == DBUS_TYPE_BYTE) {
@@ -262,55 +272,46 @@ static DBusMessage * set_network_properties(DBusMessage *message,
                                               entry.array_len);
                        if (ret <= 0)
                                goto error;
-               } else {
-                       if (entry.type == DBUS_TYPE_STRING) {
-                               if (should_quote_opt(entry.key)) {
-                                       size = os_strlen(entry.str_value);
-                                       if (size <= 0)
-                                               goto error;
-
-                                       size += 3;
-                                       value = os_zalloc(size);
-                                       if (value == NULL)
-                                               goto error;
-
-                                       ret = os_snprintf(value, size,
-                                                         "\"%s\"",
-                                                         entry.str_value);
-                                       if (ret < 0 ||
-                                           (size_t) ret != (size - 1))
-                                               goto error;
-                               } else {
-                                       value = os_strdup(entry.str_value);
-                                       if (value == NULL)
-                                               goto error;
-                               }
+               } else if (entry.type == DBUS_TYPE_STRING) {
+                       if (should_quote_opt(entry.key)) {
+                               size = os_strlen(entry.str_value);
+                               if (size <= 0)
+                                       goto error;
+
+                               size += 3;
+                               value = os_zalloc(size);
+                               if (value == NULL)
+                                       goto error;
+
+                               ret = os_snprintf(value, size, "\"%s\"",
+                                                 entry.str_value);
+                               if (ret < 0 || (size_t) ret != (size - 1))
+                                       goto error;
                        } else {
-                               if (entry.type == DBUS_TYPE_UINT32) {
-                                       value = os_zalloc(size);
-                                       if (value == NULL)
-                                               goto error;
-
-                                       ret = os_snprintf(value, size, "%u",
-                                                         entry.uint32_value);
-                                       if (ret <= 0)
-                                               goto error;
-                               } else {
-                                       if (entry.type == DBUS_TYPE_INT32) {
-                                               value = os_zalloc(size);
-                                               if (value == NULL)
-                                                       goto error;
-
-                                               ret = os_snprintf(
-                                                       value, size, "%d",
-                                                       entry.int32_value);
-                                               if (ret <= 0)
-                                                       goto error;
-                                       } else
-                                               goto error;
-                               }
+                               value = os_strdup(entry.str_value);
+                               if (value == NULL)
+                                       goto error;
                        }
-               }
+               } else if (entry.type == DBUS_TYPE_UINT32) {
+                       value = os_zalloc(size);
+                       if (value == NULL)
+                               goto error;
+
+                       ret = os_snprintf(value, size, "%u",
+                                         entry.uint32_value);
+                       if (ret <= 0)
+                               goto error;
+               } else if (entry.type == DBUS_TYPE_INT32) {
+                       value = os_zalloc(size);
+                       if (value == NULL)
+                               goto error;
+
+                       ret = os_snprintf(value, size, "%d",
+                                         entry.int32_value);
+                       if (ret <= 0)
+                               goto error;
+               } else
+                       goto error;
 
                if (wpa_config_set(ssid, entry.key, value, 0) < 0)
                        goto error;
@@ -319,6 +320,8 @@ static DBusMessage * set_network_properties(DBusMessage *message,
                     value[0] == '"' && ssid->ssid_len) ||
                    (strcmp(entry.key, "ssid") == 0 && ssid->passphrase))
                        wpa_config_update_psk(ssid);
+               else if (os_strcmp(entry.key, "priority") == 0)
+                       wpa_config_update_prio_list(wpa_s->conf);
 
                os_free(value);
                wpa_dbus_dict_entry_clear(&entry);
@@ -326,11 +329,220 @@ static DBusMessage * set_network_properties(DBusMessage *message,
 
        error:
                os_free(value);
-               reply = wpas_dbus_error_invald_args(message, entry.key);
+               reply = wpas_dbus_error_invalid_args(message, entry.key);
                wpa_dbus_dict_entry_clear(&entry);
                break;
        }
-out:
+
+       return reply;
+}
+
+
+/**
+ * wpas_dbus_simple_property_getter - Get basic type property
+ * @message: Pointer to incoming dbus message
+ * @type: DBus type of property (must be basic type)
+ * @val: pointer to place holding property value
+ * Returns: The DBus message containing response for Properties.Get call
+ * or DBus error message if error occurred.
+ *
+ * Generic getter for basic type properties. Type is required to be basic.
+ */
+DBusMessage * wpas_dbus_simple_property_getter(DBusMessage *message,
+                                              const int type, const void *val)
+{
+       DBusMessage *reply = NULL;
+       DBusMessageIter iter, variant_iter;
+
+       if (!dbus_type_is_basic(type)) {
+               wpa_printf(MSG_ERROR, "dbus: wpas_dbus_simple_property_getter:"
+                          " given type is not basic");
+               return wpas_dbus_error_unknown_error(message, NULL);
+       }
+
+       if (message == NULL)
+               reply = dbus_message_new(DBUS_MESSAGE_TYPE_SIGNAL);
+       else
+               reply = dbus_message_new_method_return(message);
+
+       if (reply != NULL) {
+               dbus_message_iter_init_append(reply, &iter);
+               if (!dbus_message_iter_open_container(
+                           &iter, DBUS_TYPE_VARIANT,
+                           wpa_dbus_type_as_string(type), &variant_iter) ||
+                   !dbus_message_iter_append_basic(&variant_iter, type,
+                                                   val) ||
+                   !dbus_message_iter_close_container(&iter, &variant_iter)) {
+                       wpa_printf(MSG_ERROR, "dbus: "
+                                  "wpas_dbus_simple_property_getter: out of "
+                                  "memory to put property value into "
+                                  "message");
+                       dbus_message_unref(reply);
+                       reply = dbus_message_new_error(message,
+                                                      DBUS_ERROR_NO_MEMORY,
+                                                      NULL);
+               }
+       } else {
+               wpa_printf(MSG_ERROR, "dbus: wpas_dbus_simple_property_getter:"
+                          " out of memory to return property value");
+               reply = dbus_message_new_error(message, DBUS_ERROR_NO_MEMORY,
+                                              NULL);
+       }
+
+       return reply;
+}
+
+
+/**
+ * wpas_dbus_simple_property_setter - Set basic type property
+ * @message: Pointer to incoming dbus message
+ * @type: DBus type of property (must be basic type)
+ * @val: pointer to place where value being set will be stored
+ * Returns: NULL or DBus error message if error occurred.
+ *
+ * Generic setter for basic type properties. Type is required to be basic.
+ */
+DBusMessage * wpas_dbus_simple_property_setter(DBusMessage *message,
+                                              const int type, void *val)
+{
+       DBusMessageIter iter, variant_iter;
+
+       if (!dbus_type_is_basic(type)) {
+               wpa_printf(MSG_ERROR, "dbus: wpas_dbus_simple_property_setter:"
+                          " given type is not basic");
+               return wpas_dbus_error_unknown_error(message, NULL);
+       }
+
+       if (!dbus_message_iter_init(message, &iter)) {
+               wpa_printf(MSG_ERROR, "dbus: wpas_dbus_simple_property_setter:"
+                          " out of memory to return scanning state");
+               return dbus_message_new_error(message, DBUS_ERROR_NO_MEMORY,
+                                             NULL);
+       }
+
+       /* omit first and second argument and get value from third */
+       dbus_message_iter_next(&iter);
+       dbus_message_iter_next(&iter);
+       dbus_message_iter_recurse(&iter, &variant_iter);
+
+       if (dbus_message_iter_get_arg_type(&variant_iter) != type) {
+               wpa_printf(MSG_DEBUG, "dbus: wpas_dbus_simple_property_setter:"
+                          " wrong property type");
+               return wpas_dbus_error_invalid_args(message,
+                                                   "wrong property type");
+       }
+       dbus_message_iter_get_basic(&variant_iter, val);
+
+       return NULL;
+}
+
+
+/**
+ * wpas_dbus_simple_array_property_getter - Get array type property
+ * @message: Pointer to incoming dbus message
+ * @type: DBus type of property array elements (must be basic type)
+ * @array: pointer to array of elements to put into response message
+ * @array_len: length of above array
+ * Returns: The DBus message containing response for Properties.Get call
+ * or DBus error message if error occurred.
+ *
+ * Generic getter for array type properties. Array elements type is
+ * required to be basic.
+ */
+DBusMessage * wpas_dbus_simple_array_property_getter(DBusMessage *message,
+                                                    const int type,
+                                                    const void *array,
+                                                    size_t array_len)
+{
+       DBusMessage *reply = NULL;
+       DBusMessageIter iter, variant_iter, array_iter;
+       char type_str[] = "a?"; /* ? will be replaced with subtype letter; */
+       const char *sub_type_str;
+       size_t element_size, i;
+
+       if (!dbus_type_is_basic(type)) {
+               wpa_printf(MSG_ERROR, "dbus: "
+                          "wpas_dbus_simple_array_property_getter: given "
+                          "type is not basic");
+               return wpas_dbus_error_unknown_error(message, NULL);
+       }
+
+       sub_type_str = wpa_dbus_type_as_string(type);
+       type_str[1] = sub_type_str[0];
+
+       if (message == NULL)
+               reply = dbus_message_new(DBUS_MESSAGE_TYPE_SIGNAL);
+       else
+               reply = dbus_message_new_method_return(message);
+       if (reply == NULL) {
+               wpa_printf(MSG_ERROR, "dbus: "
+                          "wpas_dbus_simple_array_property_getter: out of "
+                          "memory to create return message");
+               return dbus_message_new_error(message, DBUS_ERROR_NO_MEMORY,
+                                             NULL);
+       }
+
+       dbus_message_iter_init_append(reply, &iter);
+
+       if (!dbus_message_iter_open_container(&iter, DBUS_TYPE_VARIANT,
+                                             type_str, &variant_iter) ||
+           !dbus_message_iter_open_container(&variant_iter, DBUS_TYPE_ARRAY,
+                                             sub_type_str, &array_iter)) {
+               wpa_printf(MSG_ERROR, "dbus: "
+                          "wpas_dbus_simple_array_property_getter: out of "
+                          "memory to open container");
+               dbus_message_unref(reply);
+               return dbus_message_new_error(message, DBUS_ERROR_NO_MEMORY,
+                                             NULL);
+       }
+
+       switch(type) {
+       case DBUS_TYPE_BYTE:
+       case DBUS_TYPE_BOOLEAN:
+               element_size = 1;
+               break;
+       case DBUS_TYPE_INT16:
+       case DBUS_TYPE_UINT16:
+               element_size = sizeof(uint16_t);
+               break;
+       case DBUS_TYPE_INT32:
+       case DBUS_TYPE_UINT32:
+               element_size = sizeof(uint32_t);
+               break;
+       case DBUS_TYPE_INT64:
+       case DBUS_TYPE_UINT64:
+               element_size = sizeof(uint64_t);
+               break;
+       case DBUS_TYPE_DOUBLE:
+               element_size = sizeof(double);
+               break;
+       case DBUS_TYPE_STRING:
+       case DBUS_TYPE_OBJECT_PATH:
+               element_size = sizeof(char *);
+               break;
+       default:
+               wpa_printf(MSG_ERROR, "dbus: "
+                          "wpas_dbus_simple_array_property_getter: "
+                          "fatal: unknown element type");
+               element_size = 1;
+               break;
+       }
+
+       for (i = 0; i < array_len; i++) {
+               dbus_message_iter_append_basic(&array_iter, type,
+                                              array + i * element_size);
+       }
+
+       if (!dbus_message_iter_close_container(&variant_iter, &array_iter) ||
+           !dbus_message_iter_close_container(&iter, &variant_iter)) {
+               wpa_printf(MSG_ERROR, "dbus: "
+                          "wpas_dbus_simple_array_property_getter: out of "
+                          "memory to close container");
+               dbus_message_unref(reply);
+               return dbus_message_new_error(message, DBUS_ERROR_NO_MEMORY,
+                                             NULL);
+       }
+
        return reply;
 }
 
@@ -409,7 +621,7 @@ DBusMessage * wpas_dbus_handler_create_interface(DBusMessage *message,
                iface.bridge_ifname = bridge_ifname;
                /* Otherwise, have wpa_supplicant attach to it. */
                if ((wpa_s = wpa_supplicant_add_iface(global, &iface))) {
-                       const char *path = wpas_dbus_get_path(wpa_s);
+                       const char *path = wpa_s->dbus_new_path;
                        reply = dbus_message_new_method_return(message);
                        dbus_message_append_args(reply, DBUS_TYPE_OBJECT_PATH,
                                                 &path, DBUS_TYPE_INVALID);
@@ -427,7 +639,7 @@ out:
        return reply;
 
 error:
-       reply = wpas_dbus_error_invald_args(message, NULL);
+       reply = wpas_dbus_error_invalid_args(message, NULL);
        goto out;
 }
 
@@ -490,24 +702,13 @@ DBusMessage * wpas_dbus_handler_get_interface(DBusMessage *message,
        if (wpa_s == NULL)
                return wpas_dbus_error_iface_unknown(message);
 
-       path = wpas_dbus_get_path(wpa_s);
-       if (path == NULL) {
-               wpa_printf(MSG_ERROR, "wpas_dbus_handler_get_interface[dbus]: "
-                          "interface has no dbus object path set");
-               return wpas_dbus_error_unknown_error(message, "path not set");
-       }
-
+       path = wpa_s->dbus_new_path;
        reply = dbus_message_new_method_return(message);
-       if (reply == NULL) {
-               perror("wpas_dbus_handler_get_interface[dbus]: out of memory "
-                      "when creating reply");
+       if (reply == NULL)
                return dbus_message_new_error(message, DBUS_ERROR_NO_MEMORY,
                                              NULL);
-       }
        if (!dbus_message_append_args(reply, DBUS_TYPE_OBJECT_PATH, &path,
                                      DBUS_TYPE_INVALID)) {
-               perror("wpas_dbus_handler_get_interface[dbus]: out of memory "
-                      "when appending argument to reply");
                dbus_message_unref(reply);
                return dbus_message_new_error(message, DBUS_ERROR_NO_MEMORY,
                                              NULL);
@@ -518,190 +719,149 @@ DBusMessage * wpas_dbus_handler_get_interface(DBusMessage *message,
 
 
 /**
- * wpas_dbus_getter_debug_params - Get the debug params
+ * wpas_dbus_getter_debug_level - Get debug level
  * @message: Pointer to incoming dbus message
  * @global: %wpa_supplicant global data structure
- * Returns: DBus message with struct containing debug params.
+ * Returns: DBus message with value of debug level
  *
- * Getter for "DebugParams" property.
+ * Getter for "DebugLevel" property.
  */
-DBusMessage * wpas_dbus_getter_debug_params(DBusMessage *message,
-                                           struct wpa_global *global)
+DBusMessage * wpas_dbus_getter_debug_level(DBusMessage *message,
+                                          struct wpa_global *global)
 {
-       DBusMessage *reply = NULL;
-       DBusMessageIter iter, variant_iter, struct_iter;
+       const char *str;
+       int idx = wpa_debug_level;
+       if (idx < 0)
+               idx = 0;
+       if (idx > 4)
+               idx = 4;
+       str = debug_strings[idx];
+       return wpas_dbus_simple_property_getter(message, DBUS_TYPE_STRING,
+                                               &str);
+}
 
-       if (message == NULL)
-               reply = dbus_message_new(DBUS_MESSAGE_TYPE_SIGNAL);
-       else
-               reply = dbus_message_new_method_return(message);
-       if (!reply) {
-               perror("wpas_dbus_getter_network_properties[dbus] out of "
-                      "memory when trying to initialize return message");
-               reply = dbus_message_new_error(message, DBUS_ERROR_NO_MEMORY,
-                                              NULL);
-               goto out;
-       }
 
-       dbus_message_iter_init_append(reply, &iter);
+/**
+ * wpas_dbus_getter_debug_timestamp - Get debug timestamp
+ * @message: Pointer to incoming dbus message
+ * @global: %wpa_supplicant global data structure
+ * Returns: DBus message with value of debug timestamp
+ *
+ * Getter for "DebugTimestamp" property.
+ */
+DBusMessage * wpas_dbus_getter_debug_timestamp(DBusMessage *message,
+                                              struct wpa_global *global)
+{
+       return wpas_dbus_simple_property_getter(message, DBUS_TYPE_BOOLEAN,
+                                               &wpa_debug_timestamp);
 
-       if (!dbus_message_iter_open_container(&iter, DBUS_TYPE_VARIANT,
-                                             "(ibb)", &variant_iter)) {
-               perror("wpas_dbus_getter_debug_params[dbus] out of memory "
-                      "when trying to open variant");
-               dbus_message_unref(reply);
-               reply = dbus_message_new_error(message, DBUS_ERROR_NO_MEMORY,
-                                              NULL);
-               goto out;
-       }
+}
 
-       if (!dbus_message_iter_open_container(&variant_iter, DBUS_TYPE_STRUCT,
-                                             NULL, &struct_iter)) {
-               perror("wpas_dbus_getter_debug_params[dbus] out of memory "
-                      "when trying to open struct");
-               dbus_message_unref(reply);
-               reply = dbus_message_new_error(message, DBUS_ERROR_NO_MEMORY,
-                                              NULL);
-               goto out;
-       }
 
-       if (!dbus_message_iter_append_basic(&struct_iter, DBUS_TYPE_INT32,
-                                           &wpa_debug_level)) {
-               perror("wpas_dbus_getter_debug_params[dbus] out of memory "
-                      "when trying to append value to struct");
-               dbus_message_unref(reply);
-               reply = dbus_message_new_error(message, DBUS_ERROR_NO_MEMORY,
-                                              NULL);
-               goto out;
-       }
+/**
+ * wpas_dbus_getter_debug_show_keys - Get debug show keys
+ * @message: Pointer to incoming dbus message
+ * @global: %wpa_supplicant global data structure
+ * Returns: DBus message with value of debug show_keys
+ *
+ * Getter for "DebugShowKeys" property.
+ */
+DBusMessage * wpas_dbus_getter_debug_show_keys(DBusMessage *message,
+                                              struct wpa_global *global)
+{
+       return wpas_dbus_simple_property_getter(message, DBUS_TYPE_BOOLEAN,
+                                               &wpa_debug_show_keys);
 
-       if (!dbus_message_iter_append_basic(&struct_iter, DBUS_TYPE_BOOLEAN,
-                                           &wpa_debug_timestamp)) {
-               perror("wpas_dbus_getter_debug_params[dbus] out of memory "
-                      "when trying to append value to struct");
-               dbus_message_unref(reply);
-               reply = dbus_message_new_error(message, DBUS_ERROR_NO_MEMORY,
-                                              NULL);
-               goto out;
-       }
+}
 
-       if (!dbus_message_iter_append_basic(&struct_iter, DBUS_TYPE_BOOLEAN,
-                                           &wpa_debug_show_keys)) {
-               perror("wpas_dbus_getter_debug_params[dbus] out of memory "
-                      "when trying to append value to struct");
-               dbus_message_unref(reply);
-               reply = dbus_message_new_error(message, DBUS_ERROR_NO_MEMORY,
-                                              NULL);
-               goto out;
-       }
+/**
+ * wpas_dbus_setter_debug_level - Set debug level
+ * @message: Pointer to incoming dbus message
+ * @global: %wpa_supplicant global data structure
+ * Returns: %NULL or DBus error message
+ *
+ * Setter for "DebugLevel" property.
+ */
+DBusMessage * wpas_dbus_setter_debug_level(DBusMessage *message,
+                                          struct wpa_global *global)
+{
+       DBusMessage *reply;
+       const char *str = NULL;
+       int i, val = -1;
 
-       if (!dbus_message_iter_close_container(&variant_iter, &struct_iter)) {
-               perror("wpas_dbus_getter_debug_params[dbus] out of memory "
-                      "when trying to close struct");
-               dbus_message_unref(reply);
-               reply = dbus_message_new_error(message, DBUS_ERROR_NO_MEMORY,
-                                              NULL);
-               goto out;
-       }
+       reply = wpas_dbus_simple_property_setter(message, DBUS_TYPE_STRING,
+                                                &str);
+       if (reply)
+               return reply;
+
+       for (i = 0; debug_strings[i]; i++)
+               if (os_strcmp(debug_strings[i], str) == 0) {
+                       val = i;
+                       break;
+               }
 
-       if (!dbus_message_iter_close_container(&iter, &variant_iter)) {
-               perror("wpas_dbus_getter_debug_params[dbus] out of memory "
-                      "when trying to close variant");
+       if (val < 0 ||
+           wpa_supplicant_set_debug_params(global, val, wpa_debug_timestamp,
+                                           wpa_debug_show_keys)) {
                dbus_message_unref(reply);
-               reply = dbus_message_new_error(message, DBUS_ERROR_NO_MEMORY,
-                                              NULL);
-               goto out;
+               return wpas_dbus_error_invalid_args(
+                       message, "Wrong debug level value");
        }
 
-out:
-       return reply;
+       return NULL;
 }
 
 
 /**
- * wpas_dbus_setter_debugparams - Set the debug params
+ * wpas_dbus_setter_debug_timestamp - Set debug timestamp
  * @message: Pointer to incoming dbus message
  * @global: %wpa_supplicant global data structure
- * Returns: NULL indicating success or a dbus error message with more
- * information
+ * Returns: %NULL or DBus error message
  *
- * Setter for "DebugParams" property.
+ * Setter for "DebugTimestamp" property.
  */
-DBusMessage * wpas_dbus_setter_debug_params(DBusMessage *message,
-                                           struct wpa_global *global)
+DBusMessage * wpas_dbus_setter_debug_timestamp(DBusMessage *message,
+                                              struct wpa_global *global)
 {
-       DBusMessage *reply = NULL;
-       DBusMessageIter iter, variant_iter, struct_iter;
-       int debug_level;
-       dbus_bool_t debug_timestamp;
-       dbus_bool_t debug_show_keys;
-
-       if (!dbus_message_iter_init(message, &iter)) {
-               perror("wpas_dbus_handler_add_blob[dbus] out of memory when "
-                      "trying to initialize message iterator");
-               reply = dbus_message_new_error(message, DBUS_ERROR_NO_MEMORY,
-                                              NULL);
-               goto out;
-       }
-       dbus_message_iter_next(&iter);
-       dbus_message_iter_next(&iter);
+       DBusMessage *reply;
+       dbus_bool_t val;
 
-       dbus_message_iter_recurse(&iter, &variant_iter);
+       reply = wpas_dbus_simple_property_setter(message, DBUS_TYPE_BOOLEAN,
+                                                &val);
+       if (reply)
+               return reply;
 
-       if (dbus_message_iter_get_arg_type(&variant_iter) != DBUS_TYPE_STRUCT)
-       {
-               reply = wpas_dbus_error_invald_args(
-                       message, "Argument must by a structure");
-               goto out;
-       }
+       wpa_supplicant_set_debug_params(global, wpa_debug_level, val ? 1 : 0,
+                                       wpa_debug_show_keys);
 
-       dbus_message_iter_recurse(&variant_iter, &struct_iter);
+       return NULL;
+}
 
 
-       if (dbus_message_iter_get_arg_type(&struct_iter) != DBUS_TYPE_INT32) {
-               reply = wpas_dbus_error_invald_args(
-                       message, "First struct argument must by an INT32");
-               goto out;
-       }
+/**
+ * wpas_dbus_setter_debug_show_keys - Set debug show keys
+ * @message: Pointer to incoming dbus message
+ * @global: %wpa_supplicant global data structure
+ * Returns: %NULL or DBus error message
+ *
+ * Setter for "DebugShowKeys" property.
+ */
+DBusMessage * wpas_dbus_setter_debug_show_keys(DBusMessage *message,
+                                              struct wpa_global *global)
+{
+       DBusMessage *reply;
+       dbus_bool_t val;
 
-       dbus_message_iter_get_basic(&struct_iter, &debug_level);
-       if (!dbus_message_iter_next(&struct_iter)) {
-               reply = wpas_dbus_error_invald_args(
-                       message, "Not enough elements in struct");
-               goto out;
-       }
+       reply = wpas_dbus_simple_property_setter(message, DBUS_TYPE_BOOLEAN,
+                                                &val);
+       if (reply)
+               return reply;
 
-       if (dbus_message_iter_get_arg_type(&struct_iter) != DBUS_TYPE_BOOLEAN)
-       {
-               reply = wpas_dbus_error_invald_args(
-                       message, "Second struct argument must by a boolean");
-               goto out;
-       }
-       dbus_message_iter_get_basic(&struct_iter, &debug_timestamp);
-       if (!dbus_message_iter_next(&struct_iter)) {
-               reply = wpas_dbus_error_invald_args(
-                       message, "Not enough elements in struct");
-               goto out;
-       }
+       wpa_supplicant_set_debug_params(global, wpa_debug_level,
+                                       wpa_debug_timestamp,
+                                       val ? 1 : 0);
 
-       if (dbus_message_iter_get_arg_type(&struct_iter) != DBUS_TYPE_BOOLEAN)
-       {
-               reply = wpas_dbus_error_invald_args(
-                       message, "Third struct argument must by an boolean");
-               goto out;
-       }
-       dbus_message_iter_get_basic(&struct_iter, &debug_show_keys);
-
-       if (wpa_supplicant_set_debug_params(global, debug_level,
-                                           debug_timestamp ? 1 : 0,
-                                           debug_show_keys ? 1 : 0)) {
-               reply = wpas_dbus_error_invald_args(
-                       message, "Wrong debug level value");
-               goto out;
-       }
-
-out:
-       return reply;
+       return NULL;
 }
 
 
@@ -720,74 +880,27 @@ DBusMessage * wpas_dbus_getter_interfaces(DBusMessage *message,
                                          struct wpa_global *global)
 {
        DBusMessage *reply = NULL;
-       DBusMessageIter iter, variant_iter, array_iter;
-       const char *path;
        struct wpa_supplicant *wpa_s;
+       const char **paths;
+       unsigned int i = 0, num = 0;
 
-       if (message == NULL)
-               reply = dbus_message_new(DBUS_MESSAGE_TYPE_SIGNAL);
-       else
-               reply = dbus_message_new_method_return(message);
-       if (!reply) {
-               perror("wpas_dbus_getter_interfaces[dbus] out of memory "
-                      "when trying to initialize return message");
-               reply = dbus_message_new_error(message, DBUS_ERROR_NO_MEMORY,
-                                              NULL);
-               goto out;
-       }
+       for (wpa_s = global->ifaces; wpa_s; wpa_s = wpa_s->next)
+               num++;
 
-       dbus_message_iter_init_append(reply, &iter);
-       if (!dbus_message_iter_open_container(&iter, DBUS_TYPE_VARIANT,
-                                             "ao", &variant_iter)) {
-               perror("wpas_dbus_getter_interfaces[dbus] out of memory "
-                      "when trying to open variant");
-               dbus_message_unref(reply);
-               reply = dbus_message_new_error(message, DBUS_ERROR_NO_MEMORY,
-                                              NULL);
-               goto out;
-       }
-       if (!dbus_message_iter_open_container(&variant_iter, DBUS_TYPE_ARRAY,
-                                             "o", &array_iter)) {
-               perror("wpas_dbus_getter_interfaces[dbus] out of memory "
-                      "when trying to open array");
-               dbus_message_unref(reply);
-               reply = dbus_message_new_error(message, DBUS_ERROR_NO_MEMORY,
-                                              NULL);
-               goto out;
+       paths = os_zalloc(num * sizeof(char*));
+       if (!paths) {
+               return dbus_message_new_error(message, DBUS_ERROR_NO_MEMORY,
+                                             NULL);
        }
 
-       for (wpa_s = global->ifaces; wpa_s; wpa_s = wpa_s->next) {
-               path = wpas_dbus_get_path(wpa_s);
-               if (!dbus_message_iter_append_basic(&array_iter,
-                                                   DBUS_TYPE_OBJECT_PATH,
-                                                   &path)) {
-                       perror("wpas_dbus_getter_interfaces[dbus] out of "
-                              "memory when trying to append interface path");
-                       dbus_message_unref(reply);
-                       reply = dbus_message_new_error(message,
-                                                      DBUS_ERROR_NO_MEMORY,
-                                                      NULL);
-                       goto out;
-               }
-       }
+       for (wpa_s = global->ifaces; wpa_s; wpa_s = wpa_s->next)
+               paths[i] = wpa_s->dbus_new_path;
 
-       if (!dbus_message_iter_close_container(&variant_iter, &array_iter)) {
-               perror("wpas_dbus_getter_interfaces[dbus] out of memory "
-                      "when trying to close array");
-               reply = dbus_message_new_error(message, DBUS_ERROR_NO_MEMORY,
-                                              NULL);
-               goto out;
-       }
-       if (!dbus_message_iter_close_container(&iter, &variant_iter)) {
-               perror("wpas_dbus_getter_interfaces[dbus] out of memory "
-                      "when trying to close variant");
-               dbus_message_unref(reply);
-               reply = dbus_message_new_error(message, DBUS_ERROR_NO_MEMORY,
-                                              NULL);
-               goto out;
-       }
+       reply = wpas_dbus_simple_array_property_getter(message,
+                                                      DBUS_TYPE_OBJECT_PATH,
+                                                      paths, num);
 
-out:
+       os_free(paths);
        return reply;
 }
 
@@ -805,86 +918,22 @@ out:
 DBusMessage * wpas_dbus_getter_eap_methods(DBusMessage *message, void *nothing)
 {
        DBusMessage *reply = NULL;
-       DBusMessageIter iter, variant_iter, array_iter;
        char **eap_methods;
-       size_t num_items;
-
-       if (message == NULL)
-               reply = dbus_message_new(DBUS_MESSAGE_TYPE_SIGNAL);
-       else
-               reply = dbus_message_new_method_return(message);
-       if (!reply) {
-               perror("wpas_dbus_getter_eap_methods[dbus] out of memory "
-                      "when trying to initialize return message");
-               reply = dbus_message_new_error(message, DBUS_ERROR_NO_MEMORY,
-                                              NULL);
-               goto out;
-       }
-
-       dbus_message_iter_init_append(reply, &iter);
-       if (!dbus_message_iter_open_container(&iter, DBUS_TYPE_VARIANT,
-                                             "as", &variant_iter)) {
-               perror("wpas_dbus_getter_eap_methods[dbus] out of memory "
-                      "when trying to open variant");
-               dbus_message_unref(reply);
-               reply = dbus_message_new_error(message, DBUS_ERROR_NO_MEMORY,
-                                              NULL);
-               goto out;
-       }
-
-       if (!dbus_message_iter_open_container(&variant_iter, DBUS_TYPE_ARRAY,
-                                             "s", &array_iter)) {
-               perror("wpas_dbus_getter_eap_methods[dbus] out of memory "
-                      "when trying to open variant");
-               dbus_message_unref(reply);
-               reply = dbus_message_new_error(message, DBUS_ERROR_NO_MEMORY,
-                                              NULL);
-               goto out;
-       }
+       size_t num_items = 0;
 
        eap_methods = eap_get_names_as_string_array(&num_items);
-       if (eap_methods) {
-               size_t i;
-               int err = 0;
-               for (i = 0; i < num_items; i++) {
-                       if (!dbus_message_iter_append_basic(&array_iter,
-                                                           DBUS_TYPE_STRING,
-                                                           &(eap_methods[i])))
-                               err = 1;
-                       os_free(eap_methods[i]);
-               }
-               os_free(eap_methods);
-
-               if (err) {
-                       wpa_printf(MSG_ERROR, "wpas_dbus_getter_eap_methods"
-                                  "[dbus] out of memory when adding to "
-                                  "array");
-                       dbus_message_unref(reply);
-                       reply = dbus_message_new_error(message,
-                                                      DBUS_ERROR_NO_MEMORY,
-                                                      NULL);
-                       goto out;
-               }
+       if (!eap_methods) {
+               return dbus_message_new_error(message, DBUS_ERROR_NO_MEMORY,
+                                             NULL);
        }
 
-       if (!dbus_message_iter_close_container(&variant_iter, &array_iter)) {
-               perror("wpas_dbus_getter_eap_methods[dbus] "
-                      "out of memory when trying to close array");
-               dbus_message_unref(reply);
-               reply = dbus_message_new_error(message, DBUS_ERROR_NO_MEMORY,
-                                              NULL);
-                       goto out;
-       }
-       if (!dbus_message_iter_close_container(&iter, &variant_iter)) {
-               perror("wpas_dbus_getter_eap_methods[dbus] "
-                      "out of memory when trying to close variant");
-               dbus_message_unref(reply);
-               reply = dbus_message_new_error(message, DBUS_ERROR_NO_MEMORY,
-                                              NULL);
-               goto out;
-       }
+       reply = wpas_dbus_simple_array_property_getter(message,
+                                                      DBUS_TYPE_STRING,
+                                                      eap_methods, num_items);
 
-out:
+       while (num_items)
+               os_free(eap_methods[--num_items]);
+       os_free(eap_methods);
        return reply;
 }
 
@@ -895,7 +944,7 @@ static int wpas_dbus_get_scan_type(DBusMessage *message, DBusMessageIter *var,
        if (dbus_message_iter_get_arg_type(var) != DBUS_TYPE_STRING) {
                wpa_printf(MSG_DEBUG, "wpas_dbus_handler_scan[dbus]: "
                           "Type must be a string");
-               *reply = wpas_dbus_error_invald_args(
+               *reply = wpas_dbus_error_invalid_args(
                        message, "Wrong Type value type. String required");
                return -1;
        }
@@ -918,7 +967,7 @@ static int wpas_dbus_get_scan_ssids(DBusMessage *message, DBusMessageIter *var,
        if (dbus_message_iter_get_arg_type(var) != DBUS_TYPE_ARRAY) {
                wpa_printf(MSG_DEBUG, "wpas_dbus_handler_scan[dbus]: ssids "
                           "must be an array of arrays of bytes");
-               *reply = wpas_dbus_error_invald_args(
+               *reply = wpas_dbus_error_invalid_args(
                        message, "Wrong SSIDs value type. Array of arrays of "
                        "bytes required");
                return -1;
@@ -931,7 +980,7 @@ static int wpas_dbus_get_scan_ssids(DBusMessage *message, DBusMessageIter *var,
        {
                wpa_printf(MSG_DEBUG, "wpas_dbus_handler_scan[dbus]: ssids "
                           "must be an array of arrays of bytes");
-               *reply = wpas_dbus_error_invald_args(
+               *reply = wpas_dbus_error_invalid_args(
                        message, "Wrong SSIDs value type. Array of arrays of "
                        "bytes required");
                return -1;
@@ -943,7 +992,7 @@ static int wpas_dbus_get_scan_ssids(DBusMessage *message, DBusMessageIter *var,
                        wpa_printf(MSG_DEBUG, "wpas_dbus_handler_scan[dbus]: "
                                   "Too many ssids specified on scan dbus "
                                   "call");
-                       *reply = wpas_dbus_error_invald_args(
+                       *reply = wpas_dbus_error_invalid_args(
                                message, "Too many ssids specified. Specify "
                                "at most four");
                        return -1;
@@ -952,21 +1001,24 @@ static int wpas_dbus_get_scan_ssids(DBusMessage *message, DBusMessageIter *var,
                dbus_message_iter_recurse(&array_iter, &sub_array_iter);
 
                dbus_message_iter_get_fixed_array(&sub_array_iter, &val, &len);
-               if (len == 0) {
-                       dbus_message_iter_next(&array_iter);
-                       continue;
-               }
 
-               ssid = os_malloc(len);
-               if (ssid == NULL) {
-                       wpa_printf(MSG_DEBUG, "wpas_dbus_handler_scan[dbus]: "
-                                  "out of memory. Cannot allocate memory for "
-                                  "SSID");
-                       *reply = dbus_message_new_error(
-                               message, DBUS_ERROR_NO_MEMORY, NULL);
-                       return -1;
+               if (len != 0) {
+                       ssid = os_malloc(len);
+                       if (ssid == NULL) {
+                               wpa_printf(MSG_DEBUG,
+                                          "wpas_dbus_handler_scan[dbus]: "
+                                          "out of memory. Cannot allocate "
+                                          "memory for SSID");
+                               *reply = dbus_message_new_error(
+                                       message, DBUS_ERROR_NO_MEMORY, NULL);
+                               return -1;
+                       }
+                       os_memcpy(ssid, val, len);
+               } else {
+                       /* Allow zero-length SSIDs */
+                       ssid = NULL;
                }
-               os_memcpy(ssid, val, len);
+
                ssids[ssids_num].ssid = ssid;
                ssids[ssids_num].ssid_len = len;
 
@@ -992,7 +1044,7 @@ static int wpas_dbus_get_scan_ies(DBusMessage *message, DBusMessageIter *var,
        if (dbus_message_iter_get_arg_type(var) != DBUS_TYPE_ARRAY) {
                wpa_printf(MSG_DEBUG, "wpas_dbus_handler_scan[dbus]: ies must "
                           "be an array of arrays of bytes");
-               *reply = wpas_dbus_error_invald_args(
+               *reply = wpas_dbus_error_invalid_args(
                        message, "Wrong IEs value type. Array of arrays of "
                        "bytes required");
                return -1;
@@ -1005,7 +1057,7 @@ static int wpas_dbus_get_scan_ies(DBusMessage *message, DBusMessageIter *var,
        {
                wpa_printf(MSG_DEBUG, "wpas_dbus_handler_scan[dbus]: ies must "
                           "be an array of arrays of bytes");
-               *reply = wpas_dbus_error_invald_args(
+               *reply = wpas_dbus_error_invalid_args(
                        message, "Wrong IEs value type. Array required");
                return -1;
        }
@@ -1055,7 +1107,7 @@ static int wpas_dbus_get_scan_channels(DBusMessage *message,
        if (dbus_message_iter_get_arg_type(var) != DBUS_TYPE_ARRAY) {
                wpa_printf(MSG_DEBUG, "wpas_dbus_handler_scan[dbus]: "
                           "Channels must be an array of structs");
-               *reply = wpas_dbus_error_invald_args(
+               *reply = wpas_dbus_error_invalid_args(
                        message, "Wrong Channels value type. Array of structs "
                        "required");
                return -1;
@@ -1067,7 +1119,7 @@ static int wpas_dbus_get_scan_channels(DBusMessage *message,
                wpa_printf(MSG_DEBUG,
                           "wpas_dbus_handler_scan[dbus]: Channels must be an "
                           "array of structs");
-               *reply = wpas_dbus_error_invald_args(
+               *reply = wpas_dbus_error_invalid_args(
                        message, "Wrong Channels value type. Array of structs "
                        "required");
                return -1;
@@ -1086,7 +1138,7 @@ static int wpas_dbus_get_scan_channels(DBusMessage *message,
                                   "two UINT32s %c",
                                   dbus_message_iter_get_arg_type(
                                           &sub_array_iter));
-                       *reply = wpas_dbus_error_invald_args(
+                       *reply = wpas_dbus_error_invalid_args(
                                message, "Wrong Channel struct. Two UINT32s "
                                "required");
                        os_free(freqs);
@@ -1100,7 +1152,7 @@ static int wpas_dbus_get_scan_channels(DBusMessage *message,
                        wpa_printf(MSG_DEBUG, "wpas_dbus_handler_scan[dbus]: "
                                   "Channel must by specified by struct of "
                                   "two UINT32s");
-                       *reply = wpas_dbus_error_invald_args(
+                       *reply = wpas_dbus_error_invalid_args(
                                message,
                                "Wrong Channel struct. Two UINT32s required");
                        os_free(freqs);
@@ -1202,7 +1254,7 @@ DBusMessage * wpas_dbus_handler_scan(DBusMessage *message,
                } else {
                        wpa_printf(MSG_DEBUG, "wpas_dbus_handler_scan[dbus]: "
                                   "Unknown argument %s", key);
-                       reply = wpas_dbus_error_invald_args(message, key);
+                       reply = wpas_dbus_error_invalid_args(message, key);
                        goto out;
                }
 
@@ -1212,7 +1264,7 @@ DBusMessage * wpas_dbus_handler_scan(DBusMessage *message,
        if (!type) {
                wpa_printf(MSG_DEBUG, "wpas_dbus_handler_scan[dbus]: "
                           "Scan type not specified");
-               reply = wpas_dbus_error_invald_args(message, key);
+               reply = wpas_dbus_error_invalid_args(message, key);
                goto out;
        }
 
@@ -1220,25 +1272,27 @@ DBusMessage * wpas_dbus_handler_scan(DBusMessage *message,
                if (params.num_ssids || params.extra_ies_len) {
                        wpa_printf(MSG_DEBUG, "wpas_dbus_handler_scan[dbus]: "
                                   "SSIDs or IEs specified for passive scan.");
-                       reply = wpas_dbus_error_invald_args(
+                       reply = wpas_dbus_error_invalid_args(
                                message, "You can specify only Channels in "
                                "passive scan");
                        goto out;
                } else if (params.freqs && params.freqs[0]) {
-                       /* wildcard ssid */
-                       params.num_ssids++;
                        wpa_supplicant_trigger_scan(wpa_s, &params);
                } else {
                        wpa_s->scan_req = 2;
                        wpa_supplicant_req_scan(wpa_s, 0, 0);
                }
        } else if (!os_strcmp(type, "active")) {
+               if (!params.num_ssids) {
+                       /* Add wildcard ssid */
+                       params.num_ssids++;
+               }
                wpa_supplicant_trigger_scan(wpa_s, &params);
        } else {
                wpa_printf(MSG_DEBUG, "wpas_dbus_handler_scan[dbus]: "
                           "Unknown scan type: %s", type);
-               reply = wpas_dbus_error_invald_args(message,
-                                                   "Wrong scan type");
+               reply = wpas_dbus_error_invalid_args(message,
+                                                    "Wrong scan type");
                goto out;
        }
 
@@ -1265,7 +1319,8 @@ DBusMessage * wpas_dbus_handler_disconnect(DBusMessage *message,
 {
        if (wpa_s->current_ssid != NULL) {
                wpa_s->disconnected = 1;
-               wpa_supplicant_disassociate(wpa_s, WLAN_REASON_DEAUTH_LEAVING);
+               wpa_supplicant_deauthenticate(wpa_s,
+                                             WLAN_REASON_DEAUTH_LEAVING);
 
                return NULL;
        }
@@ -1289,16 +1344,7 @@ DBusMessage * wpas_dbus_handler_add_network(DBusMessage *message,
        DBusMessage *reply = NULL;
        DBusMessageIter iter;
        struct wpa_ssid *ssid = NULL;
-       char *path = NULL;
-
-       path = os_zalloc(WPAS_DBUS_OBJECT_PATH_MAX);
-       if (path == NULL) {
-               perror("wpas_dbus_handler_add_network[dbus]: out of "
-                      "memory.");
-               reply = dbus_message_new_error(message, DBUS_ERROR_NO_MEMORY,
-                                              NULL);
-               goto err;
-       }
+       char path_buf[WPAS_DBUS_OBJECT_PATH_MAX], *path = path_buf;
 
        dbus_message_iter_init(message, &iter);
 
@@ -1316,7 +1362,7 @@ DBusMessage * wpas_dbus_handler_add_network(DBusMessage *message,
        ssid->disabled = 1;
        wpa_config_set_network_defaults(ssid);
 
-       reply = set_network_properties(message, ssid, &iter);
+       reply = set_network_properties(message, wpa_s, ssid, &iter);
        if (reply) {
                wpa_printf(MSG_DEBUG, "wpas_dbus_handler_add_network[dbus]:"
                           "control interface couldn't set network "
@@ -1327,28 +1373,22 @@ DBusMessage * wpas_dbus_handler_add_network(DBusMessage *message,
        /* Construct the object path for this network. */
        os_snprintf(path, WPAS_DBUS_OBJECT_PATH_MAX,
                    "%s/" WPAS_DBUS_NEW_NETWORKS_PART "/%d",
-                   wpas_dbus_get_path(wpa_s),
-                   ssid->id);
+                   wpa_s->dbus_new_path, ssid->id);
 
        reply = dbus_message_new_method_return(message);
        if (reply == NULL) {
-               perror("wpas_dbus_handler_add_network[dbus]: out of memory "
-                      "when creating reply");
                reply = dbus_message_new_error(message, DBUS_ERROR_NO_MEMORY,
                                               NULL);
                goto err;
        }
        if (!dbus_message_append_args(reply, DBUS_TYPE_OBJECT_PATH, &path,
                                      DBUS_TYPE_INVALID)) {
-               perror("wpas_dbus_handler_add_network[dbus]: out of memory "
-                      "when appending argument to reply");
                dbus_message_unref(reply);
                reply = dbus_message_new_error(message, DBUS_ERROR_NO_MEMORY,
                                               NULL);
                goto err;
        }
 
-       os_free(path);
        return reply;
 
 err:
@@ -1356,7 +1396,6 @@ err:
                wpas_notify_network_removed(wpa_s, ssid);
                wpa_config_remove_network(wpa_s->conf, ssid->id);
        }
-       os_free(path);
        return reply;
 }
 
@@ -1384,14 +1423,14 @@ DBusMessage * wpas_dbus_handler_remove_network(DBusMessage *message,
        /* Extract the network ID and ensure the network */
        /* is actually a child of this interface */
        iface = wpas_dbus_new_decompose_object_path(op, &net_id, NULL);
-       if (iface == NULL || strcmp(iface, wpas_dbus_get_path(wpa_s)) != 0) {
-               reply = wpas_dbus_error_invald_args(message, op);
+       if (iface == NULL || os_strcmp(iface, wpa_s->dbus_new_path) != 0) {
+               reply = wpas_dbus_error_invalid_args(message, op);
                goto out;
        }
 
        id = strtoul(net_id, NULL, 10);
        if (errno == EINVAL) {
-               reply = wpas_dbus_error_invald_args(message, op);
+               reply = wpas_dbus_error_invalid_args(message, op);
                goto out;
        }
 
@@ -1414,7 +1453,8 @@ DBusMessage * wpas_dbus_handler_remove_network(DBusMessage *message,
        }
 
        if (ssid == wpa_s->current_ssid)
-               wpa_supplicant_disassociate(wpa_s, WLAN_REASON_DEAUTH_LEAVING);
+               wpa_supplicant_deauthenticate(wpa_s,
+                                             WLAN_REASON_DEAUTH_LEAVING);
 
 out:
        os_free(iface);
@@ -1446,14 +1486,14 @@ DBusMessage * wpas_dbus_handler_select_network(DBusMessage *message,
        /* Extract the network ID and ensure the network */
        /* is actually a child of this interface */
        iface = wpas_dbus_new_decompose_object_path(op, &net_id, NULL);
-       if (iface == NULL || strcmp(iface, wpas_dbus_get_path(wpa_s)) != 0) {
-               reply = wpas_dbus_error_invald_args(message, op);
+       if (iface == NULL || os_strcmp(iface, wpa_s->dbus_new_path) != 0) {
+               reply = wpas_dbus_error_invalid_args(message, op);
                goto out;
        }
 
        id = strtoul(net_id, NULL, 10);
        if (errno == EINVAL) {
-               reply = wpas_dbus_error_invald_args(message, op);
+               reply = wpas_dbus_error_invalid_args(message, op);
                goto out;
        }
 
@@ -1508,8 +1548,6 @@ DBusMessage * wpas_dbus_handler_add_blob(DBusMessage *message,
 
        blob = os_zalloc(sizeof(*blob));
        if (!blob) {
-               perror("wpas_dbus_handler_add_blob[dbus] out of memory when "
-                      "trying to allocate blob struct");
                reply = dbus_message_new_error(message, DBUS_ERROR_NO_MEMORY,
                                               NULL);
                goto err;
@@ -1517,8 +1555,6 @@ DBusMessage * wpas_dbus_handler_add_blob(DBusMessage *message,
 
        blob->data = os_malloc(blob_len);
        if (!blob->data) {
-               perror("wpas_dbus_handler_add_blob[dbus] out of memory when "
-                      "trying to allocate blob data");
                reply = dbus_message_new_error(message, DBUS_ERROR_NO_MEMORY,
                                               NULL);
                goto err;
@@ -1528,8 +1564,6 @@ DBusMessage * wpas_dbus_handler_add_blob(DBusMessage *message,
        blob->len = blob_len;
        blob->name = os_strdup(blob_name);
        if (!blob->name) {
-               perror("wpas_dbus_handler_add_blob[dbus] out of memory when "
-                      "trying to copy blob name");
                reply = dbus_message_new_error(message, DBUS_ERROR_NO_MEMORY,
                                               NULL);
                goto err;
@@ -1579,8 +1613,6 @@ DBusMessage * wpas_dbus_handler_get_blob(DBusMessage *message,
 
        reply = dbus_message_new_method_return(message);
        if (!reply) {
-               perror("wpas_dbus_handler_get_blob[dbus] out of memory when "
-                      "trying to allocate return message");
                reply = dbus_message_new_error(message, DBUS_ERROR_NO_MEMORY,
                                               NULL);
                goto out;
@@ -1592,8 +1624,6 @@ DBusMessage * wpas_dbus_handler_get_blob(DBusMessage *message,
                                              DBUS_TYPE_BYTE_AS_STRING,
                                              &array_iter)) {
                dbus_message_unref(reply);
-               perror("wpas_dbus_handler_get_blob[dbus] out of memory when "
-                      "trying to open array");
                reply = dbus_message_new_error(message, DBUS_ERROR_NO_MEMORY,
                                               NULL);
                goto out;
@@ -1602,8 +1632,6 @@ DBusMessage * wpas_dbus_handler_get_blob(DBusMessage *message,
        if (!dbus_message_iter_append_fixed_array(&array_iter, DBUS_TYPE_BYTE,
                                                  &(blob->data), blob->len)) {
                dbus_message_unref(reply);
-               perror("wpas_dbus_handler_get_blob[dbus] out of memory when "
-                      "trying to append data to array");
                reply = dbus_message_new_error(message, DBUS_ERROR_NO_MEMORY,
                                               NULL);
                goto out;
@@ -1611,8 +1639,6 @@ DBusMessage * wpas_dbus_handler_get_blob(DBusMessage *message,
 
        if (!dbus_message_iter_close_container(&iter, &array_iter)) {
                dbus_message_unref(reply);
-               perror("wpas_dbus_handler_get_blob[dbus] out of memory when "
-                      "trying to close array");
                reply = dbus_message_new_error(message, DBUS_ERROR_NO_MEMORY,
                                               NULL);
                goto out;
@@ -1809,6 +1835,18 @@ DBusMessage * wpas_dbus_getter_capabilities(DBusMessage *message,
                        if (!wpa_dbus_dict_string_array_add_element(
                                    &iter_array, "wpa-eap"))
                                goto nomem;
+
+                       if (capa.key_mgmt & WPA_DRIVER_CAPA_KEY_MGMT_FT)
+                               if (!wpa_dbus_dict_string_array_add_element(
+                                           &iter_array, "wpa-ft-eap"))
+                                       goto nomem;
+
+/* TODO: Ensure that driver actually supports sha256 encryption. */
+#ifdef CONFIG_IEEE80211W
+                       if (!wpa_dbus_dict_string_array_add_element(
+                                   &iter_array, "wpa-eap-sha256"))
+                               goto nomem;
+#endif /* CONFIG_IEEE80211W */
                }
 
                if (capa.key_mgmt & (WPA_DRIVER_CAPA_KEY_MGMT_WPA_PSK |
@@ -1816,6 +1854,18 @@ DBusMessage * wpas_dbus_getter_capabilities(DBusMessage *message,
                        if (!wpa_dbus_dict_string_array_add_element(
                                    &iter_array, "wpa-psk"))
                                goto nomem;
+
+                       if (capa.key_mgmt & WPA_DRIVER_CAPA_KEY_MGMT_FT_PSK)
+                               if (!wpa_dbus_dict_string_array_add_element(
+                                           &iter_array, "wpa-ft-psk"))
+                                       goto nomem;
+
+/* TODO: Ensure that driver actually supports sha256 encryption. */
+#ifdef CONFIG_IEEE80211W
+                       if (!wpa_dbus_dict_string_array_add_element(
+                                   &iter_array, "wpa-psk-sha256"))
+                               goto nomem;
+#endif /* CONFIG_IEEE80211W */
                }
 
                if (capa.key_mgmt & WPA_DRIVER_CAPA_KEY_MGMT_WPA_NONE) {
@@ -1951,74 +2001,32 @@ DBusMessage * wpas_dbus_getter_state(DBusMessage *message,
                                     struct wpa_supplicant *wpa_s)
 {
        DBusMessage *reply = NULL;
-       DBusMessageIter iter, variant_iter;
        const char *str_state;
        char *state_ls, *tmp;
 
-       if (message == NULL)
-               reply = dbus_message_new(DBUS_MESSAGE_TYPE_SIGNAL);
-       else
-               reply = dbus_message_new_method_return(message);
-       if (reply != NULL) {
-               dbus_message_iter_init_append(reply, &iter);
-               if (!dbus_message_iter_open_container(&iter, DBUS_TYPE_VARIANT,
-                                                     "s", &variant_iter)) {
-                       perror("wpas_dbus_getter_state[dbus] out of memory "
-                              "when trying to open variant");
-                       dbus_message_unref(reply);
-                       reply = dbus_message_new_error(message,
-                                                      DBUS_ERROR_NO_MEMORY,
-                                                      NULL);
-                       goto out;
-               }
+       str_state = wpa_supplicant_state_txt(wpa_s->wpa_state);
 
-               str_state = wpa_supplicant_state_txt(wpa_s->wpa_state);
+       /* make state string lowercase to fit new DBus API convention
+        */
+       state_ls = tmp = os_strdup(str_state);
+       if (!tmp) {
+               return dbus_message_new_error(message, DBUS_ERROR_NO_MEMORY,
+                                             NULL);
+       }
+       while (*tmp) {
+               *tmp = tolower(*tmp);
+               tmp++;
+       }
 
-               /* make state string lowercase to fit new DBus API convention
-                */
-               state_ls = tmp = os_strdup(str_state);
-               if (!tmp) {
-                       perror("wpas_dbus_getter_state[dbus] out of memory "
-                                       "when trying read state");
-                       dbus_message_unref(reply);
-                       reply = dbus_message_new_error(message,
-                                                      DBUS_ERROR_NO_MEMORY,
-                                                      NULL);
-                       goto out;
-               }
-               while (*tmp) {
-                       *tmp = tolower(*tmp);
-                       tmp++;
-               }
+       reply = wpas_dbus_simple_property_getter(message, DBUS_TYPE_STRING,
+                                                &state_ls);
 
-               if (!dbus_message_iter_append_basic(&variant_iter,
-                                                   DBUS_TYPE_STRING,
-                                                   &state_ls)) {
-                       perror("wpas_dbus_getter_state[dbus] out of memory "
-                              "when trying append state");
-                       dbus_message_unref(reply);
-                       reply = dbus_message_new_error(message,
-                                                      DBUS_ERROR_NO_MEMORY,
-                                                      NULL);
-                       goto err;
-               }
-               if (!dbus_message_iter_close_container(&iter, &variant_iter)) {
-                       perror("wpas_dbus_getter_state[dbus] out of memory "
-                              "when trying close variant");
-                       dbus_message_unref(reply);
-                       reply = dbus_message_new_error(message,
-                                                      DBUS_ERROR_NO_MEMORY,
-                                                      NULL);
-                       goto err;
-               }
-       err:
-               os_free(state_ls);
-       }
+       os_free(state_ls);
 
-out:
        return reply;
 }
 
+
 /**
  * wpas_dbus_new_iface_get_scanning - Get interface scanning state
  * @message: Pointer to incoming dbus message
@@ -2030,38 +2038,9 @@ out:
 DBusMessage * wpas_dbus_getter_scanning(DBusMessage *message,
                                        struct wpa_supplicant *wpa_s)
 {
-       DBusMessage *reply = NULL;
-       DBusMessageIter iter, variant_iter;
        dbus_bool_t scanning = wpa_s->scanning ? TRUE : FALSE;
-
-       if (message == NULL)
-               reply = dbus_message_new(DBUS_MESSAGE_TYPE_SIGNAL);
-       else
-               reply = dbus_message_new_method_return(message);
-
-       if (reply != NULL) {
-               dbus_message_iter_init_append(reply, &iter);
-               if (!dbus_message_iter_open_container(&iter, DBUS_TYPE_VARIANT,
-                                                     "b", &variant_iter) ||
-                   !dbus_message_iter_append_basic(&variant_iter,
-                                                   DBUS_TYPE_BOOLEAN,
-                                                   &scanning) ||
-                   !dbus_message_iter_close_container(&iter, &variant_iter)) {
-                       perror("wpas_dbus_getter_scanning[dbus]: out of "
-                              "memory to put scanning state into message.");
-                       dbus_message_unref(reply);
-                       reply = dbus_message_new_error(message,
-                                                      DBUS_ERROR_NO_MEMORY,
-                                                      NULL);
-               }
-       } else {
-               perror("wpas_dbus_getter_scanning[dbus]: out of "
-                      "memory to return scanning state.");
-               reply = dbus_message_new_error(message, DBUS_ERROR_NO_MEMORY,
-                                              NULL);
-       }
-
-       return reply;
+       return wpas_dbus_simple_property_getter(message, DBUS_TYPE_BOOLEAN,
+                                               &scanning);
 }
 
 
@@ -2076,38 +2055,9 @@ DBusMessage * wpas_dbus_getter_scanning(DBusMessage *message,
 DBusMessage * wpas_dbus_getter_ap_scan(DBusMessage *message,
                                       struct wpa_supplicant *wpa_s)
 {
-       DBusMessage *reply = NULL;
-       DBusMessageIter iter, variant_iter;
        dbus_uint32_t ap_scan = wpa_s->conf->ap_scan;
-
-       if (message == NULL)
-               reply = dbus_message_new(DBUS_MESSAGE_TYPE_SIGNAL);
-       else
-               reply = dbus_message_new_method_return(message);
-
-       if (reply != NULL) {
-               dbus_message_iter_init_append(reply, &iter);
-               if (!dbus_message_iter_open_container(&iter, DBUS_TYPE_VARIANT,
-                                                     "u", &variant_iter) ||
-                   !dbus_message_iter_append_basic(&variant_iter,
-                                                   DBUS_TYPE_UINT32,
-                                                   &ap_scan) ||
-                   !dbus_message_iter_close_container(&iter, &variant_iter)) {
-                       perror("wpas_dbus_getter_ap_scan[dbus]: out of "
-                              "memory to put scanning state into message.");
-                       dbus_message_unref(reply);
-                       reply = dbus_message_new_error(message,
-                                                      DBUS_ERROR_NO_MEMORY,
-                                                      NULL);
-               }
-       } else {
-               perror("wpas_dbus_getter_ap_scan[dbus]: out of "
-                      "memory to return scanning state.");
-               reply = dbus_message_new_error(message, DBUS_ERROR_NO_MEMORY,
-                                              NULL);
-       }
-
-       return reply;
+       return wpas_dbus_simple_property_getter(message, DBUS_TYPE_UINT32,
+                                               &ap_scan);
 }
 
 
@@ -2123,39 +2073,18 @@ DBusMessage * wpas_dbus_setter_ap_scan(DBusMessage *message,
                                       struct wpa_supplicant *wpa_s)
 {
        DBusMessage *reply = NULL;
-       DBusMessageIter iter, variant_iter;
        dbus_uint32_t ap_scan;
 
-       if (!dbus_message_iter_init(message, &iter)) {
-               perror("wpas_dbus_getter_ap_scan[dbus]: out of "
-                      "memory to return scanning state.");
-               reply = dbus_message_new_error(message, DBUS_ERROR_NO_MEMORY,
-                                              NULL);
-               goto out;
-       }
-
-       /* omit first and second argument and get value from third*/
-       dbus_message_iter_next(&iter);
-       dbus_message_iter_next(&iter);
-       dbus_message_iter_recurse(&iter, &variant_iter);
-
-       if (dbus_message_iter_get_arg_type(&variant_iter) != DBUS_TYPE_UINT32)
-       {
-               reply = wpas_dbus_error_invald_args(message,
-                                                   "UINT32 required");
-               goto out;
-       }
-       dbus_message_iter_get_basic(&variant_iter, &ap_scan);
+       reply = wpas_dbus_simple_property_setter(message, DBUS_TYPE_UINT32,
+                                                &ap_scan);
+       if (reply)
+               return reply;
 
        if (wpa_supplicant_set_ap_scan(wpa_s, ap_scan)) {
-               reply = wpas_dbus_error_invald_args(
-                       message,
-                       "ap_scan must equal 0, 1 or 2");
-               goto out;
+               return wpas_dbus_error_invalid_args(
+                       message, "ap_scan must equal 0, 1 or 2");
        }
-
-out:
-       return reply;
+       return NULL;
 }
 
 
@@ -2171,46 +2100,9 @@ out:
 DBusMessage * wpas_dbus_getter_ifname(DBusMessage *message,
                                      struct wpa_supplicant *wpa_s)
 {
-       DBusMessage *reply = NULL;
-       DBusMessageIter iter, variant_iter;
-       const char *ifname = NULL;
-
-       ifname = wpa_s->ifname;
-       if (ifname == NULL) {
-               wpa_printf(MSG_DEBUG, "wpas_dbus_getter_ifname[dbus]: "
-                          "wpa_s has no interface name set"");");
-               return wpas_dbus_error_unknown_error(message,
-                                                    "ifname not set");
-       }
-
-       if (message == NULL)
-               reply = dbus_message_new(DBUS_MESSAGE_TYPE_SIGNAL);
-       else
-               reply = dbus_message_new_method_return(message);
-
-       if (reply != NULL) {
-               dbus_message_iter_init_append(reply, &iter);
-               if (!dbus_message_iter_open_container(&iter, DBUS_TYPE_VARIANT,
-                                                     "s", &variant_iter) ||
-                   !dbus_message_iter_append_basic(&variant_iter,
-                                                   DBUS_TYPE_STRING,
-                                                   &ifname) ||
-                   !dbus_message_iter_close_container(&iter, &variant_iter)) {
-                       perror("wpas_dbus_getter_ifname[dbus]: out of "
-                              "memory to put ifname into message.");
-                       dbus_message_unref(reply);
-                       reply = dbus_message_new_error(message,
-                                                      DBUS_ERROR_NO_MEMORY,
-                                                      NULL);
-               }
-       } else {
-               perror("wpas_dbus_getter_ifname[dbus]: out of "
-                      "memory to return ifname state.");
-               reply = dbus_message_new_error(message, DBUS_ERROR_NO_MEMORY,
-                                              NULL);
-       }
-
-       return reply;
+       const char *ifname = wpa_s->ifname;
+       return wpas_dbus_simple_property_getter(message, DBUS_TYPE_STRING,
+                                               &ifname);
 }
 
 
@@ -2226,46 +2118,17 @@ DBusMessage * wpas_dbus_getter_ifname(DBusMessage *message,
 DBusMessage * wpas_dbus_getter_driver(DBusMessage *message,
                                      struct wpa_supplicant *wpa_s)
 {
-       DBusMessage *reply = NULL;
-       DBusMessageIter iter, variant_iter;
-       const char *driver = NULL;
+       const char *driver;
 
        if (wpa_s->driver == NULL || wpa_s->driver->name == NULL) {
                wpa_printf(MSG_DEBUG, "wpas_dbus_getter_driver[dbus]: "
-                          "wpa_s has no driver set"");");
+                          "wpa_s has no driver set");
                return wpas_dbus_error_unknown_error(message, NULL);
        }
 
        driver = wpa_s->driver->name;
-
-       if (message == NULL)
-               reply = dbus_message_new(DBUS_MESSAGE_TYPE_SIGNAL);
-       else
-               reply = dbus_message_new_method_return(message);
-
-       if (reply != NULL) {
-               dbus_message_iter_init_append(reply, &iter);
-               if (!dbus_message_iter_open_container(&iter, DBUS_TYPE_VARIANT,
-                                                     "s", &variant_iter) ||
-                   !dbus_message_iter_append_basic(&variant_iter,
-                                                   DBUS_TYPE_STRING,
-                                                   &driver) ||
-                   !dbus_message_iter_close_container(&iter, &variant_iter)) {
-                       perror("wpas_dbus_getter_driver[dbus]: out of "
-                              "memory to put driver into message.");
-                       dbus_message_unref(reply);
-                       reply = dbus_message_new_error(message,
-                                                      DBUS_ERROR_NO_MEMORY,
-                                                      NULL);
-               }
-       } else {
-               perror("wpas_dbus_getter_driver[dbus]: out of "
-                      "memory to return driver.");
-               reply = dbus_message_new_error(message, DBUS_ERROR_NO_MEMORY,
-                                              NULL);
-       }
-
-       return reply;
+       return wpas_dbus_simple_property_getter(message, DBUS_TYPE_STRING,
+                                               &driver);
 }
 
 
@@ -2281,66 +2144,20 @@ DBusMessage * wpas_dbus_getter_driver(DBusMessage *message,
 DBusMessage * wpas_dbus_getter_current_bss(DBusMessage *message,
                                           struct wpa_supplicant *wpa_s)
 {
-       DBusMessage *reply = NULL;
-       DBusMessageIter iter, variant_iter;
-       const char *path = wpas_dbus_get_path(wpa_s);
-       char *bss_obj_path = os_zalloc(WPAS_DBUS_OBJECT_PATH_MAX);
-       int is_bssid_known = 0;
-
-       if (bss_obj_path == NULL) {
-               perror("wpas_dbus_getter_current_bss[dbus]: out of "
-                      "memory to allocate result argument.");
-               return dbus_message_new_error(message, DBUS_ERROR_NO_MEMORY,
-                                             NULL);
-       }
-
-       if (!is_zero_ether_addr(wpa_s->bssid)) {
-               size_t i;
-               for (i = 0; wpa_s->scan_res && i < wpa_s->scan_res->num; i++) {
-                       struct wpa_scan_res *res = wpa_s->scan_res->res[i];
-                       if (!os_memcmp(wpa_s->bssid, res->bssid, ETH_ALEN)) {
-                               is_bssid_known = 1;
-                               break;
-                       }
-               }
-       }
+       DBusMessage *reply;
+       char path_buf[WPAS_DBUS_OBJECT_PATH_MAX], *bss_obj_path = path_buf;
 
-       if (is_bssid_known)
+       if (wpa_s->current_bss)
                os_snprintf(bss_obj_path, WPAS_DBUS_OBJECT_PATH_MAX,
-                           "%s/" WPAS_DBUS_NEW_BSSIDS_PART "/"
-                           WPAS_DBUS_BSSID_FORMAT,
-                           path, MAC2STR(wpa_s->bssid));
+                           "%s/" WPAS_DBUS_NEW_BSSIDS_PART "/%u",
+                           wpa_s->dbus_new_path, wpa_s->current_bss->id);
        else
                os_snprintf(bss_obj_path, WPAS_DBUS_OBJECT_PATH_MAX, "/");
 
-       if (message == NULL)
-               reply = dbus_message_new(DBUS_MESSAGE_TYPE_SIGNAL);
-       else
-               reply = dbus_message_new_method_return(message);
-
-       if (reply != NULL) {
-               dbus_message_iter_init_append(reply, &iter);
-               if (!dbus_message_iter_open_container(&iter, DBUS_TYPE_VARIANT,
-                                                     "o", &variant_iter) ||
-                   !dbus_message_iter_append_basic(&variant_iter,
-                                                   DBUS_TYPE_OBJECT_PATH,
-                                                   &bss_obj_path) ||
-                   !dbus_message_iter_close_container(&iter, &variant_iter)) {
-                       perror("wpas_dbus_getter_current_bss[dbus]: out of "
-                              "memory to put path into message.");
-                       dbus_message_unref(reply);
-                       reply = dbus_message_new_error(message,
-                                                      DBUS_ERROR_NO_MEMORY,
-                                                      NULL);
-               }
-       } else {
-               perror("wpas_dbus_getter_current_bss[dbus]: out of "
-                      "memory when creating reply.");
-               reply = dbus_message_new_error(message, DBUS_ERROR_NO_MEMORY,
-                                              NULL);
-       }
+       reply = wpas_dbus_simple_property_getter(message,
+                                                DBUS_TYPE_OBJECT_PATH,
+                                                &bss_obj_path);
 
-       os_free(bss_obj_path);
        return reply;
 }
 
@@ -2357,53 +2174,20 @@ DBusMessage * wpas_dbus_getter_current_bss(DBusMessage *message,
 DBusMessage * wpas_dbus_getter_current_network(DBusMessage *message,
                                               struct wpa_supplicant *wpa_s)
 {
-       DBusMessage *reply = NULL;
-       DBusMessageIter iter, variant_iter;
-       const char *path = wpas_dbus_get_path(wpa_s);
-       char *net_obj_path = os_zalloc(WPAS_DBUS_OBJECT_PATH_MAX);
-
-       if (net_obj_path == NULL) {
-               perror("wpas_dbus_getter_current_network[dbus]: out of "
-                      "memory to allocate result argument.");
-               return dbus_message_new_error(message, DBUS_ERROR_NO_MEMORY,
-                                             NULL);
-       }
+       DBusMessage *reply;
+       char path_buf[WPAS_DBUS_OBJECT_PATH_MAX], *net_obj_path = path_buf;
 
        if (wpa_s->current_ssid)
                os_snprintf(net_obj_path, WPAS_DBUS_OBJECT_PATH_MAX,
-                           "%s/" WPAS_DBUS_NEW_NETWORKS_PART "/%u", path,
-                           wpa_s->current_ssid->id);
+                           "%s/" WPAS_DBUS_NEW_NETWORKS_PART "/%u",
+                           wpa_s->dbus_new_path, wpa_s->current_ssid->id);
        else
                os_snprintf(net_obj_path, WPAS_DBUS_OBJECT_PATH_MAX, "/");
 
-       if (message == NULL)
-               reply = dbus_message_new(DBUS_MESSAGE_TYPE_SIGNAL);
-       else
-               reply = dbus_message_new_method_return(message);
+       reply = wpas_dbus_simple_property_getter(message,
+                                                DBUS_TYPE_OBJECT_PATH,
+                                                &net_obj_path);
 
-       if (reply != NULL) {
-               dbus_message_iter_init_append(reply, &iter);
-               if (!dbus_message_iter_open_container(&iter, DBUS_TYPE_VARIANT,
-                                                     "o", &variant_iter) ||
-                   !dbus_message_iter_append_basic(&variant_iter,
-                                                   DBUS_TYPE_OBJECT_PATH,
-                                                   &net_obj_path) ||
-                   !dbus_message_iter_close_container(&iter, &variant_iter)) {
-                       perror("wpas_dbus_getter_current_network[dbus]: out "
-                              "of memory to put path into message.");
-                       dbus_message_unref(reply);
-                       reply = dbus_message_new_error(message,
-                                                      DBUS_ERROR_NO_MEMORY,
-                                                      NULL);
-               }
-       } else {
-               perror("wpas_dbus_getter_current_network[dbus]: out of "
-                      "memory when creating reply.");
-               reply = dbus_message_new_error(message, DBUS_ERROR_NO_MEMORY,
-                                              NULL);
-       }
-
-       os_free(net_obj_path);
        return reply;
 }
 
@@ -2420,45 +2204,17 @@ DBusMessage * wpas_dbus_getter_current_network(DBusMessage *message,
 DBusMessage * wpas_dbus_getter_bridge_ifname(DBusMessage *message,
                                             struct wpa_supplicant *wpa_s)
 {
-       DBusMessage *reply = NULL;
-       DBusMessageIter iter, variant_iter;
        const char *bridge_ifname = NULL;
 
        bridge_ifname = wpa_s->bridge_ifname;
        if (bridge_ifname == NULL) {
                wpa_printf(MSG_ERROR, "wpas_dbus_getter_bridge_ifname[dbus]: "
-                          "wpa_s has no bridge interface name set"");");
+                          "wpa_s has no bridge interface name set");
                return wpas_dbus_error_unknown_error(message, NULL);
        }
 
-       if (message == NULL)
-               reply = dbus_message_new(DBUS_MESSAGE_TYPE_SIGNAL);
-       else
-               reply = dbus_message_new_method_return(message);
-
-       if (reply != NULL) {
-               dbus_message_iter_init_append(reply, &iter);
-               if (!dbus_message_iter_open_container(&iter, DBUS_TYPE_VARIANT,
-                                                     "s", &variant_iter) ||
-                   !dbus_message_iter_append_basic(&variant_iter,
-                                                   DBUS_TYPE_STRING,
-                                                   &bridge_ifname) ||
-                   !dbus_message_iter_close_container(&iter, &variant_iter)) {
-                       perror("wpas_dbus_getter_bridge_ifname[dbus]: out of "
-                              "memory to put bridge ifname into message.");
-                       dbus_message_unref(reply);
-                       reply = dbus_message_new_error(message,
-                                                      DBUS_ERROR_NO_MEMORY,
-                                                      NULL);
-               }
-       } else {
-               perror("wpas_dbus_getter_bridge_ifname[dbus]: out of "
-                      "memory to return bridge ifname.");
-               reply = dbus_message_new_error(message, DBUS_ERROR_NO_MEMORY,
-                                              NULL);
-       }
-
-       return reply;
+       return wpas_dbus_simple_property_getter(message, DBUS_TYPE_STRING,
+                                               &bridge_ifname);
 }
 
 
@@ -2475,84 +2231,39 @@ DBusMessage * wpas_dbus_getter_bsss(DBusMessage *message,
                                    struct wpa_supplicant *wpa_s)
 {
        DBusMessage *reply = NULL;
-       DBusMessageIter iter, variant_iter, array_iter;
-       size_t i;
-
-       /* Ensure we've actually got scan results to return */
-       if (wpa_s->scan_res == NULL &&
-           wpa_supplicant_get_scan_results(wpa_s) < 0) {
-               wpa_printf(MSG_ERROR, "wpas_dbus_getter_bsss[dbus]: "
-                          "An error occurred getting scan results.");
-               return wpas_dbus_error_unknown_error(message, NULL);
-       }
-
-       /* Create and initialize the return message */
-       if (message == NULL)
-               reply = dbus_message_new(DBUS_MESSAGE_TYPE_SIGNAL);
-       else
-               reply = dbus_message_new_method_return(message);
-       if (reply == NULL) {
-               perror("wpas_dbus_getter_bsss[dbus]: out of "
-                      "memory to create return message.");
-               reply = dbus_message_new_error(message, DBUS_ERROR_NO_MEMORY,
-                                              NULL);
-               goto out;
-       }
-
-       dbus_message_iter_init_append(reply, &iter);
+       struct wpa_bss *bss;
+       char **paths;
+       unsigned int i = 0;
 
-       if (!dbus_message_iter_open_container(&iter, DBUS_TYPE_VARIANT,
-                                             "ao", &variant_iter) ||
-           !dbus_message_iter_open_container(&variant_iter, DBUS_TYPE_ARRAY,
-                                             DBUS_TYPE_OBJECT_PATH_AS_STRING,
-                                             &array_iter)) {
-               perror("wpas_dbus_getter_bsss[dbus]: out of "
-                      "memory to open container.");
-               dbus_message_unref(reply);
-               reply = dbus_message_new_error(message, DBUS_ERROR_NO_MEMORY,
-                                              NULL);
-               goto out;
+       paths = os_zalloc(wpa_s->num_bss * sizeof(char *));
+       if (!paths) {
+               return dbus_message_new_error(message, DBUS_ERROR_NO_MEMORY,
+                                             NULL);
        }
 
        /* Loop through scan results and append each result's object path */
-       for (i = 0; i < wpa_s->scan_res->num; i++) {
-               struct wpa_scan_res *res = wpa_s->scan_res->res[i];
-               char *path;
-
-               path = os_zalloc(WPAS_DBUS_OBJECT_PATH_MAX);
-               if (path == NULL) {
-                       perror("wpas_dbus_getter_bsss[dbus]: out of "
-                              "memory.");
-                       dbus_message_unref(reply);
+       dl_list_for_each(bss, &wpa_s->bss_id, struct wpa_bss, list_id) {
+               paths[i] = os_zalloc(WPAS_DBUS_OBJECT_PATH_MAX);
+               if (paths[i] == NULL) {
                        reply = dbus_message_new_error(message,
                                                       DBUS_ERROR_NO_MEMORY,
                                                       NULL);
                        goto out;
                }
-               /* Construct the object path for this BSS. Note that ':'
-                * is not a valid character in dbus object paths.
-                */
-               os_snprintf(path, WPAS_DBUS_OBJECT_PATH_MAX,
-                           "%s/" WPAS_DBUS_NEW_BSSIDS_PART "/"
-                           WPAS_DBUS_BSSID_FORMAT,
-                           wpas_dbus_get_path(wpa_s),
-                           MAC2STR(res->bssid));
-               dbus_message_iter_append_basic(&array_iter,
-                                              DBUS_TYPE_OBJECT_PATH, &path);
-               os_free(path);
+               /* Construct the object path for this BSS. */
+               os_snprintf(paths[i++], WPAS_DBUS_OBJECT_PATH_MAX,
+                           "%s/" WPAS_DBUS_NEW_BSSIDS_PART "/%u",
+                           wpa_s->dbus_new_path, bss->id);
        }
 
-       if (!dbus_message_iter_close_container(&variant_iter, &array_iter) ||
-           !dbus_message_iter_close_container(&iter, &variant_iter)) {
-               perror("wpas_dbus_getter_bsss[dbus]: out of "
-                      "memory to close container.");
-               dbus_message_unref(reply);
-               reply = dbus_message_new_error(message, DBUS_ERROR_NO_MEMORY,
-                                              NULL);
-               goto out;
-       }
+       reply = wpas_dbus_simple_array_property_getter(message,
+                                                      DBUS_TYPE_OBJECT_PATH,
+                                                      paths, wpa_s->num_bss);
 
 out:
+       while (i)
+               os_free(paths[--i]);
+       os_free(paths);
        return reply;
 }
 
@@ -2570,8 +2281,9 @@ DBusMessage * wpas_dbus_getter_networks(DBusMessage *message,
                                        struct wpa_supplicant *wpa_s)
 {
        DBusMessage *reply = NULL;
-       DBusMessageIter iter, variant_iter, array_iter;
        struct wpa_ssid *ssid;
+       char **paths;
+       unsigned int i = 0, num = 0;
 
        if (wpa_s->conf == NULL) {
                wpa_printf(MSG_ERROR, "wpas_dbus_getter_networks[dbus]: "
@@ -2579,43 +2291,19 @@ DBusMessage * wpas_dbus_getter_networks(DBusMessage *message,
                return wpas_dbus_error_unknown_error(message, NULL);
        }
 
-       /* Create and initialize the return message */
-       if (message == NULL)
-               reply = dbus_message_new(DBUS_MESSAGE_TYPE_SIGNAL);
-       else
-               reply = dbus_message_new_method_return(message);
-       if (reply == NULL) {
-               perror("wpas_dbus_getter_networks[dbus]: out of "
-                      "memory to create return message.");
-               reply = dbus_message_new_error(message, DBUS_ERROR_NO_MEMORY,
-                                              NULL);
-               goto out;
-       }
+       for (ssid = wpa_s->conf->ssid; ssid; ssid = ssid->next)
+               num++;
 
-       dbus_message_iter_init_append(reply, &iter);
-
-       if (!dbus_message_iter_open_container(&iter, DBUS_TYPE_VARIANT,
-                                             "ao", &variant_iter) ||
-           !dbus_message_iter_open_container(&variant_iter, DBUS_TYPE_ARRAY,
-                                             DBUS_TYPE_OBJECT_PATH_AS_STRING,
-                                             &array_iter)) {
-               perror("wpas_dbus_getter_networks[dbus]: out of "
-                      "memory to open container.");
-               dbus_message_unref(reply);
-               reply = dbus_message_new_error(message, DBUS_ERROR_NO_MEMORY,
-                                              NULL);
-               goto out;
+       paths = os_zalloc(num * sizeof(char *));
+       if (!paths) {
+               return dbus_message_new_error(message, DBUS_ERROR_NO_MEMORY,
+                                             NULL);
        }
 
-       /* Loop through configured networks and append object path if each */
+       /* Loop through configured networks and append object path of each */
        for (ssid = wpa_s->conf->ssid; ssid; ssid = ssid->next) {
-               char *path;
-
-               path = os_zalloc(WPAS_DBUS_OBJECT_PATH_MAX);
-               if (path == NULL) {
-                       perror("wpas_dbus_getter_networks[dbus]: out of "
-                              "memory.");
-                       dbus_message_unref(reply);
+               paths[i] = os_zalloc(WPAS_DBUS_OBJECT_PATH_MAX);
+               if (paths[i] == NULL) {
                        reply = dbus_message_new_error(message,
                                                       DBUS_ERROR_NO_MEMORY,
                                                       NULL);
@@ -2623,25 +2311,19 @@ DBusMessage * wpas_dbus_getter_networks(DBusMessage *message,
                }
 
                /* Construct the object path for this network. */
-               os_snprintf(path, WPAS_DBUS_OBJECT_PATH_MAX,
+               os_snprintf(paths[i++], WPAS_DBUS_OBJECT_PATH_MAX,
                            "%s/" WPAS_DBUS_NEW_NETWORKS_PART "/%d",
-                           wpas_dbus_get_path(wpa_s), ssid->id);
-               dbus_message_iter_append_basic(&array_iter,
-                                              DBUS_TYPE_OBJECT_PATH, &path);
-               os_free(path);
+                           wpa_s->dbus_new_path, ssid->id);
        }
 
-       if (!dbus_message_iter_close_container(&variant_iter, &array_iter) ||
-           !dbus_message_iter_close_container(&iter, &variant_iter)) {
-               perror("wpas_dbus_getter_networks[dbus]: out of "
-                      "memory to close container.");
-               dbus_message_unref(reply);
-               reply = dbus_message_new_error(message, DBUS_ERROR_NO_MEMORY,
-                                              NULL);
-               goto out;
-       }
+       reply = wpas_dbus_simple_array_property_getter(message,
+                                                      DBUS_TYPE_OBJECT_PATH,
+                                                      paths, num);
 
 out:
+       while (i)
+               os_free(paths[--i]);
+       os_free(paths);
        return reply;
 }
 
@@ -2665,306 +2347,487 @@ DBusMessage * wpas_dbus_getter_blobs(DBusMessage *message,
                reply = dbus_message_new(DBUS_MESSAGE_TYPE_SIGNAL);
        else
                reply = dbus_message_new_method_return(message);
-       if (!reply) {
-               perror("wpas_dbus_getter_blobs[dbus] out of memory when "
-                      "trying to initialize return message");
-               reply = dbus_message_new_error(message, DBUS_ERROR_NO_MEMORY,
-                                              NULL);
-               goto out;
-       }
+       if (!reply)
+               return dbus_message_new_error(message, DBUS_ERROR_NO_MEMORY,
+                                             NULL);
 
        dbus_message_iter_init_append(reply, &iter);
 
        if (!dbus_message_iter_open_container(&iter, DBUS_TYPE_VARIANT,
-                                             "a{say}", &variant_iter)) {
-               dbus_message_unref(reply);
-               perror("wpas_dbus_getter_blobs[dbus] out of memory when "
-                      "trying to open variant");
-               reply = dbus_message_new_error(message, DBUS_ERROR_NO_MEMORY,
-                                              NULL);
-               goto out;
-       }
-
-       if (!dbus_message_iter_open_container(&variant_iter, DBUS_TYPE_ARRAY,
+                                             "a{say}", &variant_iter) ||
+           !dbus_message_iter_open_container(&variant_iter, DBUS_TYPE_ARRAY,
                                              "{say}", &dict_iter)) {
                dbus_message_unref(reply);
-               perror("wpas_dbus_getter_blobs[dbus] out of memory when "
-                      "trying to open dictionary");
-               reply = dbus_message_new_error(message, DBUS_ERROR_NO_MEMORY,
-                                              NULL);
-               goto out;
+               return dbus_message_new_error(message, DBUS_ERROR_NO_MEMORY,
+                                             NULL);
        }
 
        blob = wpa_s->conf->blobs;
        while (blob) {
                if (!dbus_message_iter_open_container(&dict_iter,
                                                      DBUS_TYPE_DICT_ENTRY,
-                                                     NULL, &entry_iter)) {
-                       dbus_message_unref(reply);
-                       perror("wpas_dbus_getter_blobs[dbus] out of memory "
-                              "when trying to open entry");
-                       reply = dbus_message_new_error(message,
-                                                      DBUS_ERROR_NO_MEMORY,
-                                                      NULL);
-                       goto out;
-               }
-
-               if (!dbus_message_iter_append_basic(&entry_iter,
+                                                     NULL, &entry_iter) ||
+                   !dbus_message_iter_append_basic(&entry_iter,
                                                    DBUS_TYPE_STRING,
-                                                   &(blob->name))) {
-                       dbus_message_unref(reply);
-                       perror("wpas_dbus_getter_blobs[dbus] out of memory "
-                              "when trying to append blob name");
-                       reply = dbus_message_new_error(message,
-                                                      DBUS_ERROR_NO_MEMORY,
-                                                      NULL);
-                       goto out;
-               }
-
-               if (!dbus_message_iter_open_container(&entry_iter,
+                                                   &(blob->name)) ||
+                   !dbus_message_iter_open_container(&entry_iter,
                                                      DBUS_TYPE_ARRAY,
                                                      DBUS_TYPE_BYTE_AS_STRING,
-                                                     &array_iter)) {
-                       dbus_message_unref(reply);
-                       perror("wpas_dbus_getter_blobs[dbus] out of memory "
-                              "when trying to open array");
-                       reply = dbus_message_new_error(message,
-                                                      DBUS_ERROR_NO_MEMORY,
-                                                      NULL);
-                       goto out;
-               }
-
-               if (!dbus_message_iter_append_fixed_array(&array_iter,
+                                                     &array_iter) ||
+                   !dbus_message_iter_append_fixed_array(&array_iter,
                                                          DBUS_TYPE_BYTE,
                                                          &(blob->data),
-                                                         blob->len)) {
-                       dbus_message_unref(reply);
-                       perror("wpas_dbus_getter_blobs[dbus] out of memory "
-                              "when trying to append blob data");
-                       reply = dbus_message_new_error(message,
-                                                      DBUS_ERROR_NO_MEMORY,
-                                                      NULL);
-                       goto out;
-               }
-
-               if (!dbus_message_iter_close_container(&entry_iter,
-                                                      &array_iter)) {
-                       dbus_message_unref(reply);
-                       perror("wpas_dbus_getter_blobs[dbus] out of memory "
-                              "when trying to close array");
-                       reply = dbus_message_new_error(message,
-                                                      DBUS_ERROR_NO_MEMORY,
-                                                      NULL);
-                       goto out;
-               }
-
-               if (!dbus_message_iter_close_container(&dict_iter,
+                                                         blob->len) ||
+                   !dbus_message_iter_close_container(&entry_iter,
+                                                      &array_iter) ||
+                   !dbus_message_iter_close_container(&dict_iter,
                                                       &entry_iter)) {
                        dbus_message_unref(reply);
-                       perror("wpas_dbus_getter_blobs[dbus] out of memory "
-                              "when trying to close entry");
-                       reply = dbus_message_new_error(message,
-                                                      DBUS_ERROR_NO_MEMORY,
-                                                      NULL);
-                       goto out;
+                       return dbus_message_new_error(message,
+                                                     DBUS_ERROR_NO_MEMORY,
+                                                     NULL);
                }
 
                blob = blob->next;
        }
 
-       if (!dbus_message_iter_close_container(&variant_iter, &dict_iter)) {
+       if (!dbus_message_iter_close_container(&variant_iter, &dict_iter) ||
+           !dbus_message_iter_close_container(&iter, &variant_iter)) {
                dbus_message_unref(reply);
-               perror("wpas_dbus_getter_blobs[dbus] out of memory when "
-                      "trying to close dictionary");
-               reply = dbus_message_new_error(message, DBUS_ERROR_NO_MEMORY,
-                                              NULL);
-               goto out;
+               return dbus_message_new_error(message, DBUS_ERROR_NO_MEMORY,
+                                             NULL);
        }
 
-       if (!dbus_message_iter_close_container(&iter, &variant_iter)) {
-               dbus_message_unref(reply);
-               perror("wpas_dbus_getter_blobs[dbus] out of memory when "
-                      "trying to close variant");
-               reply = dbus_message_new_error(message, DBUS_ERROR_NO_MEMORY,
-                                              NULL);
-               goto out;
+       return reply;
+}
+
+
+/**
+ * wpas_dbus_getter_bss_bssid - Return the BSSID of a BSS
+ * @message: Pointer to incoming dbus message
+ * @bss: a pair of interface describing structure and bss's id
+ * Returns: a dbus message containing the bssid for the requested bss
+ *
+ * Getter for "BSSID" property.
+ */
+DBusMessage * wpas_dbus_getter_bss_bssid(DBusMessage *message,
+                                        struct bss_handler_args *bss)
+{
+       struct wpa_bss *res = wpa_bss_get_id(bss->wpa_s, bss->id);
+
+       if (!res) {
+               wpa_printf(MSG_ERROR, "wpas_dbus_getter_bss_bssid[dbus]: no "
+                          "bss with id %d found", bss->id);
+               return NULL;
        }
 
-out:
-       return reply;
+       return wpas_dbus_simple_array_property_getter(message, DBUS_TYPE_BYTE,
+                                                     res->bssid, ETH_ALEN);
 }
 
 
 /**
- * wpas_dbus_getter_bss_properties - Return the properties of a scanned bss
+ * wpas_dbus_getter_bss_ssid - Return the SSID of a BSS
  * @message: Pointer to incoming dbus message
- * @bss: a pair of interface describing structure and bss' bssid
- * Returns: a dbus message containing the properties for the requested bss
+ * @bss: a pair of interface describing structure and bss'id
+ * Returns: a dbus message containing the ssid for the requested bss
  *
- * Getter for "Properties" property.
+ * Getter for "SSID" property.
  */
-DBusMessage * wpas_dbus_getter_bss_properties(DBusMessage *message,
+DBusMessage * wpas_dbus_getter_bss_ssid(DBusMessage *message,
                                              struct bss_handler_args *bss)
 {
-       DBusMessage *reply = NULL;
-       DBusMessageIter iter, iter_dict, variant_iter;
-       const u8 *ie;
-       struct wpa_scan_res *res = find_scan_result(bss);
+       struct wpa_bss *res = wpa_bss_get_id(bss->wpa_s, bss->id);
+
+       if (!res) {
+               wpa_printf(MSG_ERROR, "wpas_dbus_getter_bss_ssid[dbus]: no "
+                          "bss with id %d found", bss->id);
+               return NULL;
+       }
+
+       return wpas_dbus_simple_array_property_getter(message, DBUS_TYPE_BYTE,
+                                                     res->ssid,
+                                                     res->ssid_len);
+}
+
+
+/**
+ * wpas_dbus_getter_bss_privacy - Return the privacy flag of a BSS
+ * @message: Pointer to incoming dbus message
+ * @bss: a pair of interface describing structure and bss's id
+ * Returns: a dbus message containing the privacy flag value of requested bss
+ *
+ * Getter for "Privacy" property.
+ */
+DBusMessage * wpas_dbus_getter_bss_privacy(DBusMessage *message,
+                                          struct bss_handler_args *bss)
+{
+       struct wpa_bss *res = wpa_bss_get_id(bss->wpa_s, bss->id);
+       dbus_bool_t privacy;
 
-       if (res == NULL)
+       if (!res) {
+               wpa_printf(MSG_ERROR, "wpas_dbus_getter_bss_privacy[dbus]: no "
+                          "bss with id %d found", bss->id);
                return NULL;
+       }
+
+       privacy = (res->caps & IEEE80211_CAP_PRIVACY) ? TRUE : FALSE;
+       return wpas_dbus_simple_property_getter(message, DBUS_TYPE_BOOLEAN,
+                                               &privacy);
+}
+
+
+/**
+ * wpas_dbus_getter_bss_mode - Return the mode of a BSS
+ * @message: Pointer to incoming dbus message
+ * @bss: a pair of interface describing structure and bss's id
+ * Returns: a dbus message containing the mode of requested bss
+ *
+ * Getter for "Mode" property.
+ */
+DBusMessage * wpas_dbus_getter_bss_mode(DBusMessage *message,
+                                       struct bss_handler_args *bss)
+{
+       struct wpa_bss *res = wpa_bss_get_id(bss->wpa_s, bss->id);
+       const char *mode;
+
+       if (!res) {
+               wpa_printf(MSG_ERROR, "wpas_dbus_getter_bss_mode[dbus]: no "
+                          "bss with id %d found", bss->id);
+               return NULL;
+       }
+
+       if (res->caps & IEEE80211_CAP_IBSS)
+               mode = "ad-hoc";
+       else
+               mode = "infrastructure";
+
+       return wpas_dbus_simple_property_getter(message, DBUS_TYPE_STRING,
+                                               &mode);
+}
+
+
+/**
+ * wpas_dbus_getter_bss_level - Return the signal strength of a BSS
+ * @message: Pointer to incoming dbus message
+ * @bss: a pair of interface describing structure and bss's id
+ * Returns: a dbus message containing the signal strength of requested bss
+ *
+ * Getter for "Level" property.
+ */
+DBusMessage * wpas_dbus_getter_bss_signal(DBusMessage *message,
+                                         struct bss_handler_args *bss)
+{
+       struct wpa_bss *res = wpa_bss_get_id(bss->wpa_s, bss->id);
+
+       if (!res) {
+               wpa_printf(MSG_ERROR, "wpas_dbus_getter_bss_signal[dbus]: no "
+                          "bss with id %d found", bss->id);
+               return NULL;
+       }
+
+       return wpas_dbus_simple_property_getter(message, DBUS_TYPE_INT16,
+                                               &res->level);
+}
+
+
+/**
+ * wpas_dbus_getter_bss_frequency - Return the frequency of a BSS
+ * @message: Pointer to incoming dbus message
+ * @bss: a pair of interface describing structure and bss's id
+ * Returns: a dbus message containing the frequency of requested bss
+ *
+ * Getter for "Frequency" property.
+ */
+DBusMessage * wpas_dbus_getter_bss_frequency(DBusMessage *message,
+                                            struct bss_handler_args *bss)
+{
+       struct wpa_bss *res = wpa_bss_get_id(bss->wpa_s, bss->id);
+
+       if (!res) {
+               wpa_printf(MSG_ERROR, "wpas_dbus_getter_bss_frequency[dbus]: "
+                          "no bss with id %d found", bss->id);
+               return NULL;
+       }
+
+       return wpas_dbus_simple_property_getter(message, DBUS_TYPE_UINT16,
+                                               &res->freq);
+}
+
+
+static int cmp_u8s_desc(const void *a, const void *b)
+{
+       return (*(u8 *) b - *(u8 *) a);
+}
+
+
+/**
+ * wpas_dbus_getter_bss_rates - Return available bit rates of a BSS
+ * @message: Pointer to incoming dbus message
+ * @bss: a pair of interface describing structure and bss's id
+ * Returns: a dbus message containing sorted array of bit rates
+ *
+ * Getter for "Rates" property.
+ */
+DBusMessage * wpas_dbus_getter_bss_rates(DBusMessage *message,
+                                           struct bss_handler_args *bss)
+{
+       DBusMessage *reply;
+       struct wpa_bss *res = wpa_bss_get_id(bss->wpa_s, bss->id);
+       u8 *ie_rates = NULL;
+       u32 *real_rates;
+       int rates_num, i;
+
+       if (!res) {
+               wpa_printf(MSG_ERROR, "wpas_dbus_getter_bss_rates[dbus]: "
+                          "no bss with id %d found", bss->id);
+               return NULL;
+       }
+
+       rates_num = wpa_bss_get_bit_rates(res, &ie_rates);
+       if (rates_num < 0)
+               return NULL;
+
+       qsort(ie_rates, rates_num, 1, cmp_u8s_desc);
+
+       real_rates = os_malloc(sizeof(u32) * rates_num);
+       if (!real_rates) {
+               os_free(ie_rates);
+               return dbus_message_new_error(message, DBUS_ERROR_NO_MEMORY,
+                                             NULL);
+       }
+
+       for (i = 0; i < rates_num; i++)
+               real_rates[i] = ie_rates[i] * 500000;
+
+       reply = wpas_dbus_simple_array_property_getter(message,
+                                                      DBUS_TYPE_UINT32,
+                                                      real_rates, rates_num);
+
+       os_free(ie_rates);
+       os_free(real_rates);
+       return reply;
+}
+
+
+static DBusMessage * wpas_dbus_get_bss_security_prop(
+       DBusMessage *message, struct wpa_ie_data *ie_data)
+{
+       DBusMessage *reply;
+       DBusMessageIter iter, iter_dict, variant_iter;
+       const char *group;
+       const char *pairwise[2]; /* max 2 pairwise ciphers is supported */
+       const char *key_mgmt[7]; /* max 7 key managements may be supported */
+       int n;
 
-       /* Dump the properties into a dbus message */
        if (message == NULL)
                reply = dbus_message_new(DBUS_MESSAGE_TYPE_SIGNAL);
        else
                reply = dbus_message_new_method_return(message);
-
        if (!reply)
-               goto error;
+               goto nomem;
 
        dbus_message_iter_init_append(reply, &iter);
-
        if (!dbus_message_iter_open_container(&iter, DBUS_TYPE_VARIANT,
                                              "a{sv}", &variant_iter))
-               goto error;
+               goto nomem;
 
        if (!wpa_dbus_dict_open_write(&variant_iter, &iter_dict))
-               goto error;
+               goto nomem;
 
-       if (!wpa_dbus_dict_append_byte_array(&iter_dict, "BSSID",
-                                            (const char *) res->bssid,
-                                            ETH_ALEN))
-               goto error;
+       /* KeyMgmt */
+       n = 0;
+       if (ie_data->key_mgmt & WPA_KEY_MGMT_PSK)
+               key_mgmt[n++] = "wpa-psk";
+       if (ie_data->key_mgmt & WPA_KEY_MGMT_FT_PSK)
+               key_mgmt[n++] = "wpa-ft-psk";
+       if (ie_data->key_mgmt & WPA_KEY_MGMT_PSK_SHA256)
+               key_mgmt[n++] = "wpa-psk-sha256";
+       if (ie_data->key_mgmt & WPA_KEY_MGMT_IEEE8021X)
+               key_mgmt[n++] = "wpa-eap";
+       if (ie_data->key_mgmt & WPA_KEY_MGMT_FT_IEEE8021X)
+               key_mgmt[n++] = "wpa-ft-eap";
+       if (ie_data->key_mgmt & WPA_KEY_MGMT_IEEE8021X_SHA256)
+               key_mgmt[n++] = "wpa-eap-sha256";
+       if (ie_data->key_mgmt & WPA_KEY_MGMT_NONE)
+               key_mgmt[n++] = "wpa-none";
+
+       if (!wpa_dbus_dict_append_string_array(&iter_dict, "KeyMgmt",
+                                              key_mgmt, n))
+               goto nomem;
 
-       ie = wpa_scan_get_ie(res, WLAN_EID_SSID);
-       if (ie) {
-               if (!wpa_dbus_dict_append_byte_array(&iter_dict, "SSID",
-                                                    (const char *) (ie + 2),
-                                                    ie[1]))
-               goto error;
+       /* Group */
+       switch (ie_data->group_cipher) {
+       case WPA_CIPHER_WEP40:
+               group = "wep40";
+               break;
+       case WPA_CIPHER_TKIP:
+               group = "tkip";
+               break;
+       case WPA_CIPHER_CCMP:
+               group = "ccmp";
+               break;
+       case WPA_CIPHER_WEP104:
+               group = "wep104";
+               break;
+       default:
+               group = "";
+               break;
        }
 
-       ie = wpa_scan_get_vendor_ie(res, WPA_IE_VENDOR_TYPE);
-       if (ie) {
-               if (!wpa_dbus_dict_append_byte_array(&iter_dict, "WPAIE",
-                                                    (const char *) ie,
-                                                    ie[1] + 2))
-                       goto error;
-       }
+       if (!wpa_dbus_dict_append_string(&iter_dict, "Group", group))
+               goto nomem;
 
-       ie = wpa_scan_get_ie(res, WLAN_EID_RSN);
-       if (ie) {
-               if (!wpa_dbus_dict_append_byte_array(&iter_dict, "RSNIE",
-                                                    (const char *) ie,
-                                                    ie[1] + 2))
-                       goto error;
-       }
+       /* Pairwise */
+       n = 0;
+       if (ie_data->pairwise_cipher & WPA_CIPHER_TKIP)
+               pairwise[n++] = "tkip";
+       if (ie_data->pairwise_cipher & WPA_CIPHER_CCMP)
+               pairwise[n++] = "ccmp";
 
-       ie = wpa_scan_get_vendor_ie(res, WPS_IE_VENDOR_TYPE);
-       if (ie) {
-               if (!wpa_dbus_dict_append_byte_array(&iter_dict, "WPSIE",
-                                                    (const char *) ie,
-                                                    ie[1] + 2))
-                       goto error;
-       }
+       if (!wpa_dbus_dict_append_string_array(&iter_dict, "Pairwise",
+                                              pairwise, n))
+               goto nomem;
 
-       if (res->freq) {
-               if (!wpa_dbus_dict_append_int32(&iter_dict, "Frequency",
-                                               res->freq))
-                       goto error;
+       /* Management group (RSN only) */
+       if (ie_data->proto == WPA_PROTO_RSN) {
+               switch (ie_data->mgmt_group_cipher) {
+#ifdef CONFIG_IEEE80211W
+               case WPA_CIPHER_AES_128_CMAC:
+                       group = "aes128cmac";
+                       break;
+#endif /* CONFIG_IEEE80211W */
+               default:
+                       group = "";
+                       break;
+               }
+
+               if (!wpa_dbus_dict_append_string(&iter_dict, "MgmtGroup",
+                                                group))
+                       goto nomem;
        }
-       if (!wpa_dbus_dict_append_uint16(&iter_dict, "Capabilities",
-                                        res->caps))
-               goto error;
-       if (!(res->flags & WPA_SCAN_QUAL_INVALID) &&
-           !wpa_dbus_dict_append_int32(&iter_dict, "Quality", res->qual))
-               goto error;
-       if (!(res->flags & WPA_SCAN_NOISE_INVALID) &&
-           !wpa_dbus_dict_append_int32(&iter_dict, "Noise", res->noise))
-               goto error;
-       if (!(res->flags & WPA_SCAN_LEVEL_INVALID) &&
-           !wpa_dbus_dict_append_int32(&iter_dict, "Level", res->level))
-               goto error;
-       if (!wpa_dbus_dict_append_int32(&iter_dict, "MaxRate",
-                                       wpa_scan_get_max_rate(res) * 500000))
-               goto error;
 
-       if (!wpa_dbus_dict_close_write(&iter, &iter_dict))
-               goto error;
+       if (!wpa_dbus_dict_close_write(&variant_iter, &iter_dict))
+               goto nomem;
+       if (!dbus_message_iter_close_container(&iter, &variant_iter))
+               goto nomem;
 
        return reply;
 
-error:
+nomem:
        if (reply)
                dbus_message_unref(reply);
+
        return dbus_message_new_error(message, DBUS_ERROR_NO_MEMORY, NULL);
 }
 
 
 /**
- * wpas_dbus_getter_enabled - Check whether network is enabled or disabled
+ * wpas_dbus_getter_bss_wpa - Return the WPA options of a BSS
  * @message: Pointer to incoming dbus message
- * @wpas_dbus_setter_enabled: wpa_supplicant structure for a network interface
- * and wpa_ssid structure for a configured network
- * Returns: DBus message with boolean indicating state of configured network
- * or DBus error on failure
+ * @bss: a pair of interface describing structure and bss's id
+ * Returns: a dbus message containing the WPA options of requested bss
  *
- * Getter for "enabled" property of a configured network.
+ * Getter for "WPA" property.
  */
-DBusMessage * wpas_dbus_getter_enabled(DBusMessage *message,
-                                      struct network_handler_args *net)
+DBusMessage * wpas_dbus_getter_bss_wpa(DBusMessage *message,
+                                      struct bss_handler_args *bss)
 {
-       DBusMessage *reply = NULL;
-       DBusMessageIter iter, variant_iter;
+       struct wpa_bss *res = wpa_bss_get_id(bss->wpa_s, bss->id);
+       struct wpa_ie_data wpa_data;
+       const u8 *ie;
 
-       dbus_bool_t enabled = net->ssid->disabled ? FALSE : TRUE;
+       if (!res) {
+               wpa_printf(MSG_ERROR, "wpas_dbus_getter_bss_wpa[dbus]: no "
+                          "bss with id %d found", bss->id);
+               return NULL;
+       }
 
-       if (message == NULL)
-               reply = dbus_message_new(DBUS_MESSAGE_TYPE_SIGNAL);
-       else
-               reply = dbus_message_new_method_return(message);
-       if (!reply) {
-               perror("wpas_dbus_getter_enabled[dbus] out of memory when "
-                      "trying to initialize return message");
-               reply = dbus_message_new_error(message, DBUS_ERROR_NO_MEMORY,
-                                              NULL);
-               goto out;
+       os_memset(&wpa_data, 0, sizeof(wpa_data));
+       ie = wpa_bss_get_vendor_ie(res, WPA_IE_VENDOR_TYPE);
+       if (ie) {
+               if (wpa_parse_wpa_ie(ie, 2 + ie[1], &wpa_data) < 0)
+                       return wpas_dbus_error_unknown_error(message,
+                                                            "invalid WPA IE");
        }
 
-       dbus_message_iter_init_append(reply, &iter);
+       return wpas_dbus_get_bss_security_prop(message, &wpa_data);
+}
 
-       if (!dbus_message_iter_open_container(&iter, DBUS_TYPE_VARIANT,
-                                             "b", &variant_iter)) {
-               dbus_message_unref(reply);
-               perror("wpas_dbus_getter_enabled[dbus] out of memory when "
-                      "trying to open variant");
-               reply = dbus_message_new_error(message, DBUS_ERROR_NO_MEMORY,
-                                              NULL);
-               goto out;
+
+/**
+ * wpas_dbus_getter_bss_rsn - Return the RSN options of a BSS
+ * @message: Pointer to incoming dbus message
+ * @bss: a pair of interface describing structure and bss's id
+ * Returns: a dbus message containing the RSN options of requested bss
+ *
+ * Getter for "RSN" property.
+ */
+DBusMessage * wpas_dbus_getter_bss_rsn(DBusMessage *message,
+                                      struct bss_handler_args *bss)
+{
+       struct wpa_bss *res = wpa_bss_get_id(bss->wpa_s, bss->id);
+       struct wpa_ie_data wpa_data;
+       const u8 *ie;
+
+       if (!res) {
+               wpa_printf(MSG_ERROR, "wpas_dbus_getter_bss_rsn[dbus]: no "
+                          "bss with id %d found", bss->id);
+               return NULL;
        }
 
-       if (!dbus_message_iter_append_basic(&variant_iter,
-                                           DBUS_TYPE_BOOLEAN, &enabled)) {
-               dbus_message_unref(reply);
-               perror("wpas_dbus_getter_enabled[dbus] out of memory when "
-                      "trying to append value");
-               reply = dbus_message_new_error(message, DBUS_ERROR_NO_MEMORY,
-                                              NULL);
-               goto out;
+       os_memset(&wpa_data, 0, sizeof(wpa_data));
+       ie = wpa_bss_get_ie(res, WLAN_EID_RSN);
+       if (ie) {
+               if (wpa_parse_wpa_ie(ie, 2 + ie[1], &wpa_data) < 0)
+                       return wpas_dbus_error_unknown_error(message,
+                                                            "invalid RSN IE");
        }
 
-       if (!dbus_message_iter_close_container(&iter, &variant_iter)) {
-               dbus_message_unref(reply);
-               perror("wpas_dbus_getter_blobs[dbus] out of memory when "
-                      "trying to close variant");
-               reply = dbus_message_new_error(message, DBUS_ERROR_NO_MEMORY,
-                                              NULL);
-               goto out;
+       return wpas_dbus_get_bss_security_prop(message, &wpa_data);
+}
+
+
+/**
+ * wpas_dbus_getter_bss_ies - Return all IEs of a BSS
+ * @message: Pointer to incoming dbus message
+ * @bss: a pair of interface describing structure and bss's id
+ * Returns: a dbus message containing IEs byte array
+ *
+ * Getter for "IEs" property.
+ */
+DBusMessage * wpas_dbus_getter_bss_ies(DBusMessage *message,
+                                      struct bss_handler_args *bss)
+{
+       struct wpa_bss *res = wpa_bss_get_id(bss->wpa_s, bss->id);
+
+       if (!res) {
+               wpa_printf(MSG_ERROR, "wpas_dbus_getter_bss_ies[dbus]: no "
+                          "bss with id %d found", bss->id);
+               return NULL;
        }
 
-out:
-       return reply;
+       return wpas_dbus_simple_array_property_getter(message, DBUS_TYPE_BYTE,
+                                                     res + 1, res->ie_len);
+}
+
+
+/**
+ * wpas_dbus_getter_enabled - Check whether network is enabled or disabled
+ * @message: Pointer to incoming dbus message
+ * @wpas_dbus_setter_enabled: wpa_supplicant structure for a network interface
+ * and wpa_ssid structure for a configured network
+ * Returns: DBus message with boolean indicating state of configured network
+ * or DBus error on failure
+ *
+ * Getter for "enabled" property of a configured network.
+ */
+DBusMessage * wpas_dbus_getter_enabled(DBusMessage *message,
+                                      struct network_handler_args *net)
+{
+       dbus_bool_t enabled = net->ssid->disabled ? FALSE : TRUE;
+       return wpas_dbus_simple_property_getter(message, DBUS_TYPE_BOOLEAN,
+                                               &enabled);
 }
 
 
@@ -2981,35 +2844,17 @@ DBusMessage * wpas_dbus_setter_enabled(DBusMessage *message,
                                       struct network_handler_args *net)
 {
        DBusMessage *reply = NULL;
-       DBusMessageIter iter, variant_iter;
 
        struct wpa_supplicant *wpa_s;
        struct wpa_ssid *ssid;
 
        dbus_bool_t enable;
 
-       if (!dbus_message_iter_init(message, &iter)) {
-               perror("wpas_dbus_setter_enabled[dbus] out of memory when "
-                      "trying to init iterator");
-               reply = dbus_message_new_error(message, DBUS_ERROR_NO_MEMORY,
-                                              NULL);
-               goto out;
-       }
-
-       dbus_message_iter_next(&iter);
-       dbus_message_iter_next(&iter);
+       reply = wpas_dbus_simple_property_setter(message, DBUS_TYPE_BOOLEAN,
+                                                &enable);
 
-       dbus_message_iter_recurse(&iter, &variant_iter);
-       if (dbus_message_iter_get_arg_type(&variant_iter) !=
-           DBUS_TYPE_BOOLEAN) {
-               perror("wpas_dbus_setter_enabled[dbus] "
-                      "variant content should be boolean");
-               reply = dbus_message_new_error(message,
-                                              DBUS_ERROR_INVALID_ARGS,
-                                              "value should be a boolean");
-               goto out;
-       }
-       dbus_message_iter_get_basic(&variant_iter, &enable);
+       if (reply)
+               return reply;
 
        wpa_s = net->wpa_s;
        ssid = net->ssid;
@@ -3019,8 +2864,7 @@ DBusMessage * wpas_dbus_setter_enabled(DBusMessage *message,
        else
                wpa_supplicant_disable_network(wpa_s, ssid);
 
-out:
-       return reply;
+       return NULL;
 }
 
 
@@ -3040,20 +2884,15 @@ DBusMessage * wpas_dbus_getter_network_properties(
        DBusMessageIter iter, variant_iter, dict_iter;
        char **iterator;
        char **props = wpa_config_get_all(net->ssid, 0);
-       if (!props) {
-               perror("wpas_dbus_getter_network_properties[dbus] couldn't "
-                      "read network properties. out of memory.");
+       if (!props)
                return dbus_message_new_error(message, DBUS_ERROR_NO_MEMORY,
                                              NULL);
-       }
 
        if (message == NULL)
                reply = dbus_message_new(DBUS_MESSAGE_TYPE_SIGNAL);
        else
                reply = dbus_message_new_method_return(message);
        if (!reply) {
-               perror("wpas_dbus_getter_network_properties[dbus] out of "
-                      "memory when trying to initialize return message");
                reply = dbus_message_new_error(message, DBUS_ERROR_NO_MEMORY,
                                               NULL);
                goto out;
@@ -3062,18 +2901,8 @@ DBusMessage * wpas_dbus_getter_network_properties(
        dbus_message_iter_init_append(reply, &iter);
 
        if (!dbus_message_iter_open_container(&iter, DBUS_TYPE_VARIANT,
-                       "a{sv}", &variant_iter)) {
-               perror("wpas_dbus_getter_network_properties[dbus] out of "
-                      "memory when trying to open variant container");
-               dbus_message_unref(reply);
-               reply = dbus_message_new_error(message, DBUS_ERROR_NO_MEMORY,
-                                              NULL);
-               goto out;
-       }
-
-       if (!wpa_dbus_dict_open_write(&variant_iter, &dict_iter)) {
-               perror("wpas_dbus_getter_network_properties[dbus] out of "
-                      "memory when trying to open dict");
+                       "a{sv}", &variant_iter) ||
+           !wpa_dbus_dict_open_write(&variant_iter, &dict_iter)) {
                dbus_message_unref(reply);
                reply = dbus_message_new_error(message, DBUS_ERROR_NO_MEMORY,
                                               NULL);
@@ -3084,8 +2913,6 @@ DBusMessage * wpas_dbus_getter_network_properties(
        while (*iterator) {
                if (!wpa_dbus_dict_append_string(&dict_iter, *iterator,
                                                 *(iterator + 1))) {
-                       perror("wpas_dbus_getter_network_properties[dbus] out "
-                              "of memory when trying to add entry");
                        dbus_message_unref(reply);
                        reply = dbus_message_new_error(message,
                                                       DBUS_ERROR_NO_MEMORY,
@@ -3096,18 +2923,8 @@ DBusMessage * wpas_dbus_getter_network_properties(
        }
 
 
-       if (!wpa_dbus_dict_close_write(&variant_iter, &dict_iter)) {
-               perror("wpas_dbus_getter_network_properties[dbus] out of "
-                      "memory when trying to close dictionary");
-               dbus_message_unref(reply);
-               reply = dbus_message_new_error(message, DBUS_ERROR_NO_MEMORY,
-                                              NULL);
-               goto out;
-       }
-
-       if (!dbus_message_iter_close_container(&iter, &variant_iter)) {
-               perror("wpas_dbus_getter_network_properties[dbus] out of "
-                      "memory when trying to close variant container");
+       if (!wpa_dbus_dict_close_write(&variant_iter, &dict_iter) ||
+           !dbus_message_iter_close_container(&iter, &variant_iter)) {
                dbus_message_unref(reply);
                reply = dbus_message_new_error(message, DBUS_ERROR_NO_MEMORY,
                                               NULL);
@@ -3149,7 +2966,8 @@ DBusMessage * wpas_dbus_setter_network_properties(
 
        dbus_message_iter_recurse(&iter, &variant_iter);
 
-       reply = set_network_properties(message, ssid, &variant_iter);
+       reply = set_network_properties(message, net->wpa_s, ssid,
+                                      &variant_iter);
        if (reply)
                wpa_printf(MSG_DEBUG, "dbus control interface couldn't set "
                           "network properties");