Blob Blame History Raw
From 822596cfa5e37cdad710b9e282c2bcc267c3fe01 Mon Sep 17 00:00:00 2001
From: Dan Williams <dcbw@redhat.com>
Date: Tue, 26 Jul 2011 19:48:01 -0500
Subject: [PATCH] dbus: clean up new D-Bus interface getters/setters

A number of fixes/improvements here:

1) Remove casting of getter/setter function types which allows
us to change the prototypes in the future and not have hard-to-find
runtime segfaults

2) Instead of having the getters create a fake reply message which
then gets its arguments copied into the real reply message, and is
then disposed, just pass message iters around and have them add
their arguments to the message itself

3) For setters, just pass in the message iter positioned at the
start of the argument list, instead of each setter having to skip
over the standard interface+property name

4) Convert error handling to use DBusError and return the error
back down through the call stacks to the function that will
actually send the error back to the caller, instead of having a
fake DBusMessage of type DBUS_MESSAGE_TYPE_ERROR that then
needs to have the error extracted from it.

But most of all, this fixes various segfaults (like rh #725517
and #678625) which were caused by some functions deep down in the
getter callpaths wanting a source DBusMessage* when the getters were
used for two things: signals (which don't have a source DBusMessage)
and methods (which will have a source DBusMessage that's being
replied to).  This duality made the code fragile when handling
errors like invalid IEs over the air.
---
 wpa_supplicant/dbus/dbus_dict_helpers.c     |   14 +-
 wpa_supplicant/dbus/dbus_dict_helpers.h     |    3 +-
 wpa_supplicant/dbus/dbus_new.c              |  127 ++--
 wpa_supplicant/dbus/dbus_new_handlers.c     | 1236 +++++++++++++--------------
 wpa_supplicant/dbus/dbus_new_handlers.h     |  204 +++--
 wpa_supplicant/dbus/dbus_new_handlers_wps.c |   32 +-
 wpa_supplicant/dbus/dbus_new_helpers.c      |  365 +++++----
 wpa_supplicant/dbus/dbus_new_helpers.h      |   17 +-
 wpa_supplicant/dbus/dbus_old_handlers.c     |    8 +-
 9 files changed, 1009 insertions(+), 997 deletions(-)

diff --git a/wpa_supplicant/dbus/dbus_dict_helpers.c b/wpa_supplicant/dbus/dbus_dict_helpers.c
index b3aff40..dbfdcc1 100644
--- a/wpa_supplicant/dbus/dbus_dict_helpers.c
+++ b/wpa_supplicant/dbus/dbus_dict_helpers.c
@@ -593,18 +593,26 @@ dbus_bool_t wpa_dbus_dict_append_string_array(DBusMessageIter *iter_dict,
  * @param iter A valid DBusMessageIter pointing to the start of the dict
  * @param iter_dict (out) A DBusMessageIter to be passed to
  *    wpa_dbus_dict_read_next_entry()
+ * @error on failure a descriptive error
  * @return TRUE on success, FALSE on failure
  *
  */
 dbus_bool_t wpa_dbus_dict_open_read(DBusMessageIter *iter,
-				    DBusMessageIter *iter_dict)
+				    DBusMessageIter *iter_dict,
+				    DBusError *error)
 {
-	if (!iter || !iter_dict)
+	if (!iter || !iter_dict) {
+		dbus_set_error_const(error, DBUS_ERROR_FAILED,
+		                     "[internal] missing message iterators");
 		return FALSE;
+	}
 
 	if (dbus_message_iter_get_arg_type(iter) != DBUS_TYPE_ARRAY ||
-	    dbus_message_iter_get_element_type(iter) != DBUS_TYPE_DICT_ENTRY)
+	    dbus_message_iter_get_element_type(iter) != DBUS_TYPE_DICT_ENTRY) {
+		dbus_set_error_const(error, DBUS_ERROR_INVALID_ARGS,
+		                     "unexpected message argument types");
 		return FALSE;
+	}
 
 	dbus_message_iter_recurse(iter, iter_dict);
 	return TRUE;
diff --git a/wpa_supplicant/dbus/dbus_dict_helpers.h b/wpa_supplicant/dbus/dbus_dict_helpers.h
index eb31575..9d23efa 100644
--- a/wpa_supplicant/dbus/dbus_dict_helpers.h
+++ b/wpa_supplicant/dbus/dbus_dict_helpers.h
@@ -125,7 +125,8 @@ struct wpa_dbus_dict_entry {
 };
 
 dbus_bool_t wpa_dbus_dict_open_read(DBusMessageIter *iter,
-				    DBusMessageIter *iter_dict);
+				    DBusMessageIter *iter_dict,
+				    DBusError *error);
 
 dbus_bool_t wpa_dbus_dict_get_entry(DBusMessageIter *iter_dict,
 				    struct wpa_dbus_dict_entry *entry);
diff --git a/wpa_supplicant/dbus/dbus_new.c b/wpa_supplicant/dbus/dbus_new.c
index c66640a..2da9fef 100644
--- a/wpa_supplicant/dbus/dbus_new.c
+++ b/wpa_supplicant/dbus/dbus_new.c
@@ -42,7 +42,7 @@ static void wpas_dbus_signal_interface(struct wpa_supplicant *wpa_s,
 {
 	struct wpas_dbus_priv *iface;
 	DBusMessage *msg;
-	DBusMessageIter iter, iter_dict;
+	DBusMessageIter iter;
 
 	iface = wpa_s->global->dbus;
 
@@ -61,14 +61,9 @@ static void wpas_dbus_signal_interface(struct wpa_supplicant *wpa_s,
 		goto err;
 
 	if (properties) {
-		if (!wpa_dbus_dict_open_write(&iter, &iter_dict))
-			goto err;
-
-		wpa_dbus_get_object_properties(iface, wpa_s->dbus_new_path,
-					       WPAS_DBUS_NEW_IFACE_INTERFACE,
-					       &iter_dict);
-
-		if (!wpa_dbus_dict_close_write(&iter, &iter_dict))
+		if (!wpa_dbus_get_object_properties(iface, wpa_s->dbus_new_path,
+						    WPAS_DBUS_NEW_IFACE_INTERFACE,
+						    &iter))
 			goto err;
 	}
 
@@ -157,7 +152,7 @@ static void wpas_dbus_signal_bss(struct wpa_supplicant *wpa_s,
 {
 	struct wpas_dbus_priv *iface;
 	DBusMessage *msg;
-	DBusMessageIter iter, iter_dict;
+	DBusMessageIter iter;
 
 	iface = wpa_s->global->dbus;
 
@@ -177,14 +172,9 @@ static void wpas_dbus_signal_bss(struct wpa_supplicant *wpa_s,
 		goto err;
 
 	if (properties) {
-		if (!wpa_dbus_dict_open_write(&iter, &iter_dict))
-			goto err;
-
-		wpa_dbus_get_object_properties(iface, bss_obj_path,
-					       WPAS_DBUS_NEW_IFACE_BSS,
-					       &iter_dict);
-
-		if (!wpa_dbus_dict_close_write(&iter, &iter_dict))
+		if (!wpa_dbus_get_object_properties(iface, bss_obj_path,
+						    WPAS_DBUS_NEW_IFACE_BSS,
+						    &iter))
 			goto err;
 	}
 
@@ -304,7 +294,7 @@ static void wpas_dbus_signal_network(struct wpa_supplicant *wpa_s,
 {
 	struct wpas_dbus_priv *iface;
 	DBusMessage *msg;
-	DBusMessageIter iter, iter_dict;
+	DBusMessageIter iter;
 	char net_obj_path[WPAS_DBUS_OBJECT_PATH_MAX], *path;
 
 	iface = wpa_s->global->dbus;
@@ -330,14 +320,9 @@ static void wpas_dbus_signal_network(struct wpa_supplicant *wpa_s,
 		goto err;
 
 	if (properties) {
-		if (!wpa_dbus_dict_open_write(&iter, &iter_dict))
-			goto err;
-
-		wpa_dbus_get_object_properties(iface, net_obj_path,
-					       WPAS_DBUS_NEW_IFACE_NETWORK,
-					       &iter_dict);
-
-		if (!wpa_dbus_dict_close_write(&iter, &iter_dict))
+		if (!wpa_dbus_get_object_properties(iface, net_obj_path,
+						    WPAS_DBUS_NEW_IFACE_NETWORK,
+						    &iter))
 			goto err;
 	}
 
@@ -655,30 +655,27 @@ void wpas_dbus_signal_prop_changed(struc
 
 	switch (property) {
 	case WPAS_DBUS_PROP_AP_SCAN:
-		getter = (WPADBusPropertyAccessor) wpas_dbus_getter_ap_scan;
+		getter = wpas_dbus_getter_ap_scan;
 		prop = "ApScan";
 		break;
 	case WPAS_DBUS_PROP_SCANNING:
-		getter = (WPADBusPropertyAccessor) wpas_dbus_getter_scanning;
+		getter = wpas_dbus_getter_scanning;
 		prop = "Scanning";
 		break;
 	case WPAS_DBUS_PROP_STATE:
-		getter = (WPADBusPropertyAccessor) wpas_dbus_getter_state;
+		getter = wpas_dbus_getter_state;
 		prop = "State";
 		break;
 	case WPAS_DBUS_PROP_CURRENT_BSS:
-		getter = (WPADBusPropertyAccessor)
-			wpas_dbus_getter_current_bss;
+		getter = wpas_dbus_getter_current_bss;
 		prop = "CurrentBSS";
 		break;
 	case WPAS_DBUS_PROP_CURRENT_NETWORK:
-		getter = (WPADBusPropertyAccessor)
-			wpas_dbus_getter_current_network;
+		getter = wpas_dbus_getter_current_network;
 		prop = "CurrentNetwork";
 		break;
 	case WPAS_DBUS_PROP_BSSS:
-		getter = (WPADBusPropertyAccessor)
-			wpas_dbus_getter_bsss;
+		getter = wpas_dbus_getter_bsss;
 		prop = "BSSs";
 		break;
 	default:
@@ -859,27 +842,27 @@ static const struct wpa_dbus_method_desc wpas_dbus_global_methods[] = {
 
 static const struct wpa_dbus_property_desc wpas_dbus_global_properties[] = {
 	{ "DebugLevel", WPAS_DBUS_NEW_INTERFACE, "s",
-	  (WPADBusPropertyAccessor) wpas_dbus_getter_debug_level,
-	  (WPADBusPropertyAccessor) wpas_dbus_setter_debug_level,
+	  wpas_dbus_getter_debug_level,
+	  wpas_dbus_setter_debug_level,
 	  RW
 	},
 	{ "DebugTimestamp", WPAS_DBUS_NEW_INTERFACE, "b",
-	  (WPADBusPropertyAccessor) wpas_dbus_getter_debug_timestamp,
-	  (WPADBusPropertyAccessor) wpas_dbus_setter_debug_timestamp,
+	  wpas_dbus_getter_debug_timestamp,
+	  wpas_dbus_setter_debug_timestamp,
 	  RW
 	},
 	{ "DebugShowKeys", WPAS_DBUS_NEW_INTERFACE, "b",
-	  (WPADBusPropertyAccessor) wpas_dbus_getter_debug_show_keys,
-	  (WPADBusPropertyAccessor) wpas_dbus_setter_debug_show_keys,
+	  wpas_dbus_getter_debug_show_keys,
+	  wpas_dbus_setter_debug_show_keys,
 	  RW
 	},
 	{ "Interfaces", WPAS_DBUS_NEW_INTERFACE, "ao",
-	  (WPADBusPropertyAccessor) &wpas_dbus_getter_interfaces,
+	  wpas_dbus_getter_interfaces,
 	  NULL,
 	  R
 	},
 	{ "EapMethods", WPAS_DBUS_NEW_INTERFACE, "as",
-	  (WPADBusPropertyAccessor) wpas_dbus_getter_eap_methods,
+	  wpas_dbus_getter_eap_methods,
 	  NULL,
 	  R
 	},
@@ -976,13 +959,13 @@ static void wpa_dbus_free(void *ptr)
 
 static const struct wpa_dbus_property_desc wpas_dbus_network_properties[] = {
 	{ "Properties", WPAS_DBUS_NEW_IFACE_NETWORK, "a{sv}",
-	  (WPADBusPropertyAccessor) wpas_dbus_getter_network_properties,
-	  (WPADBusPropertyAccessor) wpas_dbus_setter_network_properties,
+	  wpas_dbus_getter_network_properties,
+	  wpas_dbus_setter_network_properties,
 	  RW
 	},
 	{ "Enabled", WPAS_DBUS_NEW_IFACE_NETWORK, "b",
-	  (WPADBusPropertyAccessor) wpas_dbus_getter_enabled,
-	  (WPADBusPropertyAccessor) wpas_dbus_setter_enabled,
+	  wpas_dbus_getter_enabled,
+	  wpas_dbus_setter_enabled,
 	  RW
 	},
 	{ NULL, NULL, NULL, NULL, NULL, 0 }
@@ -1104,52 +1087,52 @@ int wpas_dbus_unregister_network(struct wpa_supplicant *wpa_s, int nid)
 
 static const struct wpa_dbus_property_desc wpas_dbus_bss_properties[] = {
 	{ "SSID", WPAS_DBUS_NEW_IFACE_BSS, "ay",
-	  (WPADBusPropertyAccessor) wpas_dbus_getter_bss_ssid,
+	  wpas_dbus_getter_bss_ssid,
 	  NULL,
 	  R
 	},
 	{ "BSSID", WPAS_DBUS_NEW_IFACE_BSS, "ay",
-	  (WPADBusPropertyAccessor) wpas_dbus_getter_bss_bssid,
+	  wpas_dbus_getter_bss_bssid,
 	  NULL,
 	  R
 	},
 	{ "Privacy", WPAS_DBUS_NEW_IFACE_BSS, "b",
-	  (WPADBusPropertyAccessor) wpas_dbus_getter_bss_privacy,
+	  wpas_dbus_getter_bss_privacy,
 	  NULL,
 	  R
 	},
 	{ "Mode", WPAS_DBUS_NEW_IFACE_BSS, "s",
-	  (WPADBusPropertyAccessor) wpas_dbus_getter_bss_mode,
+	  wpas_dbus_getter_bss_mode,
 	  NULL,
 	  R
 	},
 	{ "Signal", WPAS_DBUS_NEW_IFACE_BSS, "n",
-	  (WPADBusPropertyAccessor) wpas_dbus_getter_bss_signal,
+	  wpas_dbus_getter_bss_signal,
 	  NULL,
 	  R
 	},
 	{ "Frequency", WPAS_DBUS_NEW_IFACE_BSS, "q",
-	  (WPADBusPropertyAccessor) wpas_dbus_getter_bss_frequency,
+	  wpas_dbus_getter_bss_frequency,
 	  NULL,
 	  R
 	},
 	{ "Rates", WPAS_DBUS_NEW_IFACE_BSS, "au",
-	  (WPADBusPropertyAccessor) wpas_dbus_getter_bss_rates,
+	  wpas_dbus_getter_bss_rates,
 	  NULL,
 	  R
 	},
 	{ "WPA", WPAS_DBUS_NEW_IFACE_BSS, "a{sv}",
-	  (WPADBusPropertyAccessor) wpas_dbus_getter_bss_wpa,
+	  wpas_dbus_getter_bss_wpa,
 	  NULL,
 	  R
 	},
 	{ "RSN", WPAS_DBUS_NEW_IFACE_BSS, "a{sv}",
-	  (WPADBusPropertyAccessor) wpas_dbus_getter_bss_rsn,
+	  wpas_dbus_getter_bss_rsn,
 	  NULL,
 	  R
 	},
 	{ "IEs", WPAS_DBUS_NEW_IFACE_BSS, "ay",
-	  (WPADBusPropertyAccessor) wpas_dbus_getter_bss_ies,
+	  wpas_dbus_getter_bss_ies,
 	  NULL,
 	  R
 	},
@@ -1352,58 +1335,58 @@ static const struct wpa_dbus_method_desc wpas_dbus_interface_methods[] = {
 
 static const struct wpa_dbus_property_desc wpas_dbus_interface_properties[] = {
 	{ "Capabilities", WPAS_DBUS_NEW_IFACE_INTERFACE, "a{sv}",
-	  (WPADBusPropertyAccessor) wpas_dbus_getter_capabilities,
+	  wpas_dbus_getter_capabilities,
 	  NULL, R
 	},
 	{ "State", WPAS_DBUS_NEW_IFACE_INTERFACE, "s",
-	  (WPADBusPropertyAccessor) wpas_dbus_getter_state,
+	  wpas_dbus_getter_state,
 	  NULL, R
 	},
 	{ "Scanning", WPAS_DBUS_NEW_IFACE_INTERFACE, "b",
-	  (WPADBusPropertyAccessor) wpas_dbus_getter_scanning,
+	  wpas_dbus_getter_scanning,
 	  NULL, R
 	},
 	{ "ApScan", WPAS_DBUS_NEW_IFACE_INTERFACE, "u",
-	  (WPADBusPropertyAccessor) wpas_dbus_getter_ap_scan,
-	  (WPADBusPropertyAccessor) wpas_dbus_setter_ap_scan,
+	  wpas_dbus_getter_ap_scan,
+	  wpas_dbus_setter_ap_scan,
 	  RW
 	},
 	{ "Ifname", WPAS_DBUS_NEW_IFACE_INTERFACE, "s",
-	  (WPADBusPropertyAccessor) wpas_dbus_getter_ifname,
+	  wpas_dbus_getter_ifname,
 	  NULL, R
 	},
 	{ "Driver", WPAS_DBUS_NEW_IFACE_INTERFACE, "s",
-	  (WPADBusPropertyAccessor) wpas_dbus_getter_driver,
+	  wpas_dbus_getter_driver,
 	  NULL, R
 	},
 	{ "BridgeIfname", WPAS_DBUS_NEW_IFACE_INTERFACE, "s",
-	  (WPADBusPropertyAccessor) wpas_dbus_getter_bridge_ifname,
+	  wpas_dbus_getter_bridge_ifname,
 	  NULL, R
 	},
 	{ "CurrentBSS", WPAS_DBUS_NEW_IFACE_INTERFACE, "o",
-	  (WPADBusPropertyAccessor) wpas_dbus_getter_current_bss,
+	  wpas_dbus_getter_current_bss,
 	  NULL, R
 	},
 	{ "CurrentNetwork", WPAS_DBUS_NEW_IFACE_INTERFACE, "o",
-	  (WPADBusPropertyAccessor) wpas_dbus_getter_current_network,
+	  wpas_dbus_getter_current_network,
 	  NULL, R
 	},
 	{ "Blobs", WPAS_DBUS_NEW_IFACE_INTERFACE, "a{say}",
-	  (WPADBusPropertyAccessor) wpas_dbus_getter_blobs,
+	  wpas_dbus_getter_blobs,
 	  NULL, R
 	},
 	{ "BSSs", WPAS_DBUS_NEW_IFACE_INTERFACE, "ao",
-	  (WPADBusPropertyAccessor) wpas_dbus_getter_bsss,
+	  wpas_dbus_getter_bsss,
 	  NULL, R
 	},
 	{ "Networks", WPAS_DBUS_NEW_IFACE_INTERFACE, "ao",
-	  (WPADBusPropertyAccessor) wpas_dbus_getter_networks,
+	  wpas_dbus_getter_networks,
 	  NULL, R
 	},
 #ifdef CONFIG_WPS
 	{ "ProcessCredentials", WPAS_DBUS_NEW_IFACE_WPS, "b",
-	  (WPADBusPropertyAccessor) wpas_dbus_getter_process_credentials,
-	  (WPADBusPropertyAccessor) wpas_dbus_setter_process_credentials,
+	  wpas_dbus_getter_process_credentials,
+	  wpas_dbus_setter_process_credentials,
 	  RW
 	},
 #endif /* CONFIG_WPS */
diff --git a/wpa_supplicant/dbus/dbus_new_handlers.c b/wpa_supplicant/dbus/dbus_new_handlers.c
index e2b5e50..af17a16 100644
--- a/wpa_supplicant/dbus/dbus_new_handlers.c
+++ b/wpa_supplicant/dbus/dbus_new_handlers.c
@@ -213,36 +213,35 @@ 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.
- * Returns: NULL when succeed or DBus error on failure
+ * @error: On failure, an error describing the failure
+ * Returns: TRUE if the request succeeds, FALSE if it failed
  *
  * 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)
+dbus_bool_t set_network_properties(struct wpa_supplicant *wpa_s,
+				   struct wpa_ssid *ssid,
+				   DBusMessageIter *iter,
+				   DBusError *error)
 {
-
 	struct wpa_dbus_dict_entry entry = { .type = DBUS_TYPE_STRING };
-	DBusMessage *reply = NULL;
 	DBusMessageIter	iter_dict;
+	char *value = NULL;
 
-	if (!wpa_dbus_dict_open_read(iter, &iter_dict))
-		return wpas_dbus_error_invalid_args(message, NULL);
+	if (!wpa_dbus_dict_open_read(iter, &iter_dict, error))
+		return FALSE;
 
 	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_invalid_args(message, NULL);
-			break;
-		}
+
+		if (!wpa_dbus_dict_get_entry(&iter_dict, &entry))
+			goto error;
+
+		value = NULL;
 		if (entry.type == DBUS_TYPE_ARRAY &&
 		    entry.array_type == DBUS_TYPE_BYTE) {
 			if (entry.array_len <= 0)
@@ -311,71 +310,59 @@ static DBusMessage * set_network_properties(DBusMessage *message,
 
 		os_free(value);
 		wpa_dbus_dict_entry_clear(&entry);
-		continue;
-
-	error:
-		os_free(value);
-		reply = wpas_dbus_error_invalid_args(message, entry.key);
-		wpa_dbus_dict_entry_clear(&entry);
-		break;
 	}
 
-	return reply;
+	return TRUE;
+
+error:
+	os_free(value);
+	wpa_dbus_dict_entry_clear(&entry);
+	dbus_set_error_const(error, DBUS_ERROR_INVALID_ARGS,
+			     "invalid message format");
+	return FALSE;
 }
 
 
 /**
  * wpas_dbus_simple_property_getter - Get basic type property
- * @message: Pointer to incoming dbus message
+ * @iter: Message iter to use when appending arguments
  * @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.
+ * @error: On failure an error describing the failure
+ * Returns: TRUE if the request was successful, FALSE if it failed
  *
  * 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)
+dbus_bool_t wpas_dbus_simple_property_getter(DBusMessageIter *iter,
+					     const int type,
+					     const void *val,
+					     DBusError *error)
 {
-	DBusMessage *reply = NULL;
-	DBusMessageIter iter, variant_iter;
+	DBusMessageIter 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);
+		dbus_set_error(error, DBUS_ERROR_FAILED,
+		               "%s: given type is not basic", __func__);
+		return 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,
-			    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);
-	}
+	if (!dbus_message_iter_open_container(iter, DBUS_TYPE_VARIANT,
+	                                      wpa_dbus_type_as_string(type),
+	                                      &variant_iter))
+		goto error;
 
-	return reply;
+	if (!dbus_message_iter_append_basic(&variant_iter, type, val))
+		goto error;
+
+	if (!dbus_message_iter_close_container(iter, &variant_iter))
+		goto error;
+
+	return TRUE;
+
+error:
+	dbus_set_error(error, DBUS_ERROR_FAILED,
+	               "%s: error constructing reply", __func__);
+	return FALSE;
 }
 
 
@@ -388,98 +375,75 @@ DBusMessage * wpas_dbus_simple_property_getter(DBusMessage *message,
  *
  * 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)
+dbus_bool_t wpas_dbus_simple_property_setter(DBusMessageIter *iter,
+					     DBusError *error,
+					     const int type, void *val)
 {
-	DBusMessageIter iter, variant_iter;
+	DBusMessageIter 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);
+		dbus_set_error(error, DBUS_ERROR_FAILED,
+			       "%s: given type is not basic", __func__);
+		return FALSE;
 	}
 
-	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);
-
+	/* Look at the new value */
+	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_set_error_const(error, DBUS_ERROR_FAILED,
+				     "wrong property type");
+		return FALSE;
 	}
 	dbus_message_iter_get_basic(&variant_iter, val);
 
-	return NULL;
+	return TRUE;
 }
 
 
 /**
  * wpas_dbus_simple_array_property_getter - Get array type property
- * @message: Pointer to incoming dbus message
+ * @iter: Pointer to incoming dbus message iterator
  * @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.
+ * @error: a pointer to an error to fill on failure
+ * Returns: TRUE if the request succeeded, FALSE if it failed
  *
  * 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)
+dbus_bool_t wpas_dbus_simple_array_property_getter(DBusMessageIter *iter,
+						   const int type,
+						   const void *array,
+						   size_t array_len,
+						   DBusError *error)
 {
-	DBusMessage *reply = NULL;
-	DBusMessageIter iter, variant_iter, array_iter;
+	DBusMessageIter 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);
+		dbus_set_error(error, DBUS_ERROR_FAILED,
+		               "%s: given type is not basic", __func__);
+		return FALSE;
 	}
 
 	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);
+	if (!dbus_message_iter_open_container(iter, DBUS_TYPE_VARIANT,
+					      type_str, &variant_iter)) {
+		dbus_set_error(error, DBUS_ERROR_FAILED,
+		               "%s: failed to construct message 1", __func__);
+		return FALSE;
 	}
 
-	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,
+	if (!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);
+		dbus_set_error(error, DBUS_ERROR_FAILED,
+		               "%s: failed to construct message 2", __func__);
+		return FALSE;
 	}
 
 	switch(type) {
@@ -507,11 +471,9 @@ DBusMessage * wpas_dbus_simple_array_property_getter(DBusMessage *message,
 		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;
+		dbus_set_error(error, DBUS_ERROR_FAILED,
+		               "%s: unknown element type %d", __func__, type);
+		return FALSE;
 	}
 
 	for (i = 0; i < array_len; i++) {
@@ -519,17 +481,19 @@ DBusMessage * wpas_dbus_simple_array_property_getter(DBusMessage *message,
 					       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);
+	if (!dbus_message_iter_close_container(&variant_iter, &array_iter)) {
+		dbus_set_error(error, DBUS_ERROR_FAILED,
+		               "%s: failed to construct message 3", __func__);
+		return FALSE;
 	}
 
-	return reply;
+	if (!dbus_message_iter_close_container(iter, &variant_iter)) {
+		dbus_set_error(error, DBUS_ERROR_FAILED,
+		               "%s: failed to construct message 4", __func__);
+		return FALSE;
+	}
+
+	return TRUE;
 }
 
 
@@ -557,7 +521,7 @@ DBusMessage * wpas_dbus_handler_create_interface(DBusMessage *message,
 
 	dbus_message_iter_init(message, &iter);
 
-	if (!wpa_dbus_dict_open_read(&iter, &iter_dict))
+	if (!wpa_dbus_dict_open_read(&iter, &iter_dict, NULL))
 		goto error;
 	while (wpa_dbus_dict_has_dict_entry(&iter_dict)) {
 		if (!wpa_dbus_dict_get_entry(&iter_dict, &entry))
@@ -706,79 +670,85 @@ DBusMessage * wpas_dbus_handler_get_interface(DBusMessage *message,
 
 /**
  * wpas_dbus_getter_debug_level - Get debug level
- * @message: Pointer to incoming dbus message
- * @global: %wpa_supplicant global data structure
- * Returns: DBus message with value of debug level
+ * @iter: Pointer to incoming dbus message iter
+ * @error: Location to store error on failure
+ * @user_data: Function specific data
+ * Returns: TRUE on success, FALSE on failure
  *
  * Getter for "DebugLevel" property.
  */
-DBusMessage * wpas_dbus_getter_debug_level(DBusMessage *message,
-					   struct wpa_global *global)
+dbus_bool_t wpas_dbus_getter_debug_level(DBusMessageIter *iter,
+					 DBusError *error,
+					 void *user_data)
 {
 	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);
+	return wpas_dbus_simple_property_getter(iter, DBUS_TYPE_STRING,
+						&str, error);
 }
 
 
 /**
  * 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
+ * @iter: Pointer to incoming dbus message iter
+ * @error: Location to store error on failure
+ * @user_data: Function specific data
+ * Returns: TRUE on success, FALSE on failure
  *
  * Getter for "DebugTimestamp" property.
  */
-DBusMessage * wpas_dbus_getter_debug_timestamp(DBusMessage *message,
-					       struct wpa_global *global)
+dbus_bool_t wpas_dbus_getter_debug_timestamp(DBusMessageIter *iter,
+                                             DBusError *error,
+                                             void *user_data)
 {
-	return wpas_dbus_simple_property_getter(message, DBUS_TYPE_BOOLEAN,
-						&wpa_debug_timestamp);
-
+	return wpas_dbus_simple_property_getter(iter, DBUS_TYPE_BOOLEAN,
+						&wpa_debug_timestamp, error);
 }
 
 
 /**
  * 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
+ * @iter: Pointer to incoming dbus message iter
+ * @error: Location to store error on failure
+ * @user_data: Function specific data
+ * Returns: TRUE on success, FALSE on failure
  *
  * Getter for "DebugShowKeys" property.
  */
-DBusMessage * wpas_dbus_getter_debug_show_keys(DBusMessage *message,
-					       struct wpa_global *global)
+dbus_bool_t wpas_dbus_getter_debug_show_keys(DBusMessageIter *iter,
+					     DBusError *error,
+					     void *user_data)
 {
-	return wpas_dbus_simple_property_getter(message, DBUS_TYPE_BOOLEAN,
-						&wpa_debug_show_keys);
+	return wpas_dbus_simple_property_getter(iter, DBUS_TYPE_BOOLEAN,
+						&wpa_debug_show_keys, error);
 
 }
 
 /**
  * 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
+ * @iter: Pointer to incoming dbus message iter
+ * @error: Location to store error on failure
+ * @user_data: Function specific data
+ * Returns: TRUE on success, FALSE on failure
  *
  * Setter for "DebugLevel" property.
  */
-DBusMessage * wpas_dbus_setter_debug_level(DBusMessage *message,
-					   struct wpa_global *global)
+dbus_bool_t wpas_dbus_setter_debug_level(DBusMessageIter *iter,
+					 DBusError *error, void *user_data)
 {
-	DBusMessage *reply;
+	struct wpa_global *global = user_data;
 	const char *str = NULL;
 	int i, val = -1;
 
-	reply = wpas_dbus_simple_property_setter(message, DBUS_TYPE_STRING,
-						 &str);
-	if (reply)
-		return reply;
+	if (!wpas_dbus_simple_property_setter(iter, error, DBUS_TYPE_STRING,
+					      &str))
+		return FALSE;
 
 	for (i = 0; debug_strings[i]; i++)
 		if (os_strcmp(debug_strings[i], str) == 0) {
@@ -789,138 +759,142 @@ DBusMessage * wpas_dbus_setter_debug_level(DBusMessage *message,
 	if (val < 0 ||
 	    wpa_supplicant_set_debug_params(global, val, wpa_debug_timestamp,
 					    wpa_debug_show_keys)) {
-		dbus_message_unref(reply);
-		return wpas_dbus_error_invalid_args(
-			message, "Wrong debug level value");
+		dbus_set_error_const(error, DBUS_ERROR_FAILED, "wrong debug "
+				     "level value");
+		return FALSE;
 	}
 
-	return NULL;
+	return TRUE;
 }
 
 
 /**
  * wpas_dbus_setter_debug_timestamp - Set debug timestamp
- * @message: Pointer to incoming dbus message
- * @global: %wpa_supplicant global data structure
- * Returns: %NULL or DBus error message
+ * @iter: Pointer to incoming dbus message iter
+ * @error: Location to store error on failure
+ * @user_data: Function specific data
+ * Returns: TRUE on success, FALSE on failure
  *
  * Setter for "DebugTimestamp" property.
  */
-DBusMessage * wpas_dbus_setter_debug_timestamp(DBusMessage *message,
-					       struct wpa_global *global)
+dbus_bool_t wpas_dbus_setter_debug_timestamp(DBusMessageIter *iter,
+					     DBusError *error,
+					     void *user_data)
 {
-	DBusMessage *reply;
+	struct wpa_global *global = user_data;
 	dbus_bool_t val;
 
-	reply = wpas_dbus_simple_property_setter(message, DBUS_TYPE_BOOLEAN,
-						 &val);
-	if (reply)
-		return reply;
+	if (!wpas_dbus_simple_property_setter(iter, error, DBUS_TYPE_BOOLEAN,
+					      &val))
+		return FALSE;
 
 	wpa_supplicant_set_debug_params(global, wpa_debug_level, val ? 1 : 0,
 					wpa_debug_show_keys);
 
-	return NULL;
+	return TRUE;
 }
 
 
 /**
  * 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
+ * @iter: Pointer to incoming dbus message iter
+ * @error: Location to store error on failure
+ * @user_data: Function specific data
+ * Returns: TRUE on success, FALSE on failure
  *
  * Setter for "DebugShowKeys" property.
  */
-DBusMessage * wpas_dbus_setter_debug_show_keys(DBusMessage *message,
-					       struct wpa_global *global)
+dbus_bool_t wpas_dbus_setter_debug_show_keys(DBusMessageIter *iter,
+					     DBusError *error,
+					     void *user_data)
 {
-	DBusMessage *reply;
+	struct wpa_global *global = user_data;
 	dbus_bool_t val;
 
-	reply = wpas_dbus_simple_property_setter(message, DBUS_TYPE_BOOLEAN,
-						 &val);
-	if (reply)
-		return reply;
+	if (!wpas_dbus_simple_property_setter(iter, error, DBUS_TYPE_BOOLEAN,
+					      &val))
+		return FALSE;
 
 	wpa_supplicant_set_debug_params(global, wpa_debug_level,
 					wpa_debug_timestamp,
 					val ? 1 : 0);
 
-	return NULL;
+	return TRUE;
 }
 
 
 /**
  * wpas_dbus_getter_interfaces - Request registered interfaces list
- * @message: Pointer to incoming dbus message
- * @global: %wpa_supplicant global data structure
- * Returns: The object paths array containing registered interfaces
- * objects paths or DBus error on failure
+ * @iter: Pointer to incoming dbus message iter
+ * @error: Location to store error on failure
+ * @user_data: Function specific data
+ * Returns: TRUE on success, FALSE on failure
  *
  * Getter for "Interfaces" property. Handles requests
  * by dbus clients to return list of registered interfaces objects
  * paths
  */
-DBusMessage * wpas_dbus_getter_interfaces(DBusMessage *message,
-					  struct wpa_global *global)
+dbus_bool_t wpas_dbus_getter_interfaces(DBusMessageIter *iter, DBusError *error,
+					void *user_data)
 {
-	DBusMessage *reply = NULL;
+	struct wpa_global *global = user_data;
 	struct wpa_supplicant *wpa_s;
 	const char **paths;
 	unsigned int i = 0, num = 0;
+	dbus_bool_t success;
 
 	for (wpa_s = global->ifaces; wpa_s; wpa_s = wpa_s->next)
 		num++;
 
 	paths = os_zalloc(num * sizeof(char*));
 	if (!paths) {
-		return dbus_message_new_error(message, DBUS_ERROR_NO_MEMORY,
-					      NULL);
+		dbus_set_error_const(error, DBUS_ERROR_NO_MEMORY, "no memory");
+		return FALSE;
 	}
 
 	for (wpa_s = global->ifaces; wpa_s; wpa_s = wpa_s->next)
 		paths[i] = wpa_s->dbus_new_path;
 
-	reply = wpas_dbus_simple_array_property_getter(message,
-						       DBUS_TYPE_OBJECT_PATH,
-						       paths, num);
+	success = wpas_dbus_simple_array_property_getter(iter,
+							 DBUS_TYPE_OBJECT_PATH,
+							 paths, num, error);
 
 	os_free(paths);
-	return reply;
+	return success;
 }
 
 
 /**
  * wpas_dbus_getter_eap_methods - Request supported EAP methods list
- * @message: Pointer to incoming dbus message
- * @nothing: not used argument. may be NULL or anything else
- * Returns: The object paths array containing supported EAP methods
- * represented by strings or DBus error on failure
+ * @iter: Pointer to incoming dbus message iter
+ * @error: Location to store error on failure
+ * @user_data: Function specific data
+ * Returns: TRUE on success, FALSE on failure
  *
  * Getter for "EapMethods" property. Handles requests
  * by dbus clients to return list of strings with supported EAP methods
  */
-DBusMessage * wpas_dbus_getter_eap_methods(DBusMessage *message, void *nothing)
+dbus_bool_t wpas_dbus_getter_eap_methods(DBusMessageIter *iter,
+					 DBusError *error, void *user_data)
 {
-	DBusMessage *reply = NULL;
 	char **eap_methods;
 	size_t num_items = 0;
+	dbus_bool_t success;
 
 	eap_methods = eap_get_names_as_string_array(&num_items);
 	if (!eap_methods) {
-		return dbus_message_new_error(message, DBUS_ERROR_NO_MEMORY,
-					      NULL);
+		dbus_set_error_const(error, DBUS_ERROR_NO_MEMORY, "no memory");
+		return FALSE;
 	}
 
-	reply = wpas_dbus_simple_array_property_getter(message,
-						       DBUS_TYPE_STRING,
-						       eap_methods, num_items);
+	success = wpas_dbus_simple_array_property_getter(iter, DBUS_TYPE_STRING,
+							 eap_methods, num_items,
+							 error);
 
 	while (num_items)
 		os_free(eap_methods[--num_items]);
 	os_free(eap_methods);
-	return reply;
+	return success;
 }
 
 
@@ -1326,6 +1300,7 @@ DBusMessage * wpas_dbus_handler_add_network(DBusMessage *message,
 	DBusMessageIter	iter;
 	struct wpa_ssid *ssid = NULL;
 	char path_buf[WPAS_DBUS_OBJECT_PATH_MAX], *path = path_buf;
+	DBusError error;
 
 	dbus_message_iter_init(message, &iter);
 
@@ -1343,11 +1318,15 @@ DBusMessage * wpas_dbus_handler_add_network(DBusMessage *message,
 	ssid->disabled = 1;
 	wpa_config_set_network_defaults(ssid);
 
-	reply = set_network_properties(message, wpa_s, ssid, &iter);
-	if (reply) {
+	dbus_error_init(&error);
+	if (!set_network_properties(wpa_s, ssid, &iter, &error)) {
 		wpa_printf(MSG_DEBUG, "wpas_dbus_handler_add_network[dbus]:"
 			   "control interface couldn't set network "
 			   "properties");
+		reply = wpas_dbus_reply_new_from_error(message, &error,
+						       DBUS_ERROR_INVALID_ARGS,
+						       "Failed to add network");
+		dbus_error_free(&error);
 		goto err;
 	}
 
@@ -1661,34 +1640,26 @@ DBusMessage * wpas_dbus_handler_remove_blob(DBusMessage *message,
 
 /**
  * wpas_dbus_getter_capabilities - Return interface capabilities
- * @message: Pointer to incoming dbus message
- * @wpa_s: wpa_supplicant structure for a network interface
- * Returns: A dbus message containing a dict of strings
+ * @iter: Pointer to incoming dbus message iter
+ * @error: Location to store error on failure
+ * @user_data: Function specific data
+ * Returns: TRUE on success, FALSE on failure
  *
  * Getter for "Capabilities" property of an interface.
  */
-DBusMessage * wpas_dbus_getter_capabilities(DBusMessage *message,
-					    struct wpa_supplicant *wpa_s)
+dbus_bool_t wpas_dbus_getter_capabilities(DBusMessageIter *iter,
+					  DBusError *error, void *user_data)
 {
-	DBusMessage *reply = NULL;
+	struct wpa_supplicant *wpa_s = user_data;
 	struct wpa_driver_capa capa;
 	int res;
-	DBusMessageIter iter, iter_dict;
-	DBusMessageIter iter_dict_entry, iter_dict_val, iter_array,
+	DBusMessageIter iter_dict, iter_dict_entry, iter_dict_val, iter_array,
 		variant_iter;
 	const char *scans[] = { "active", "passive", "ssid" };
 	const char *modes[] = { "infrastructure", "ad-hoc", "ap" };
 	int n = sizeof(modes) / sizeof(char *);
 
-	if (message == NULL)
-		reply = dbus_message_new(DBUS_MESSAGE_TYPE_SIGNAL);
-	else
-		reply = dbus_message_new_method_return(message);
-	if (!reply)
-		goto nomem;
-
-	dbus_message_iter_init_append(reply, &iter);
-	if (!dbus_message_iter_open_container(&iter, DBUS_TYPE_VARIANT,
+	if (!dbus_message_iter_open_container(iter, DBUS_TYPE_VARIANT,
 					      "a{sv}", &variant_iter))
 		goto nomem;
 
@@ -1956,34 +1927,33 @@ DBusMessage * wpas_dbus_getter_capabilities(DBusMessage *message,
 
 	if (!wpa_dbus_dict_close_write(&variant_iter, &iter_dict))
 		goto nomem;
-	if (!dbus_message_iter_close_container(&iter, &variant_iter))
+	if (!dbus_message_iter_close_container(iter, &variant_iter))
 		goto nomem;
 
-	return reply;
+	return TRUE;
 
 nomem:
-	if (reply)
-		dbus_message_unref(reply);
-
-	return dbus_message_new_error(message, DBUS_ERROR_NO_MEMORY, NULL);
+	dbus_set_error_const(error, DBUS_ERROR_NO_MEMORY, "no memory");
+	return FALSE;
 }
 
 
 /**
  * wpas_dbus_getter_state - Get interface state
- * @message: Pointer to incoming dbus message
- * @wpa_s: wpa_supplicant structure for a network interface
- * Returns: A dbus message containing a STRING representing the current
- *          interface state
+ * @iter: Pointer to incoming dbus message iter
+ * @error: Location to store error on failure
+ * @user_data: Function specific data
+ * Returns: TRUE on success, FALSE on failure
  *
  * Getter for "State" property.
  */
-DBusMessage * wpas_dbus_getter_state(DBusMessage *message,
-				     struct wpa_supplicant *wpa_s)
+dbus_bool_t wpas_dbus_getter_state(DBusMessageIter *iter, DBusError *error,
+				   void *user_data)
 {
-	DBusMessage *reply = NULL;
+	struct wpa_supplicant *wpa_s = user_data;
 	const char *str_state;
 	char *state_ls, *tmp;
+	dbus_bool_t success = FALSE;
 
 	str_state = wpa_supplicant_state_txt(wpa_s->wpa_state);
 
@@ -1991,141 +1961,154 @@ DBusMessage * wpas_dbus_getter_state(DBusMessage *message,
 	 */
 	state_ls = tmp = os_strdup(str_state);
 	if (!tmp) {
-		return dbus_message_new_error(message, DBUS_ERROR_NO_MEMORY,
-					      NULL);
+		dbus_set_error_const(error, DBUS_ERROR_NO_MEMORY, "no memory");
+		return FALSE;
 	}
 	while (*tmp) {
 		*tmp = tolower(*tmp);
 		tmp++;
 	}
 
-	reply = wpas_dbus_simple_property_getter(message, DBUS_TYPE_STRING,
-						 &state_ls);
+	success = wpas_dbus_simple_property_getter(iter, DBUS_TYPE_STRING,
+						   &state_ls, error);
 
 	os_free(state_ls);
 
-	return reply;
+	return success;
 }
 
 
 /**
  * wpas_dbus_new_iface_get_scanning - Get interface scanning state
- * @message: Pointer to incoming dbus message
- * @wpa_s: wpa_supplicant structure for a network interface
- * Returns: A dbus message containing whether the interface is scanning
+ * @iter: Pointer to incoming dbus message iter
+ * @error: Location to store error on failure
+ * @user_data: Function specific data
+ * Returns: TRUE on success, FALSE on failure
  *
  * Getter for "scanning" property.
  */
-DBusMessage * wpas_dbus_getter_scanning(DBusMessage *message,
-					struct wpa_supplicant *wpa_s)
+dbus_bool_t wpas_dbus_getter_scanning(DBusMessageIter *iter, DBusError *error,
+                                      void *user_data)
 {
+	struct wpa_supplicant *wpa_s = user_data;
 	dbus_bool_t scanning = wpa_s->scanning ? TRUE : FALSE;
-	return wpas_dbus_simple_property_getter(message, DBUS_TYPE_BOOLEAN,
-						&scanning);
+
+	return wpas_dbus_simple_property_getter(iter, DBUS_TYPE_BOOLEAN,
+						&scanning, error);
 }
 
 
 /**
  * wpas_dbus_getter_ap_scan - Control roaming mode
- * @message: Pointer to incoming dbus message
- * @wpa_s: wpa_supplicant structure for a network interface
- * Returns: A message containong value of ap_scan variable
+ * @iter: Pointer to incoming dbus message iter
+ * @error: Location to store error on failure
+ * @user_data: Function specific data
+ * Returns: TRUE on success, FALSE on failure
  *
  * Getter function for "ApScan" property.
  */
-DBusMessage * wpas_dbus_getter_ap_scan(DBusMessage *message,
-				       struct wpa_supplicant *wpa_s)
+dbus_bool_t wpas_dbus_getter_ap_scan(DBusMessageIter *iter, DBusError *error,
+				     void *user_data)
 {
+	struct wpa_supplicant *wpa_s = user_data;
 	dbus_uint32_t ap_scan = wpa_s->conf->ap_scan;
-	return wpas_dbus_simple_property_getter(message, DBUS_TYPE_UINT32,
-						&ap_scan);
+
+	return wpas_dbus_simple_property_getter(iter, DBUS_TYPE_UINT32,
+						&ap_scan, error);
 }
 
 
 /**
  * wpas_dbus_setter_ap_scan - Control roaming mode
- * @message: Pointer to incoming dbus message
- * @wpa_s: wpa_supplicant structure for a network interface
- * Returns: NULL
+ * @iter: Pointer to incoming dbus message iter
+ * @error: Location to store error on failure
+ * @user_data: Function specific data
+ * Returns: TRUE on success, FALSE on failure
  *
  * Setter function for "ApScan" property.
  */
-DBusMessage * wpas_dbus_setter_ap_scan(DBusMessage *message,
-				       struct wpa_supplicant *wpa_s)
+dbus_bool_t wpas_dbus_setter_ap_scan(DBusMessageIter *iter, DBusError *error,
+				     void *user_data)
 {
-	DBusMessage *reply = NULL;
+	struct wpa_supplicant *wpa_s = user_data;
 	dbus_uint32_t ap_scan;
 
-	reply = wpas_dbus_simple_property_setter(message, DBUS_TYPE_UINT32,
-						 &ap_scan);
-	if (reply)
-		return reply;
+	if (!wpas_dbus_simple_property_setter(iter, error, DBUS_TYPE_UINT32,
+					      &ap_scan))
+		return FALSE;
 
 	if (wpa_supplicant_set_ap_scan(wpa_s, ap_scan)) {
-		return wpas_dbus_error_invalid_args(
-			message, "ap_scan must equal 0, 1 or 2");
+		dbus_set_error_const(error, DBUS_ERROR_FAILED,
+				     "ap_scan must be 0, 1, or 2");
+		return FALSE;
 	}
-	return NULL;
+	return TRUE;
 }
 
 
 /**
  * wpas_dbus_getter_ifname - Get interface name
- * @message: Pointer to incoming dbus message
- * @wpa_s: wpa_supplicant structure for a network interface
- * Returns: A dbus message containing a name of network interface
- * associated with with wpa_s
+ * @iter: Pointer to incoming dbus message iter
+ * @error: Location to store error on failure
+ * @user_data: Function specific data
+ * Returns: TRUE on success, FALSE on failure
  *
  * Getter for "Ifname" property.
  */
-DBusMessage * wpas_dbus_getter_ifname(DBusMessage *message,
-				      struct wpa_supplicant *wpa_s)
+dbus_bool_t wpas_dbus_getter_ifname(DBusMessageIter *iter, DBusError *error,
+				    void *user_data)
 {
+	struct wpa_supplicant *wpa_s = user_data;
 	const char *ifname = wpa_s->ifname;
-	return wpas_dbus_simple_property_getter(message, DBUS_TYPE_STRING,
-						&ifname);
+
+	return wpas_dbus_simple_property_getter(iter, DBUS_TYPE_STRING,
+						&ifname, error);
 }
 
 
 /**
  * wpas_dbus_getter_driver - Get interface name
- * @message: Pointer to incoming dbus message
- * @wpa_s: wpa_supplicant structure for a network interface
- * Returns: A dbus message containing a name of network interface
- * driver associated with with wpa_s
++ * @iter: Pointer to incoming dbus message iter
++ * @error: Location to store error on failure
++ * @user_data: Function specific data
++ * Returns: TRUE on success, FALSE on failure
  *
  * Getter for "Driver" property.
  */
-DBusMessage * wpas_dbus_getter_driver(DBusMessage *message,
-				      struct wpa_supplicant *wpa_s)
+dbus_bool_t wpas_dbus_getter_driver(DBusMessageIter *iter, DBusError *error,
+				    void *user_data)
 {
+	struct wpa_supplicant *wpa_s = user_data;
 	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");
-		return wpas_dbus_error_unknown_error(message, NULL);
+		dbus_set_error(error, DBUS_ERROR_FAILED, "%s: no driver set",
+			       __func__);
+		return FALSE;
 	}
 
 	driver = wpa_s->driver->name;
-	return wpas_dbus_simple_property_getter(message, DBUS_TYPE_STRING,
-						&driver);
+	return wpas_dbus_simple_property_getter(iter, DBUS_TYPE_STRING,
+						&driver, error);
 }
 
 
 /**
  * wpas_dbus_getter_current_bss - Get current bss object path
- * @message: Pointer to incoming dbus message
- * @wpa_s: wpa_supplicant structure for a network interface
- * Returns: A dbus message containing a DBus object path to
- * current BSS
+ * @iter: Pointer to incoming dbus message iter
+ * @error: Location to store error on failure
+ * @user_data: Function specific data
+ * Returns: TRUE on success, FALSE on failure
  *
  * Getter for "CurrentBSS" property.
  */
-DBusMessage * wpas_dbus_getter_current_bss(DBusMessage *message,
-					   struct wpa_supplicant *wpa_s)
+dbus_bool_t wpas_dbus_getter_current_bss(DBusMessageIter *iter,
+					 DBusError *error,
+					 void *user_data)
 {
-	DBusMessage *reply;
+	struct wpa_supplicant *wpa_s = user_data;
 	char path_buf[WPAS_DBUS_OBJECT_PATH_MAX], *bss_obj_path = path_buf;
 
 	if (wpa_s->current_bss)
@@ -2135,27 +2118,25 @@ DBusMessage * wpas_dbus_getter_current_bss(DBusMessage *message,
 	else
 		os_snprintf(bss_obj_path, WPAS_DBUS_OBJECT_PATH_MAX, "/");
 
-	reply = wpas_dbus_simple_property_getter(message,
-						 DBUS_TYPE_OBJECT_PATH,
-						 &bss_obj_path);
-
-	return reply;
+	return wpas_dbus_simple_property_getter(iter, DBUS_TYPE_OBJECT_PATH,
+						&bss_obj_path, error);
 }
 
 
 /**
  * wpas_dbus_getter_current_network - Get current network object path
- * @message: Pointer to incoming dbus message
- * @wpa_s: wpa_supplicant structure for a network interface
- * Returns: A dbus message containing a DBus object path to
- * current network
+ * @iter: Pointer to incoming dbus message iter
+ * @error: Location to store error on failure
+ * @user_data: Function specific data
+ * Returns: TRUE on success, FALSE on failure
  *
  * Getter for "CurrentNetwork" property.
  */
-DBusMessage * wpas_dbus_getter_current_network(DBusMessage *message,
-					       struct wpa_supplicant *wpa_s)
+dbus_bool_t wpas_dbus_getter_current_network(DBusMessageIter *iter,
+					     DBusError *error,
+					     void *user_data)
 {
-	DBusMessage *reply;
+	struct wpa_supplicant *wpa_s = user_data;
 	char path_buf[WPAS_DBUS_OBJECT_PATH_MAX], *net_obj_path = path_buf;
 
 	if (wpa_s->current_ssid)
@@ -2165,70 +2146,63 @@ DBusMessage * wpas_dbus_getter_current_network(DBusMessage *message,
 	else
 		os_snprintf(net_obj_path, WPAS_DBUS_OBJECT_PATH_MAX, "/");
 
-	reply = wpas_dbus_simple_property_getter(message,
-						 DBUS_TYPE_OBJECT_PATH,
-						 &net_obj_path);
-
-	return reply;
+	return wpas_dbus_simple_property_getter(iter, DBUS_TYPE_OBJECT_PATH,
+						&net_obj_path, error);
 }
 
 
 /**
  * wpas_dbus_getter_bridge_ifname - Get interface name
- * @message: Pointer to incoming dbus message
- * @wpa_s: wpa_supplicant structure for a network interface
- * Returns: A dbus message containing a name of bridge network
- * interface associated with with wpa_s
+ * @iter: Pointer to incoming dbus message iter
+ * @error: Location to store error on failure
+ * @user_data: Function specific data
+ * Returns: TRUE on success, FALSE on failure
  *
  * Getter for "BridgeIfname" property.
  */
-DBusMessage * wpas_dbus_getter_bridge_ifname(DBusMessage *message,
-					     struct wpa_supplicant *wpa_s)
+dbus_bool_t wpas_dbus_getter_bridge_ifname(DBusMessageIter *iter,
+					   DBusError *error,
+					   void *user_data)
 {
-	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");
-		return wpas_dbus_error_unknown_error(message, NULL);
-	}
+	struct wpa_supplicant *wpa_s = user_data;
+	const char *bridge_ifname;
 
-	return wpas_dbus_simple_property_getter(message, DBUS_TYPE_STRING,
-						&bridge_ifname);
+	bridge_ifname = wpa_s->bridge_ifname ? wpa_s->bridge_ifname : "";
+	return wpas_dbus_simple_property_getter(iter, DBUS_TYPE_STRING,
+						&bridge_ifname, error);
 }
 
 
 /**
  * wpas_dbus_getter_bsss - Get array of BSSs objects
- * @message: Pointer to incoming dbus message
- * @wpa_s: wpa_supplicant structure for a network interface
- * Returns: a dbus message containing an array of all known BSS objects
- * dbus paths
+ * @iter: Pointer to incoming dbus message iter
+ * @error: Location to store error on failure
+ * @user_data: Function specific data
+ * Returns: TRUE on success, FALSE on failure
  *
  * Getter for "BSSs" property.
  */
-DBusMessage * wpas_dbus_getter_bsss(DBusMessage *message,
-				    struct wpa_supplicant *wpa_s)
+dbus_bool_t wpas_dbus_getter_bsss(DBusMessageIter *iter, DBusError *error,
+				  void *user_data)
 {
-	DBusMessage *reply = NULL;
+	struct wpa_supplicant *wpa_s = user_data;
 	struct wpa_bss *bss;
 	char **paths;
 	unsigned int i = 0;
+	dbus_bool_t success = FALSE;
 
 	paths = os_zalloc(wpa_s->num_bss * sizeof(char *));
 	if (!paths) {
-		return dbus_message_new_error(message, DBUS_ERROR_NO_MEMORY,
-					      NULL);
+		dbus_set_error_const(error, DBUS_ERROR_NO_MEMORY, "no memory");
+		return FALSE;
 	}
 
 	/* Loop through scan results and append each result's object path */
 	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);
+			dbus_set_error_const(error, DBUS_ERROR_NO_MEMORY,
+					     "no memory");
 			goto out;
 		}
 		/* Construct the object path for this BSS. */
@@ -2237,39 +2211,43 @@ DBusMessage * wpas_dbus_getter_bsss(DBusMessage *message,
 			    wpa_s->dbus_new_path, bss->id);
 	}
 
-	reply = wpas_dbus_simple_array_property_getter(message,
-						       DBUS_TYPE_OBJECT_PATH,
-						       paths, wpa_s->num_bss);
+	success = wpas_dbus_simple_array_property_getter(iter,
+							 DBUS_TYPE_OBJECT_PATH,
+							 paths, wpa_s->num_bss,
+							 error);
 
 out:
 	while (i)
 		os_free(paths[--i]);
 	os_free(paths);
-	return reply;
+	return TRUE;
 }
 
 
 /**
  * wpas_dbus_getter_networks - Get array of networks objects
- * @message: Pointer to incoming dbus message
- * @wpa_s: wpa_supplicant structure for a network interface
- * Returns: a dbus message containing an array of all configured
- * networks dbus object paths.
+ * @iter: Pointer to incoming dbus message iter
+ * @error: Location to store error on failure
+ * @user_data: Function specific data
+ * Returns: TRUE on success, FALSE on failure
  *
  * Getter for "Networks" property.
  */
-DBusMessage * wpas_dbus_getter_networks(DBusMessage *message,
-					struct wpa_supplicant *wpa_s)
+dbus_bool_t wpas_dbus_getter_networks(DBusMessageIter *iter, DBusError *error,
+				      void *user_data)
 {
-	DBusMessage *reply = NULL;
+	struct wpa_supplicant *wpa_s = user_data;
 	struct wpa_ssid *ssid;
 	char **paths;
 	unsigned int i = 0, num = 0;
+	dbus_bool_t success = FALSE;
 
 	if (wpa_s->conf == NULL) {
-		wpa_printf(MSG_ERROR, "wpas_dbus_getter_networks[dbus]: "
-			   "An error occurred getting networks list.");
-		return wpas_dbus_error_unknown_error(message, NULL);
+		wpa_printf(MSG_ERROR, "%s[dbus]: An error occurred getting "
+			   "networks list.", __func__);
+		dbus_set_error(error, DBUS_ERROR_FAILED, "%s: an error "
+			       "occurred getting the networks list", __func__);
+		return FALSE;
 	}
 
 	for (ssid = wpa_s->conf->ssid; ssid; ssid = ssid->next)
@@ -2277,17 +2255,15 @@ DBusMessage * wpas_dbus_getter_networks(DBusMessage *message,
 
 	paths = os_zalloc(num * sizeof(char *));
 	if (!paths) {
-		return dbus_message_new_error(message, DBUS_ERROR_NO_MEMORY,
-					      NULL);
+		dbus_set_error(error, DBUS_ERROR_NO_MEMORY, "no memory");
+		return FALSE;
 	}
 
 	/* Loop through configured networks and append object path of each */
 	for (ssid = wpa_s->conf->ssid; ssid; ssid = ssid->next) {
 		paths[i] = os_zalloc(WPAS_DBUS_OBJECT_PATH_MAX);
 		if (paths[i] == NULL) {
-			reply = dbus_message_new_error(message,
-						       DBUS_ERROR_NO_MEMORY,
-						       NULL);
+			dbus_set_error(error, DBUS_ERROR_NO_MEMORY, "no memory");
 			goto out;
 		}
 
@@ -2297,50 +2273,40 @@ DBusMessage * wpas_dbus_getter_networks(DBusMessage *message,
 			    wpa_s->dbus_new_path, ssid->id);
 	}
 
-	reply = wpas_dbus_simple_array_property_getter(message,
-						       DBUS_TYPE_OBJECT_PATH,
-						       paths, num);
+	success = wpas_dbus_simple_array_property_getter(iter,
+							 DBUS_TYPE_OBJECT_PATH,
+							 paths, num, error);
 
 out:
 	while (i)
 		os_free(paths[--i]);
 	os_free(paths);
-	return reply;
+	return success;
 }
 
 
 /**
  * wpas_dbus_getter_blobs - Get all blobs defined for this interface
- * @message: Pointer to incoming dbus message
- * @wpa_s: wpa_supplicant structure for a network interface
- * Returns: a dbus message containing a dictionary of pairs (blob_name, blob)
+ * @iter: Pointer to incoming dbus message iter
+ * @error: Location to store error on failure
+ * @user_data: Function specific data
+ * Returns: TRUE on success, FALSE on failure
  *
  * Getter for "Blobs" property.
  */
-DBusMessage * wpas_dbus_getter_blobs(DBusMessage *message,
-				     struct wpa_supplicant *wpa_s)
+dbus_bool_t wpas_dbus_getter_blobs(DBusMessageIter *iter, DBusError *error,
+				   void *user_data)
 {
-	DBusMessage *reply = NULL;
-	DBusMessageIter iter, variant_iter, dict_iter, entry_iter, array_iter;
+	struct wpa_supplicant *wpa_s = user_data;
+	DBusMessageIter variant_iter, dict_iter, entry_iter, array_iter;
 	struct wpa_config_blob *blob;
 
-	if (message == NULL)
-		reply = dbus_message_new(DBUS_MESSAGE_TYPE_SIGNAL);
-	else
-		reply = dbus_message_new_method_return(message);
-	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,
+	if (!dbus_message_iter_open_container(iter, DBUS_TYPE_VARIANT,
 					      "a{say}", &variant_iter) ||
 	    !dbus_message_iter_open_container(&variant_iter, DBUS_TYPE_ARRAY,
 					      "{say}", &dict_iter)) {
-		dbus_message_unref(reply);
-		return dbus_message_new_error(message, DBUS_ERROR_NO_MEMORY,
-					      NULL);
+		dbus_set_error_const(error, DBUS_ERROR_NO_MEMORY, "no memory");
+		return FALSE;
 	}
 
 	blob = wpa_s->conf->blobs;
@@ -2363,176 +2329,189 @@ DBusMessage * wpas_dbus_getter_blobs(DBusMessage *message,
 						       &array_iter) ||
 		    !dbus_message_iter_close_container(&dict_iter,
 						       &entry_iter)) {
-			dbus_message_unref(reply);
-			return dbus_message_new_error(message,
-						      DBUS_ERROR_NO_MEMORY,
-						      NULL);
+			dbus_set_error_const(error, DBUS_ERROR_NO_MEMORY,
+					     "no memory");
+			return FALSE;
 		}
 
 		blob = blob->next;
 	}
 
 	if (!dbus_message_iter_close_container(&variant_iter, &dict_iter) ||
-	    !dbus_message_iter_close_container(&iter, &variant_iter)) {
-		dbus_message_unref(reply);
-		return dbus_message_new_error(message, DBUS_ERROR_NO_MEMORY,
-					      NULL);
+	    !dbus_message_iter_close_container(iter, &variant_iter)) {
+		dbus_set_error_const(error, DBUS_ERROR_NO_MEMORY, "no memory");
+		return FALSE;
 	}
 
-	return reply;
+	return TRUE;
 }
 
+static struct wpa_bss * get_bss_helper(struct bss_handler_args *args,
+				       DBusError *error,
+				       const char *func_name)
+{
+	struct wpa_bss *res = wpa_bss_get_id(args->wpa_s, args->id);
+
+	if (!res) {
+		wpa_printf(MSG_ERROR, "%s[dbus]: no bss with id %d found",
+		           func_name, args->id);
+		dbus_set_error(error, DBUS_ERROR_FAILED, "%s: BSS %d not found",
+			       func_name, args->id);
+	}
+	return res;
+}
 
 /**
  * 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
+ * @iter: Pointer to incoming dbus message iter
+ * @error: Location to store error on failure
+ * @user_data: Function specific data
+ * Returns: TRUE on success, FALSE on failure
  *
  * Getter for "BSSID" property.
  */
-DBusMessage * wpas_dbus_getter_bss_bssid(DBusMessage *message,
-					 struct bss_handler_args *bss)
+dbus_bool_t wpas_dbus_getter_bss_bssid(DBusMessageIter *iter, DBusError *error,
+				       void *user_data)
 {
-	struct wpa_bss *res = wpa_bss_get_id(bss->wpa_s, bss->id);
+	struct bss_handler_args *args = user_data;
+	struct wpa_bss *res;
 
-	if (!res) {
-		wpa_printf(MSG_ERROR, "wpas_dbus_getter_bss_bssid[dbus]: no "
-			   "bss with id %d found", bss->id);
-		return NULL;
-	}
+	res = get_bss_helper(args, error, __func__);
+	if (!res)
+		return FALSE;
 
-	return wpas_dbus_simple_array_property_getter(message, DBUS_TYPE_BYTE,
-						      res->bssid, ETH_ALEN);
+	return wpas_dbus_simple_array_property_getter(iter, DBUS_TYPE_BYTE,
+						      res->bssid, ETH_ALEN,
+						      error);
 }
 
 
 /**
  * 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's id
- * Returns: a dbus message containing the ssid for the requested bss
+ * @iter: Pointer to incoming dbus message iter
+ * @error: Location to store error on failure
+ * @user_data: Function specific data
+ * Returns: TRUE on success, FALSE on failure
  *
  * Getter for "SSID" property.
  */
-DBusMessage * wpas_dbus_getter_bss_ssid(DBusMessage *message,
-					      struct bss_handler_args *bss)
+dbus_bool_t wpas_dbus_getter_bss_ssid(DBusMessageIter *iter, DBusError *error,
+				      void *user_data)
 {
-	struct wpa_bss *res = wpa_bss_get_id(bss->wpa_s, bss->id);
+	struct bss_handler_args *args = user_data;
+	struct wpa_bss *res;
 
-	if (!res) {
-		wpa_printf(MSG_ERROR, "wpas_dbus_getter_bss_ssid[dbus]: no "
-			   "bss with id %d found", bss->id);
-		return NULL;
-	}
+	res = get_bss_helper(args, error, __func__);
+	if (!res)
+		return FALSE;
 
-	return wpas_dbus_simple_array_property_getter(message, DBUS_TYPE_BYTE,
-						      res->ssid,
-						      res->ssid_len);
+	return wpas_dbus_simple_array_property_getter(iter, DBUS_TYPE_BYTE,
+						      res->ssid, res->ssid_len,
+						      error);
 }
 
 
 /**
  * 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
+ * @iter: Pointer to incoming dbus message iter
+ * @error: Location to store error on failure
+ * @user_data: Function specific data
+ * Returns: TRUE on success, FALSE on failure
  *
  * Getter for "Privacy" property.
  */
-DBusMessage * wpas_dbus_getter_bss_privacy(DBusMessage *message,
-					   struct bss_handler_args *bss)
+dbus_bool_t wpas_dbus_getter_bss_privacy(DBusMessageIter *iter,
+					 DBusError *error, void *user_data)
 {
-	struct wpa_bss *res = wpa_bss_get_id(bss->wpa_s, bss->id);
+	struct bss_handler_args *args = user_data;
+	struct wpa_bss *res;
 	dbus_bool_t privacy;
 
-	if (!res) {
-		wpa_printf(MSG_ERROR, "wpas_dbus_getter_bss_privacy[dbus]: no "
-			   "bss with id %d found", bss->id);
-		return NULL;
-	}
+	res = get_bss_helper(args, error, __func__);
+	if (!res)
+		return FALSE;
 
 	privacy = (res->caps & IEEE80211_CAP_PRIVACY) ? TRUE : FALSE;
-	return wpas_dbus_simple_property_getter(message, DBUS_TYPE_BOOLEAN,
-						&privacy);
+	return wpas_dbus_simple_property_getter(iter, DBUS_TYPE_BOOLEAN,
+						&privacy, error);
 }
 
 
 /**
  * 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
+ * @iter: Pointer to incoming dbus message iter
+ * @error: Location to store error on failure
+ * @user_data: Function specific data
+ * Returns: TRUE on success, FALSE on failure
  *
  * Getter for "Mode" property.
  */
-DBusMessage * wpas_dbus_getter_bss_mode(DBusMessage *message,
-					struct bss_handler_args *bss)
+dbus_bool_t wpas_dbus_getter_bss_mode(DBusMessageIter *iter, DBusError *error,
+				      void *user_data)
 {
-	struct wpa_bss *res = wpa_bss_get_id(bss->wpa_s, bss->id);
+	struct bss_handler_args *args = user_data;
+	struct wpa_bss *res;
 	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;
-	}
+	res = get_bss_helper(args, error, __func__);
+	if (!res)
+		return FALSE;
 
 	if (res->caps & IEEE80211_CAP_IBSS)
 		mode = "ad-hoc";
 	else
 		mode = "infrastructure";
 
-	return wpas_dbus_simple_property_getter(message, DBUS_TYPE_STRING,
-						&mode);
+	return wpas_dbus_simple_property_getter(iter, DBUS_TYPE_STRING,
+						&mode, error);
 }
 
 
 /**
  * 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
+ * @iter: Pointer to incoming dbus message iter
+ * @error: Location to store error on failure
+ * @user_data: Function specific data
+ * Returns: TRUE on success, FALSE on failure
  *
  * Getter for "Level" property.
  */
-DBusMessage * wpas_dbus_getter_bss_signal(DBusMessage *message,
-					  struct bss_handler_args *bss)
+dbus_bool_t wpas_dbus_getter_bss_signal(DBusMessageIter *iter,
+					DBusError *error, void *user_data)
 {
-	struct wpa_bss *res = wpa_bss_get_id(bss->wpa_s, bss->id);
+	struct bss_handler_args *args = user_data;
+	struct wpa_bss *res;
 
-	if (!res) {
-		wpa_printf(MSG_ERROR, "wpas_dbus_getter_bss_signal[dbus]: no "
-			   "bss with id %d found", bss->id);
-		return NULL;
-	}
+	res = get_bss_helper(args, error, __func__);
+	if (!res)
+		return FALSE;
 
-	return wpas_dbus_simple_property_getter(message, DBUS_TYPE_INT16,
-						&res->level);
+	return wpas_dbus_simple_property_getter(iter, DBUS_TYPE_INT16,
+						&res->level, error);
 }
 
 
 /**
  * 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
+ * @iter: Pointer to incoming dbus message iter
+ * @error: Location to store error on failure
+ * @user_data: Function specific data
+ * Returns: TRUE on success, FALSE on failure
  *
  * Getter for "Frequency" property.
  */
-DBusMessage * wpas_dbus_getter_bss_frequency(DBusMessage *message,
-					     struct bss_handler_args *bss)
+dbus_bool_t wpas_dbus_getter_bss_frequency(DBusMessageIter *iter,
+					   DBusError *error, void *user_data)
 {
-	struct wpa_bss *res = wpa_bss_get_id(bss->wpa_s, bss->id);
+	struct bss_handler_args *args = user_data;
+	struct wpa_bss *res;
 
-	if (!res) {
-		wpa_printf(MSG_ERROR, "wpas_dbus_getter_bss_frequency[dbus]: "
-			   "no bss with id %d found", bss->id);
-		return NULL;
-	}
+	res = get_bss_helper(args, error, __func__);
+	if (!res)
+		return FALSE;
 
-	return wpas_dbus_simple_property_getter(message, DBUS_TYPE_UINT16,
-						&res->freq);
+	return wpas_dbus_simple_property_getter(iter, DBUS_TYPE_UINT16,
+						&res->freq, error);
 }
 
 
@@ -2544,72 +2523,64 @@ static int cmp_u8s_desc(const void *a, const void *b)
 
 /**
  * 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
+ * @iter: Pointer to incoming dbus message iter
+ * @error: Location to store error on failure
+ * @user_data: Function specific data
+ * Returns: TRUE on success, FALSE on failure
  *
  * Getter for "Rates" property.
  */
-DBusMessage * wpas_dbus_getter_bss_rates(DBusMessage *message,
-					    struct bss_handler_args *bss)
+dbus_bool_t wpas_dbus_getter_bss_rates(DBusMessageIter *iter,
+				       DBusError *error, void *user_data)
 {
-	DBusMessage *reply;
-	struct wpa_bss *res = wpa_bss_get_id(bss->wpa_s, bss->id);
+	struct bss_handler_args *args = user_data;
+	struct wpa_bss *res;
 	u8 *ie_rates = NULL;
 	u32 *real_rates;
 	int rates_num, i;
+	dbus_bool_t success = FALSE;
 
-	if (!res) {
-		wpa_printf(MSG_ERROR, "wpas_dbus_getter_bss_rates[dbus]: "
-			   "no bss with id %d found", bss->id);
-		return NULL;
-	}
+	res = get_bss_helper(args, error, __func__);
+	if (!res)
+		return FALSE;
 
 	rates_num = wpa_bss_get_bit_rates(res, &ie_rates);
 	if (rates_num < 0)
-		return NULL;
+		return FALSE;
 
 	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);
+		dbus_set_error_const(error, DBUS_ERROR_NO_MEMORY, "no memory");
+		return FALSE;
 	}
 
 	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);
+	success = wpas_dbus_simple_array_property_getter(iter, DBUS_TYPE_UINT32,
+							 real_rates, rates_num,
+							 error);
 
 	os_free(ie_rates);
 	os_free(real_rates);
-	return reply;
+	return success;
 }
 
 
-static DBusMessage * wpas_dbus_get_bss_security_prop(
-	DBusMessage *message, struct wpa_ie_data *ie_data)
+static dbus_bool_t wpas_dbus_get_bss_security_prop(DBusMessageIter *iter,
+						   struct wpa_ie_data *ie_data,
+						   DBusError *error)
 {
-	DBusMessage *reply;
-	DBusMessageIter iter, iter_dict, variant_iter;
+	DBusMessageIter 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;
 
-	if (message == NULL)
-		reply = dbus_message_new(DBUS_MESSAGE_TYPE_SIGNAL);
-	else
-		reply = dbus_message_new_method_return(message);
-	if (!reply)
-		goto nomem;
-
-	dbus_message_iter_init_append(reply, &iter);
-	if (!dbus_message_iter_open_container(&iter, DBUS_TYPE_VARIANT,
+	if (!dbus_message_iter_open_container(iter, DBUS_TYPE_VARIANT,
 					      "a{sv}", &variant_iter))
 		goto nomem;
 
@@ -2690,152 +2661,152 @@ static DBusMessage * wpas_dbus_get_bss_security_prop(
 
 	if (!wpa_dbus_dict_close_write(&variant_iter, &iter_dict))
 		goto nomem;
-	if (!dbus_message_iter_close_container(&iter, &variant_iter))
+	if (!dbus_message_iter_close_container(iter, &variant_iter))
 		goto nomem;
 
-	return reply;
+	return TRUE;
 
 nomem:
-	if (reply)
-		dbus_message_unref(reply);
-
-	return dbus_message_new_error(message, DBUS_ERROR_NO_MEMORY, NULL);
+	dbus_set_error_const(error, DBUS_ERROR_NO_MEMORY, "no memory");
+	return FALSE;
 }
 
 
 /**
  * wpas_dbus_getter_bss_wpa - Return the WPA 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 WPA options of requested bss
+ * @iter: Pointer to incoming dbus message iter
+ * @error: Location to store error on failure
+ * @user_data: Function specific data
+ * Returns: TRUE on success, FALSE on failure
  *
  * Getter for "WPA" property.
  */
-DBusMessage * wpas_dbus_getter_bss_wpa(DBusMessage *message,
-				       struct bss_handler_args *bss)
+dbus_bool_t wpas_dbus_getter_bss_wpa(DBusMessageIter *iter, DBusError *error,
+				     void *user_data)
 {
-	struct wpa_bss *res = wpa_bss_get_id(bss->wpa_s, bss->id);
+	struct bss_handler_args *args = user_data;
+	struct wpa_bss *res;
 	struct wpa_ie_data wpa_data;
 	const u8 *ie;
 
-	if (!res) {
-		wpa_printf(MSG_ERROR, "wpas_dbus_getter_bss_wpa[dbus]: no "
-			   "bss with id %d found", bss->id);
-		return NULL;
-	}
+	res = get_bss_helper(args, error, __func__);
+	if (!res)
+		return FALSE;
 
 	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");
+		if (wpa_parse_wpa_ie(ie, 2 + ie[1], &wpa_data) < 0) {
+			dbus_set_error_const(error, DBUS_ERROR_FAILED,
+					     "failed to parse WPA IE");
+			return FALSE;
+		}
 	}
 
-	return wpas_dbus_get_bss_security_prop(message, &wpa_data);
+	return wpas_dbus_get_bss_security_prop(iter, &wpa_data, error);
 }
 
 
 /**
  * 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
+ * @iter: Pointer to incoming dbus message iter
+ * @error: Location to store error on failure
+ * @user_data: Function specific data
+ * Returns: TRUE on success, FALSE on failure
  *
  * Getter for "RSN" property.
  */
-DBusMessage * wpas_dbus_getter_bss_rsn(DBusMessage *message,
-				       struct bss_handler_args *bss)
+dbus_bool_t wpas_dbus_getter_bss_rsn(DBusMessageIter *iter, DBusError *error,
+				     void *user_data)
 {
-	struct wpa_bss *res = wpa_bss_get_id(bss->wpa_s, bss->id);
+	struct bss_handler_args *args = user_data;
+	struct wpa_bss *res;
 	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;
-	}
+	res = get_bss_helper(args, error, __func__);
+	if (!res)
+		return FALSE;
 
 	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 (wpa_parse_wpa_ie(ie, 2 + ie[1], &wpa_data) < 0) {
+			dbus_set_error_const(error, DBUS_ERROR_FAILED,
+					     "failed to parse RSN IE");
+			return FALSE;
+		}
 	}
 
-	return wpas_dbus_get_bss_security_prop(message, &wpa_data);
+	return wpas_dbus_get_bss_security_prop(iter, &wpa_data, error);
 }
 
 
 /**
  * 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
+ * @iter: Pointer to incoming dbus message iter
+ * @error: Location to store error on failure
+ * @user_data: Function specific data
+ * Returns: TRUE on success, FALSE on failure
  *
  * Getter for "IEs" property.
  */
-DBusMessage * wpas_dbus_getter_bss_ies(DBusMessage *message,
-				       struct bss_handler_args *bss)
+dbus_bool_t wpas_dbus_getter_bss_ies(DBusMessageIter *iter, DBusError *error,
+				     void *user_data)
 {
-	struct wpa_bss *res = wpa_bss_get_id(bss->wpa_s, bss->id);
+	struct bss_handler_args *args = user_data;
+	struct wpa_bss *res;
 
-	if (!res) {
-		wpa_printf(MSG_ERROR, "wpas_dbus_getter_bss_ies[dbus]: no "
-			   "bss with id %d found", bss->id);
-		return NULL;
-	}
+	res = get_bss_helper(args, error, __func__);
+	if (!res)
+		return FALSE;
 
-	return wpas_dbus_simple_array_property_getter(message, DBUS_TYPE_BYTE,
-						      res + 1, res->ie_len);
+	return wpas_dbus_simple_array_property_getter(iter, DBUS_TYPE_BYTE,
+						      res + 1, res->ie_len,
+						      error);
 }
 
 
 /**
  * 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
+ * @iter: Pointer to incoming dbus message iter
+ * @error: Location to store error on failure
+ * @user_data: Function specific data
+ * Returns: TRUE on success, FALSE 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 wpas_dbus_getter_enabled(DBusMessageIter *iter, DBusError *error,
+				     void *user_data)
 {
+	struct network_handler_args *net = user_data;
 	dbus_bool_t enabled = net->ssid->disabled ? FALSE : TRUE;
-	return wpas_dbus_simple_property_getter(message, DBUS_TYPE_BOOLEAN,
-						&enabled);
+
+	return wpas_dbus_simple_property_getter(iter, DBUS_TYPE_BOOLEAN,
+						&enabled, error);
 }
 
 
 /**
  * wpas_dbus_setter_enabled - Mark a configured network as 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: NULL indicating success or DBus error on failure
+ * @iter: Pointer to incoming dbus message iter
+ * @error: Location to store error on failure
+ * @user_data: Function specific data
+ * Returns: TRUE on success, FALSE on failure
  *
  * Setter for "Enabled" property of a configured network.
  */
-DBusMessage * wpas_dbus_setter_enabled(DBusMessage *message,
-				       struct network_handler_args *net)
+dbus_bool_t wpas_dbus_setter_enabled(DBusMessageIter *iter, DBusError *error,
+				     void *user_data)
 {
-	DBusMessage *reply = NULL;
-
+	struct network_handler_args *net = user_data;
 	struct wpa_supplicant *wpa_s;
 	struct wpa_ssid *ssid;
-
 	dbus_bool_t enable;
 
-	reply = wpas_dbus_simple_property_setter(message, DBUS_TYPE_BOOLEAN,
-						 &enable);
-
-	if (reply)
-		return reply;
+	if (!wpas_dbus_simple_property_setter(iter, error, DBUS_TYPE_BOOLEAN,
+					      &enable))
+		return FALSE;
 
 	wpa_s = net->wpa_s;
 	ssid = net->ssid;
@@ -2845,48 +2816,37 @@ DBusMessage * wpas_dbus_setter_enabled(DBusMessage *message,
 	else
 		wpa_supplicant_disable_network(wpa_s, ssid);
 
-	return NULL;
+	return TRUE;
 }
 
 
 /**
  * wpas_dbus_getter_network_properties - Get options for a configured network
- * @message: Pointer to incoming dbus message
- * @net: wpa_supplicant structure for a network interface and
- * wpa_ssid structure for a configured network
- * Returns: DBus message with network properties or DBus error on failure
+ * @iter: Pointer to incoming dbus message iter
+ * @error: Location to store error on failure
+ * @user_data: Function specific data
+ * Returns: TRUE on success, FALSE on failure
  *
  * Getter for "Properties" property of a configured network.
  */
-DBusMessage * wpas_dbus_getter_network_properties(
-	DBusMessage *message, struct network_handler_args *net)
+dbus_bool_t wpas_dbus_getter_network_properties(DBusMessageIter *iter,
+	DBusError *error, void *user_data)
 {
-	DBusMessage *reply = NULL;
-	DBusMessageIter	iter, variant_iter, dict_iter;
+	struct network_handler_args *net = user_data;
+	DBusMessageIter	variant_iter, dict_iter;
 	char **iterator;
 	char **props = wpa_config_get_all(net->ssid, 0);
-	if (!props)
-		return dbus_message_new_error(message, DBUS_ERROR_NO_MEMORY,
-					      NULL);
+	dbus_bool_t success = FALSE;
 
-	if (message == NULL)
-		reply = dbus_message_new(DBUS_MESSAGE_TYPE_SIGNAL);
-	else
-		reply = dbus_message_new_method_return(message);
-	if (!reply) {
-		reply = dbus_message_new_error(message, DBUS_ERROR_NO_MEMORY,
-					       NULL);
-		goto out;
+	if (!props) {
+		dbus_set_error_const(error, DBUS_ERROR_NO_MEMORY, "no memory");
+		return FALSE;
 	}
 
-	dbus_message_iter_init_append(reply, &iter);
-
-	if (!dbus_message_iter_open_container(&iter, DBUS_TYPE_VARIANT,
-			"a{sv}", &variant_iter) ||
+	if (!dbus_message_iter_open_container(iter, DBUS_TYPE_VARIANT, "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);
+		dbus_set_error_const(error, DBUS_ERROR_NO_MEMORY, "no memory");
 		goto out;
 	}
 
@@ -2894,10 +2854,8 @@ DBusMessage * wpas_dbus_getter_network_properties(
 	while (*iterator) {
 		if (!wpa_dbus_dict_append_string(&dict_iter, *iterator,
 						 *(iterator + 1))) {
-			dbus_message_unref(reply);
-			reply = dbus_message_new_error(message,
-						       DBUS_ERROR_NO_MEMORY,
-						       NULL);
+			dbus_set_error_const(error, DBUS_ERROR_NO_MEMORY,
+					     "no memory");
 			goto out;
 		}
 		iterator += 2;
@@ -2905,13 +2863,13 @@ DBusMessage * wpas_dbus_getter_network_properties(
 
 
 	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);
+	    !dbus_message_iter_close_container(iter, &variant_iter)) {
+		dbus_set_error_const(error, DBUS_ERROR_NO_MEMORY, "no memory");
 		goto out;
 	}
 
+	success = TRUE;
+
 out:
 	iterator = props;
 	while (*iterator) {
@@ -2919,39 +2877,27 @@ out:
 		iterator++;
 	}
 	os_free(props);
-	return reply;
+	return success;
 }
 
 
 /**
  * wpas_dbus_setter_network_properties - Set options for a configured network
- * @message: Pointer to incoming dbus message
- * @net: wpa_supplicant structure for a network interface and
- * wpa_ssid structure for a configured network
- * Returns: NULL indicating success or DBus error on failure
+ * @iter: Pointer to incoming dbus message iter
+ * @error: Location to store error on failure
+ * @user_data: Function specific data
+ * Returns: TRUE on success, FALSE on failure
  *
  * Setter for "Properties" property of a configured network.
  */
-DBusMessage * wpas_dbus_setter_network_properties(
-	DBusMessage *message, struct network_handler_args *net)
+dbus_bool_t wpas_dbus_setter_network_properties(DBusMessageIter *iter,
+						DBusError *error,
+						void *user_data)
 {
+	struct network_handler_args *net = user_data;
 	struct wpa_ssid *ssid = net->ssid;
+	DBusMessageIter	variant_iter;
 
-	DBusMessage *reply = NULL;
-	DBusMessageIter	iter, variant_iter;
-
-	dbus_message_iter_init(message, &iter);
-
-	dbus_message_iter_next(&iter);
-	dbus_message_iter_next(&iter);
-
-	dbus_message_iter_recurse(&iter, &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");
-
-	return reply;
+	dbus_message_iter_recurse(iter, &variant_iter);
+	return set_network_properties(net->wpa_s, ssid, &variant_iter, error);
 }
diff --git a/wpa_supplicant/dbus/dbus_new_handlers.h b/wpa_supplicant/dbus/dbus_new_handlers.h
index 3cdf9cb..9d5b6ff 100644
--- a/wpa_supplicant/dbus/dbus_new_handlers.h
+++ b/wpa_supplicant/dbus/dbus_new_handlers.h
@@ -26,17 +26,20 @@ struct bss_handler_args {
 	unsigned int id;
 };
 
-DBusMessage * wpas_dbus_simple_property_getter(DBusMessage *message,
-					       const int type,
-					       const void *val);
+dbus_bool_t wpas_dbus_simple_property_getter(DBusMessageIter *iter,
+					     const int type,
+					     const void *val,
+					     DBusError *error);
 
-DBusMessage * wpas_dbus_simple_property_setter(DBusMessage *message,
-					       const int type, void *val);
+dbus_bool_t wpas_dbus_simple_property_setter(DBusMessageIter *iter,
+					     DBusError *error,
+					     const int type, void *val);
 
-DBusMessage * wpas_dbus_simple_array_property_getter(DBusMessage *message,
-						     const int type,
-						     const void *array,
-						     size_t array_len);
+dbus_bool_t wpas_dbus_simple_array_property_getter(DBusMessageIter *iter,
+						   const int type,
+						   const void *array,
+						   size_t array_len,
+						   DBusError *error);
 
 DBusMessage * wpas_dbus_handler_create_interface(DBusMessage *message,
 						 struct wpa_global *global);
@@ -47,29 +50,34 @@ DBusMessage * wpas_dbus_handler_remove_interface(DBusMessage *message,
 DBusMessage * wpas_dbus_handler_get_interface(DBusMessage *message,
 					      struct wpa_global *global);
 
-DBusMessage * wpas_dbus_getter_debug_level(DBusMessage *message,
-					   struct wpa_global *global);
+dbus_bool_t wpas_dbus_getter_debug_level(DBusMessageIter *iter,
+					 DBusError *error,
+					 void *user_data);
 
-DBusMessage * wpas_dbus_getter_debug_timestamp(DBusMessage *message,
-					       struct wpa_global *global);
+dbus_bool_t wpas_dbus_getter_debug_timestamp(DBusMessageIter *iter,
+                                             DBusError *error,
+                                             void *user_data);
 
-DBusMessage * wpas_dbus_getter_debug_show_keys(DBusMessage *message,
-					       struct wpa_global *global);
+dbus_bool_t wpas_dbus_getter_debug_show_keys(DBusMessageIter *iter,
+					     DBusError *error,
+					     void *user_data);
 
-DBusMessage * wpas_dbus_setter_debug_level(DBusMessage *message,
-					   struct wpa_global *global);
+dbus_bool_t wpas_dbus_setter_debug_level(DBusMessageIter *iter,
+					 DBusError *error, void *user_data);
 
-DBusMessage * wpas_dbus_setter_debug_timestamp(DBusMessage *message,
-					       struct wpa_global *global);
+dbus_bool_t wpas_dbus_setter_debug_timestamp(DBusMessageIter *iter,
+					     DBusError *error,
+					     void *user_data);
 
-DBusMessage * wpas_dbus_setter_debug_show_keys(DBusMessage *message,
-					       struct wpa_global *global);
+dbus_bool_t wpas_dbus_setter_debug_show_keys(DBusMessageIter *iter,
+					     DBusError *error,
+					     void *user_data);
 
-DBusMessage * wpas_dbus_getter_interfaces(DBusMessage *message,
-					  struct wpa_global *global);
+dbus_bool_t wpas_dbus_getter_interfaces(DBusMessageIter *iter, DBusError *error,
+					void *user_data);
 
-DBusMessage * wpas_dbus_getter_eap_methods(DBusMessage *message,
-					   void *nothing);
+dbus_bool_t wpas_dbus_getter_eap_methods(DBusMessageIter *iter,
+					 DBusError *error, void *user_data);
 
 DBusMessage * wpas_dbus_handler_scan(DBusMessage *message,
 				     struct wpa_supplicant *wpa_s);
@@ -95,98 +103,122 @@ DBusMessage * wpas_dbus_handler_get_blob(DBusMessage *message,
 DBusMessage * wpas_dbus_handler_remove_blob(DBusMessage *message,
 					    struct wpa_supplicant *wpa_s);
 
-DBusMessage * wpas_dbus_getter_capabilities(DBusMessage *message,
-					    struct wpa_supplicant *wpa_s);
+dbus_bool_t wpas_dbus_getter_capabilities(DBusMessageIter *iter,
+					  DBusError *error, void *user_data);
 
-DBusMessage * wpas_dbus_getter_state(DBusMessage *message,
-				     struct wpa_supplicant *wpa_s);
+dbus_bool_t wpas_dbus_getter_state(DBusMessageIter *iter, DBusError *error,
+				   void *user_data);
 
-DBusMessage * wpas_dbus_getter_scanning(DBusMessage *message,
-					struct wpa_supplicant *wpa_s);
+dbus_bool_t wpas_dbus_getter_scanning(DBusMessageIter *iter, DBusError *error,
+				      void *user_data);
 
-DBusMessage * wpas_dbus_getter_ap_scan(DBusMessage *message,
-				       struct wpa_supplicant *wpa_s);
+dbus_bool_t wpas_dbus_getter_ap_scan(DBusMessageIter *iter, DBusError *error,
+				     void *user_data);
 
-DBusMessage * wpas_dbus_setter_ap_scan(DBusMessage *message,
-				       struct wpa_supplicant *wpa_s);
+dbus_bool_t wpas_dbus_setter_ap_scan(DBusMessageIter *iter, DBusError *error,
+				     void *user_data);
 
-DBusMessage * wpas_dbus_getter_ifname(DBusMessage *message,
-				      struct wpa_supplicant *wpa_s);
+dbus_bool_t wpas_dbus_getter_bss_expire_age(DBusMessageIter *iter,
+					    DBusError *error, void *user_data);
 
-DBusMessage * wpas_dbus_getter_driver(DBusMessage *message,
-				      struct wpa_supplicant *wpa_s);
+dbus_bool_t wpas_dbus_setter_bss_expire_age(DBusMessageIter *iter,
+					    DBusError *error,
+					    void *user_data);
 
-DBusMessage * wpas_dbus_getter_bridge_ifname(DBusMessage *message,
-					     struct wpa_supplicant *wpa_s);
+dbus_bool_t wpas_dbus_getter_bss_expire_count(DBusMessageIter *iter,
+					      DBusError *error,
+					      void *user_data);
 
-DBusMessage * wpas_dbus_getter_current_bss(DBusMessage *message,
-					   struct wpa_supplicant *wpa_s);
+dbus_bool_t wpas_dbus_setter_bss_expire_count(DBusMessageIter *iter,
+					      DBusError *error,
+					      void *user_data);
 
-DBusMessage * wpas_dbus_getter_current_network(DBusMessage *message,
-					       struct wpa_supplicant *wpa_s);
+dbus_bool_t wpas_dbus_getter_country(DBusMessageIter *iter, DBusError *error,
+				     void *user_data);
+
+dbus_bool_t wpas_dbus_setter_country(DBusMessageIter *iter, DBusError *error,
+				     void *user_data);
+
+dbus_bool_t wpas_dbus_getter_ifname(DBusMessageIter *iter, DBusError *error,
+				    void *user_data);
 
-DBusMessage * wpas_dbus_getter_bsss(DBusMessage *message,
-				    struct wpa_supplicant *wpa_s);
+dbus_bool_t wpas_dbus_getter_driver(DBusMessageIter *iter, DBusError *error,
+				    void *user_data);
 
-DBusMessage * wpas_dbus_getter_networks(DBusMessage *message,
-					struct wpa_supplicant *wpa_s);
+dbus_bool_t wpas_dbus_getter_bridge_ifname(DBusMessageIter *iter,
+					   DBusError *error,
+					   void *user_data);
 
-DBusMessage * wpas_dbus_getter_blobs(DBusMessage *message,
-				     struct wpa_supplicant *bss);
+dbus_bool_t wpas_dbus_getter_current_bss(DBusMessageIter *iter,
+					 DBusError *error,
+					 void *user_data);
 
-DBusMessage * wpas_dbus_getter_bss_bssid(DBusMessage *message,
-					 struct bss_handler_args *bss);
+dbus_bool_t wpas_dbus_getter_current_network(DBusMessageIter *iter,
+					     DBusError *error,
+					     void *user_data);
 
-DBusMessage * wpas_dbus_getter_bss_ssid(DBusMessage *message,
-					struct bss_handler_args *bss);
+dbus_bool_t wpas_dbus_getter_bsss(DBusMessageIter *iter, DBusError *error,
+				  void *user_data);
 
-DBusMessage * wpas_dbus_getter_bss_privacy(DBusMessage *message,
-					   struct bss_handler_args *bss);
+dbus_bool_t wpas_dbus_getter_networks(DBusMessageIter *iter, DBusError *error,
+				      void *user_data);
 
-DBusMessage * wpas_dbus_getter_bss_mode(DBusMessage *message,
-					struct bss_handler_args *bss);
+dbus_bool_t wpas_dbus_getter_blobs(DBusMessageIter *iter, DBusError *error,
+				   void *user_data);
 
-DBusMessage * wpas_dbus_getter_bss_signal(DBusMessage *message,
-					  struct bss_handler_args *bss);
+dbus_bool_t wpas_dbus_getter_bss_bssid(DBusMessageIter *iter, DBusError *error,
+				       void *user_data);
 
-DBusMessage * wpas_dbus_getter_bss_frequency(DBusMessage *message,
-					     struct bss_handler_args *bss);
+dbus_bool_t wpas_dbus_getter_bss_ssid(DBusMessageIter *iter, DBusError *error,
+				      void *user_data);
 
-DBusMessage * wpas_dbus_getter_bss_rates(DBusMessage *message,
-					 struct bss_handler_args *bss);
+dbus_bool_t wpas_dbus_getter_bss_privacy(DBusMessageIter *iter,
+					 DBusError *error, void *user_data);
 
-DBusMessage * wpas_dbus_getter_bss_wpa(DBusMessage *message,
-				       struct bss_handler_args *bss);
+dbus_bool_t wpas_dbus_getter_bss_mode(DBusMessageIter *iter, DBusError *error,
+				      void *user_data);
 
-DBusMessage * wpas_dbus_getter_bss_rsn(DBusMessage *message,
-				       struct bss_handler_args *bss);
+dbus_bool_t wpas_dbus_getter_bss_signal(DBusMessageIter *iter,
+					DBusError *error, void *user_data);
 
-DBusMessage * wpas_dbus_getter_bss_ies(DBusMessage *message,
-				       struct bss_handler_args *bss);
+dbus_bool_t wpas_dbus_getter_bss_frequency(DBusMessageIter *iter,
+					   DBusError *error, void *user_data);
 
-DBusMessage * wpas_dbus_getter_enabled(DBusMessage *message,
-				       struct network_handler_args *net);
+dbus_bool_t wpas_dbus_getter_bss_rates(DBusMessageIter *iter,
+				       DBusError *error, void *user_data);
 
-DBusMessage * wpas_dbus_setter_enabled(DBusMessage *message,
-				       struct network_handler_args *net);
+dbus_bool_t wpas_dbus_getter_bss_wpa(DBusMessageIter *iter, DBusError *error,
+				     void *user_data);
 
-DBusMessage * wpas_dbus_getter_network_properties(
-	DBusMessage *message, struct network_handler_args *net);
+dbus_bool_t wpas_dbus_getter_bss_rsn(DBusMessageIter *iter, DBusError *error,
+				     void *user_data);
 
-DBusMessage * wpas_dbus_setter_network_properties(
-	DBusMessage *message, struct network_handler_args *net);
+dbus_bool_t wpas_dbus_getter_bss_ies(DBusMessageIter *iter, DBusError *error,
+				     void *user_data);
+
+dbus_bool_t wpas_dbus_getter_enabled(DBusMessageIter *iter, DBusError *error,
+				     void *user_data);
+
+dbus_bool_t wpas_dbus_setter_enabled(DBusMessageIter *iter, DBusError *error,
+				     void *user_data);
+
+dbus_bool_t wpas_dbus_getter_network_properties(DBusMessageIter *iter,
+						DBusError *error,
+						void *user_data);
+
+dbus_bool_t wpas_dbus_setter_network_properties(DBusMessageIter *iter,
+						DBusError *error,
+						void *user_data);
 
 DBusMessage * wpas_dbus_handler_wps_start(DBusMessage *message,
 					  struct wpa_supplicant *wpa_s);
 
-DBusMessage * wpas_dbus_getter_process_credentials(
-	DBusMessage *message, struct wpa_supplicant *wpa_s);
-
-DBusMessage * wpas_dbus_setter_process_credentials(
-	DBusMessage *message, struct wpa_supplicant *wpa_s);
+dbus_bool_t wpas_dbus_getter_process_credentials(DBusMessageIter *iter,
+	DBusError *error, void *user_data);
 
-DBusMessage * wpas_dbus_getter_credentials(DBusMessage *message,
-					   struct wpa_supplicant *wpa_s);
+dbus_bool_t wpas_dbus_setter_process_credentials(DBusMessageIter *iter,
+						 DBusError *error,
+						 void *user_data);
 
 DBusMessage * wpas_dbus_error_invalid_args(DBusMessage *message,
 					   const char *arg);
diff --git a/wpa_supplicant/dbus/dbus_new_handlers_wps.c b/wpa_supplicant/dbus/dbus_new_handlers_wps.c
index dc44a59..9e934c7 100644
--- a/wpa_supplicant/dbus/dbus_new_handlers_wps.c
+++ b/wpa_supplicant/dbus/dbus_new_handlers_wps.c
@@ -289,34 +289,36 @@ DBusMessage * wpas_dbus_handler_wps_start(DBusMessage *message,
  * true if wps_cred_processing configuration field is not equal to 1 or false
  * if otherwise.
  */
-DBusMessage * wpas_dbus_getter_process_credentials(
-	DBusMessage *message, struct wpa_supplicant *wpa_s)
+dbus_bool_t wpas_dbus_getter_process_credentials(DBusMessageIter *iter,
+	DBusError *error, void *user_data)
 {
+	struct wpa_supplicant *wpa_s = user_data;
 	dbus_bool_t process = (wpa_s->conf->wps_cred_processing != 1);
-	return wpas_dbus_simple_property_getter(message, DBUS_TYPE_BOOLEAN,
-						&process);
+	return wpas_dbus_simple_property_getter(iter, DBUS_TYPE_BOOLEAN,
+						&process, error);
 }
 
 
 /**
  * wpas_dbus_setter_process_credentials - Set credentials_processed conf param
- * @message: Pointer to incoming dbus message
- * @wpa_s: %wpa_supplicant data structure
- * Returns: NULL on success or DBus error on failure
+ * @iter: Pointer to incoming dbus message iter
+ * @error: Location to store error on failure
+ * @user_data: Function specific data
+ * Returns: TRUE on success, FALSE on failure
  *
  * Setter for "ProcessCredentials" property. Sets credentials_processed on 2
  * if boolean argument is true or on 1 if otherwise.
  */
-DBusMessage * wpas_dbus_setter_process_credentials(
-	DBusMessage *message, struct wpa_supplicant *wpa_s)
+dbus_bool_t wpas_dbus_setter_process_credentials(DBusMessageIter *iter,
+						 DBusError *error,
+						 void *user_data)
 {
-	DBusMessage *reply = NULL;
+	struct wpa_supplicant *wpa_s = user_data;
 	dbus_bool_t process_credentials, old_pc;
 
-	reply = wpas_dbus_simple_property_setter(message, DBUS_TYPE_BOOLEAN,
-						 &process_credentials);
-	if (reply)
-		return reply;
+	if (!wpas_dbus_simple_property_setter(iter, error, DBUS_TYPE_BOOLEAN,
+					      &process_credentials))
+		return FALSE;
 
 	old_pc = (wpa_s->conf->wps_cred_processing != 1);
 	wpa_s->conf->wps_cred_processing = (process_credentials ? 2 : 1);
@@ -327,5 +329,5 @@ DBusMessage * wpas_dbus_setter_process_credentials(
 					       WPAS_DBUS_NEW_IFACE_WPS,
 					       "ProcessCredentials");
 
-	return NULL;
+	return TRUE;
 }
diff --git a/wpa_supplicant/dbus/dbus_new_helpers.c b/wpa_supplicant/dbus/dbus_new_helpers.c
index 06749db..e77a0c7 100644
--- a/wpa_supplicant/dbus/dbus_new_helpers.c
+++ b/wpa_supplicant/dbus/dbus_new_helpers.c
@@ -21,112 +21,49 @@
 #include "dbus_common_i.h"
 #include "dbus_new.h"
 #include "dbus_new_helpers.h"
+#include "dbus_dict_helpers.h"
 
 
-/**
- * recursive_iter_copy - Reads arguments from one iterator and
- * writes to another recursively
- * @from: iterator to read from
- * @to: iterator to write to
- *
- * Copies one iterator's elements to another. If any element in
- * iterator is of container type, its content is copied recursively
- */
-static void recursive_iter_copy(DBusMessageIter *from, DBusMessageIter *to)
+static dbus_bool_t fill_dict_with_properties(DBusMessageIter *dict_iter,
+	const struct wpa_dbus_property_desc *props,
+	const char *interface, void *user_data, DBusError *error)
 {
-
-	char *subtype = NULL;
-	int type;
-
-	/* iterate over iterator to copy */
-	while ((type = dbus_message_iter_get_arg_type(from)) !=
-	       DBUS_TYPE_INVALID) {
-
-		/* simply copy basic type entries */
-		if (dbus_type_is_basic(type)) {
-			if (dbus_type_is_fixed(type)) {
-				/*
-				 * According to DBus documentation all
-				 * fixed-length types are guaranteed to fit
-				 * 8 bytes
-				 */
-				dbus_uint64_t v;
-				dbus_message_iter_get_basic(from, &v);
-				dbus_message_iter_append_basic(to, type, &v);
-			} else {
-				char *v;
-				dbus_message_iter_get_basic(from, &v);
-				dbus_message_iter_append_basic(to, type, &v);
-			}
-		} else {
-			/* recursively copy container type entries */
-			DBusMessageIter write_subiter, read_subiter;
-
-			dbus_message_iter_recurse(from, &read_subiter);
-
-			if (type == DBUS_TYPE_VARIANT ||
-			    type == DBUS_TYPE_ARRAY) {
-				subtype = dbus_message_iter_get_signature(
-					&read_subiter);
-			}
-
-			dbus_message_iter_open_container(to, type, subtype,
-							 &write_subiter);
-
-			recursive_iter_copy(&read_subiter, &write_subiter);
-
-			dbus_message_iter_close_container(to, &write_subiter);
-			if (subtype)
-				dbus_free(subtype);
-		}
-
-		dbus_message_iter_next(from);
-	}
-}
-
-
-static unsigned int fill_dict_with_properties(
-	DBusMessageIter *dict_iter, const struct wpa_dbus_property_desc *props,
-	const char *interface, const void *user_data)
-{
-	DBusMessage *reply;
-	DBusMessageIter entry_iter, ret_iter;
-	unsigned int counter = 0;
+	DBusMessageIter entry_iter;
 	const struct wpa_dbus_property_desc *dsc;
 
 	for (dsc = props; dsc && dsc->dbus_property; dsc++) {
-		if (!os_strncmp(dsc->dbus_interface, interface,
-				WPAS_DBUS_INTERFACE_MAX) &&
-		    dsc->access != W && dsc->getter) {
-			reply = dsc->getter(NULL, user_data);
-			if (!reply)
-				continue;
-
-			if (dbus_message_get_type(reply) ==
-			    DBUS_MESSAGE_TYPE_ERROR) {
-				dbus_message_unref(reply);
-				continue;
-			}
+		/* Only return properties for the requested D-Bus interface */
+		if (os_strncmp(dsc->dbus_interface, interface,
+			       WPAS_DBUS_INTERFACE_MAX) != 0)
+			continue;
 
-			dbus_message_iter_init(reply, &ret_iter);
+		/* Handle access permissions or missing getter */
+		if (dsc->getter == NULL || dsc->access == W)
+			continue;
 
-			dbus_message_iter_open_container(dict_iter,
-							 DBUS_TYPE_DICT_ENTRY,
-							 NULL, &entry_iter);
-			dbus_message_iter_append_basic(
-				&entry_iter, DBUS_TYPE_STRING,
-				&dsc->dbus_property);
+		if (!dbus_message_iter_open_container(dict_iter,
+						      DBUS_TYPE_DICT_ENTRY,
+						      NULL, &entry_iter)) {
+			dbus_set_error_const(error, DBUS_ERROR_NO_MEMORY,
+			                     "no memory");
+			return FALSE;
+		}
+		if (!dbus_message_iter_append_basic(&entry_iter,
+						    DBUS_TYPE_STRING,
+						    &dsc->dbus_property)) {
+			dbus_set_error_const(error, DBUS_ERROR_NO_MEMORY,
+			                     "no memory");
+			return FALSE;
+		}
 
-			recursive_iter_copy(&ret_iter, &entry_iter);
+		/* An error getting a property fails the request entirely */
+		if (!dsc->getter(&entry_iter, error, user_data))
+			return FALSE;
 
-			dbus_message_iter_close_container(dict_iter,
-							  &entry_iter);
-			dbus_message_unref(reply);
-			counter++;
-		}
+		dbus_message_iter_close_container(dict_iter, &entry_iter);
 	}
 
-	return counter;
+	return TRUE;
 }
 
 
@@ -142,37 +79,43 @@ static unsigned int fill_dict_with_properties(
  * specified as argument. Returned message contains one dict argument
  * with properties names as keys and theirs values as values.
  */
-static DBusMessage * get_all_properties(
-	DBusMessage *message, char *interface,
-	struct wpa_dbus_object_desc *obj_dsc)
+static DBusMessage * get_all_properties(DBusMessage *message, char *interface,
+				        struct wpa_dbus_object_desc *obj_dsc)
 {
-	/* Create and initialize the return message */
-	DBusMessage *reply = dbus_message_new_method_return(message);
+	DBusMessage *reply;
 	DBusMessageIter iter, dict_iter;
-	int props_num;
-
-	dbus_message_iter_init_append(reply, &iter);
-
-	dbus_message_iter_open_container(&iter, DBUS_TYPE_ARRAY,
-					 DBUS_DICT_ENTRY_BEGIN_CHAR_AS_STRING
-					 DBUS_TYPE_STRING_AS_STRING
-					 DBUS_TYPE_VARIANT_AS_STRING
-					 DBUS_DICT_ENTRY_END_CHAR_AS_STRING,
-					 &dict_iter);
+	DBusError error;
 
-	props_num = fill_dict_with_properties(&dict_iter, obj_dsc->properties,
-					      interface, obj_dsc->user_data);
+	reply = dbus_message_new_method_return(message);
+	if (reply == NULL) {
+		wpa_printf(MSG_ERROR, "%s: out of memory creating dbus reply",
+			   __func__);
+		return NULL;
+	}
 
-	dbus_message_iter_close_container(&iter, &dict_iter);
+ 	dbus_message_iter_init_append(reply, &iter);
+	if (!wpa_dbus_dict_open_write(&iter, &dict_iter)) {
+		wpa_printf(MSG_ERROR, "%s: out of memory creating reply",
+			   __func__);
+		dbus_message_unref(reply);
+		reply = dbus_message_new_error(message, DBUS_ERROR_NO_MEMORY,
+					       "out of memory");
+		return reply;
+	}
 
-	if (props_num == 0) {
+	dbus_error_init(&error);
+	if (!fill_dict_with_properties(&dict_iter, obj_dsc->properties,
+				       interface, obj_dsc->user_data, &error)) {
 		dbus_message_unref(reply);
-		reply = dbus_message_new_error(message,
-					       DBUS_ERROR_INVALID_ARGS,
-					       "No readable properties in "
-					       "this interface");
+		reply = wpas_dbus_reply_new_from_error (message, &error,
+							DBUS_ERROR_INVALID_ARGS,
+							"No readable properties"
+							" in this interface");
+		dbus_error_free(&error);
+		return reply;
 	}
 
+	wpa_dbus_dict_close_write(&iter, &dict_iter);
 	return reply;
 }
 
@@ -219,15 +162,33 @@ static DBusMessage * properties_get(DBusMessage *message,
 				    const struct wpa_dbus_property_desc *dsc,
 				    void *user_data)
 {
-	if (os_strcmp(dbus_message_get_signature(message), "ss"))
+	DBusMessage *reply;
+	DBusMessageIter iter;
+	DBusError error;
+
+	if (os_strcmp(dbus_message_get_signature(message), "ss")) {
 		return dbus_message_new_error(message, DBUS_ERROR_INVALID_ARGS,
 					      NULL);
+	}
+
+	if (dsc->access == W || dsc->getter == NULL) {
+		return dbus_message_new_error(message, DBUS_ERROR_INVALID_ARGS,
+					      "Property is write-only");
+	}
 
-	if (dsc->access != W && dsc->getter)
-		return dsc->getter(message, user_data);
+	reply = dbus_message_new_method_return(message);
+	dbus_message_iter_init_append(reply, &iter);
 
-	return dbus_message_new_error(message, DBUS_ERROR_INVALID_ARGS,
-				      "Property is write-only");
+	dbus_error_init(&error);
+	if (dsc->getter(&iter, &error, user_data) == FALSE) {
+		dbus_message_unref(reply);
+		reply = wpas_dbus_reply_new_from_error(message, &error,
+		                                       DBUS_ERROR_FAILED,
+		                                       "Failed to read property");
+		dbus_error_free(&error);
+	}
+
+	return reply;
 }
 
 
@@ -235,15 +196,38 @@ static DBusMessage * properties_set(DBusMessage *message,
 				    const struct wpa_dbus_property_desc *dsc,
 				    void *user_data)
 {
-	if (os_strcmp(dbus_message_get_signature(message), "ssv"))
+	DBusMessage *reply;
+	DBusMessageIter iter;
+	DBusError error;
+
+	if (os_strcmp(dbus_message_get_signature(message), "ssv")) {
 		return dbus_message_new_error(message, DBUS_ERROR_INVALID_ARGS,
 					      NULL);
+	}
+
+	if (dsc->access == R || dsc->setter == NULL) {
+		return dbus_message_new_error(message, DBUS_ERROR_INVALID_ARGS,
+					      "Property is read-only");
+	}
+
+	dbus_message_iter_init(message, &iter);
+	/* Skip the interface name and the property name */
+	dbus_message_iter_next(&iter);
+	dbus_message_iter_next(&iter);
 
-	if (dsc->access != R && dsc->setter)
-		return dsc->setter(message, user_data);
+	/* Iter will now point to the property's new value */
+	dbus_error_init(&error);
+	if (dsc->setter(&iter, &error, user_data) == TRUE) {
+		/* Success */
+		reply = dbus_message_new_method_return(message);
+	} else {
+		reply = wpas_dbus_reply_new_from_error(message, &error,
+		                                       DBUS_ERROR_FAILED,
+		                                       "Failed to set property");
+		dbus_error_free(&error);
+	}
 
-	return dbus_message_new_error(message, DBUS_ERROR_INVALID_ARGS,
-				      "Property is read-only");
+	return reply;
 }
 
 
@@ -611,14 +595,14 @@ int wpa_dbus_unregister_object_per_iface(
 }
 
 
-static void put_changed_properties(const struct wpa_dbus_object_desc *obj_dsc,
-				   const char *interface,
-				   DBusMessageIter *dict_iter)
+static dbus_bool_t put_changed_properties(
+	const struct wpa_dbus_object_desc *obj_dsc, const char *interface,
+	DBusMessageIter *dict_iter)
 {
-	DBusMessage *getter_reply;
-	DBusMessageIter prop_iter, entry_iter;
+	DBusMessageIter entry_iter;
 	const struct wpa_dbus_property_desc *dsc;
 	int i;
+	DBusError error;
 
 	for (dsc = obj_dsc->properties, i = 0; dsc && dsc->dbus_property;
 	     dsc++, i++) {
@@ -629,37 +613,37 @@ static void put_changed_properties(const struct wpa_dbus_object_desc *obj_dsc,
 			continue;
 		obj_dsc->prop_changed_flags[i] = 0;
 
-		getter_reply = dsc->getter(NULL, obj_dsc->user_data);
-		if (!getter_reply ||
-		    dbus_message_get_type(getter_reply) ==
-		    DBUS_MESSAGE_TYPE_ERROR) {
-			wpa_printf(MSG_ERROR, "dbus: %s: Cannot get new value "
-				   "of property %s", __func__,
-				   dsc->dbus_property);
-			continue;
-		}
-
-		if (!dbus_message_iter_init(getter_reply, &prop_iter) ||
-		    !dbus_message_iter_open_container(dict_iter,
+		if (!dbus_message_iter_open_container(dict_iter,
 						      DBUS_TYPE_DICT_ENTRY,
-						      NULL, &entry_iter) ||
-		    !dbus_message_iter_append_basic(&entry_iter,
+						      NULL, &entry_iter))
+			return FALSE;
+
+		if (!dbus_message_iter_append_basic(&entry_iter,
 						    DBUS_TYPE_STRING,
 						    &dsc->dbus_property))
-			goto err;
-
-		recursive_iter_copy(&prop_iter, &entry_iter);
+			return FALSE;
+
+		dbus_error_init(&error);
+		if (!dsc->getter(&entry_iter, &error, obj_dsc->user_data)) {
+			if (dbus_error_is_set (&error)) {
+				wpa_printf(MSG_ERROR, "dbus: %s: Cannot get new"
+				           " value of property %s: (%s) %s",
+				           __func__, dsc->dbus_property,
+				           error.name, error.message);
+			} else {
+				wpa_printf(MSG_ERROR, "dbus: %s: Cannot get new"
+				           "value of property %s", __func__,
+					   dsc->dbus_property);
+			}
+			dbus_error_free(&error);
+			return FALSE;
+		}
 
 		if (!dbus_message_iter_close_container(dict_iter, &entry_iter))
-			goto err;
-
-		dbus_message_unref(getter_reply);
+			return FALSE;
 	}
 
-	return;
-
-err:
-	wpa_printf(MSG_ERROR, "dbus: %s: Cannot construct signal", __func__);
+	return TRUE;
 }
 
 
@@ -680,7 +664,8 @@ static void send_prop_changed_signal(
 					      "{sv}", &dict_iter))
 		goto err;
 
-	put_changed_properties(obj_dsc, interface, &dict_iter);
+	if (!put_changed_properties(obj_dsc, interface, &dict_iter))
+		goto err;
 
 	if (!dbus_message_iter_close_container(&signal_iter, &dict_iter))
 		goto err;
@@ -849,27 +834,75 @@ void wpa_dbus_mark_property_changed(struct wpas_dbus_priv *iface,
  * @iface: dbus priv struct
  * @path: path to DBus object which properties will be obtained
  * @interface: interface name which properties will be obtained
- * @dict_iter: correct, open DBus dictionary iterator.
+ * @iter: DBus message iter at which to append property dictionary.
  *
  * Iterates over all properties registered with object and execute getters
  * of those, which are readable and which interface matches interface
  * specified as argument. Obtained properties values are stored in
  * dict_iter dictionary.
  */
-void wpa_dbus_get_object_properties(struct wpas_dbus_priv *iface,
-				    const char *path, const char *interface,
-				    DBusMessageIter *dict_iter)
+dbus_bool_t wpa_dbus_get_object_properties(struct wpas_dbus_priv *iface,
+					   const char *path,
+					   const char *interface,
+					   DBusMessageIter *iter)
 {
 	struct wpa_dbus_object_desc *obj_desc = NULL;
+	DBusMessageIter dict_iter;
+	DBusError error;
 
 	dbus_connection_get_object_path_data(iface->con, path,
 					     (void **) &obj_desc);
 	if (!obj_desc) {
-		wpa_printf(MSG_ERROR, "dbus: wpa_dbus_get_object_properties: "
-			   "could not obtain object's private data: %s", path);
-		return;
+		wpa_printf(MSG_ERROR, "dbus: %s: could not obtain object's "
+		           "private data: %s", __func__, path);
+		return FALSE;
+	}
+
+	if (!wpa_dbus_dict_open_write(iter, &dict_iter)) {
+		wpa_printf(MSG_ERROR, "dbus: %s: failed to open message dict",
+			   __func__);
+		return FALSE;
+	}
+
+	dbus_error_init(&error);
+	if (!fill_dict_with_properties(&dict_iter, obj_desc->properties,
+				       interface, obj_desc->user_data,
+				       &error)) {
+		wpa_printf(MSG_ERROR, "dbus: %s: failed to get object"
+		           " properties: (%s) %s", __func__,
+		           dbus_error_is_set(&error) ? error.name : "none",
+		           dbus_error_is_set(&error) ? error.message : "none");
+		dbus_error_free(&error);
+		return FALSE;
 	}
 
-	fill_dict_with_properties(dict_iter, obj_desc->properties,
-				  interface, obj_desc->user_data);
+	return wpa_dbus_dict_close_write(iter, &dict_iter);
+}
+
+/**
+ * wpas_dbus_reply_new_from_error - Create a new D-Bus error message from a
+ *   dbus error structure
+ * @message: The original request message for which the error is a reply
+ * @error: The error containing a name and a descriptive error cause
+ * @fallback_name: A generic error name if @error was not set
+ * @fallback_string: A generic error string if @error was not set
+ * Returns: A new D-Bus error message
+ *
+ * Given a DBusMessage structure, creates a new D-Bus error message using
+ * the error name and string contained in that structure.
+ */
+DBusMessage *wpas_dbus_reply_new_from_error (DBusMessage *message,
+					     DBusError *error,
+					     const char *fallback_name,
+					     const char *fallback_string)
+{
+	if (error && error->name && error->message) {
+		return dbus_message_new_error(message, error->name,
+					      error->message);
+	}
+	if (fallback_name && fallback_string) {
+		return dbus_message_new_error(message, fallback_name,
+					      fallback_string);
+	}
+	return NULL;
 }
diff --git a/wpa_supplicant/dbus/dbus_new_helpers.h b/wpa_supplicant/dbus/dbus_new_helpers.h
index 8db7a37..32a3ba5 100644
--- a/wpa_supplicant/dbus/dbus_new_helpers.h
+++ b/wpa_supplicant/dbus/dbus_new_helpers.h
@@ -22,8 +22,9 @@ typedef DBusMessage * (* WPADBusMethodHandler)(DBusMessage *message,
 					       void *user_data);
 typedef void (* WPADBusArgumentFreeFunction)(void *handler_arg);
 
-typedef DBusMessage * (* WPADBusPropertyAccessor)(DBusMessage *message,
-						  const void *user_data);
+typedef dbus_bool_t (* WPADBusPropertyAccessor)(DBusMessageIter *iter,
+                                                DBusError *error,
+						void *user_data);
 
 struct wpa_dbus_object_desc {
 	DBusConnection *connection;
@@ -127,9 +128,10 @@ int wpa_dbus_unregister_object_per_iface(
 	struct wpas_dbus_priv *ctrl_iface,
 	const char *path);
 
-void wpa_dbus_get_object_properties(struct wpas_dbus_priv *iface,
-				    const char *path, const char *interface,
-				    DBusMessageIter *dict_iter);
+dbus_bool_t wpa_dbus_get_object_properties(struct wpas_dbus_priv *iface,
+					   const char *path,
+					   const char *interface,
+					   DBusMessageIter *iter);
 
 
 void wpa_dbus_flush_all_changed_properties(DBusConnection *con);
@@ -144,4 +146,9 @@ void wpa_dbus_mark_property_changed(struct wpas_dbus_priv *iface,
 DBusMessage * wpa_dbus_introspect(DBusMessage *message,
 				  struct wpa_dbus_object_desc *obj_dsc);
 
+DBusMessage *wpas_dbus_reply_new_from_error(DBusMessage *message,
+					    DBusError *error,
+					    const char *fallback_name,
+					    const char *fallback_string);
+
 #endif /* WPA_DBUS_CTRL_H */
diff --git a/wpa_supplicant/dbus/dbus_old_handlers.c b/wpa_supplicant/dbus/dbus_old_handlers.c
index d914697..3d252e7 100644
--- a/wpa_supplicant/dbus/dbus_old_handlers.c
+++ b/wpa_supplicant/dbus/dbus_old_handlers.c
@@ -116,7 +116,7 @@ DBusMessage * wpas_dbus_global_add_interface(DBusMessage *message,
 		DBusMessageIter iter_dict;
 		struct wpa_dbus_dict_entry entry;
 
-		if (!wpa_dbus_dict_open_read(&iter, &iter_dict))
+		if (!wpa_dbus_dict_open_read(&iter, &iter_dict, NULL))
 			goto error;
 		while (wpa_dbus_dict_has_dict_entry(&iter_dict)) {
 			if (!wpa_dbus_dict_get_entry(&iter_dict, &entry))
@@ -922,7 +922,7 @@ DBusMessage * wpas_dbus_iface_set_network(DBusMessage *message,
 
 	dbus_message_iter_init(message, &iter);
 
-	if (!wpa_dbus_dict_open_read(&iter, &iter_dict)) {
+	if (!wpa_dbus_dict_open_read(&iter, &iter_dict, NULL)) {
 		reply = wpas_dbus_new_invalid_opts_error(message, NULL);
 		goto out;
 	}
@@ -1202,7 +1202,7 @@ DBusMessage * wpas_dbus_iface_set_smartcard_modules(
 	if (!dbus_message_iter_init(message, &iter))
 		goto error;
 
-	if (!wpa_dbus_dict_open_read(&iter, &iter_dict))
+	if (!wpa_dbus_dict_open_read(&iter, &iter_dict, NULL))
 		goto error;
 
 	while (wpa_dbus_dict_has_dict_entry(&iter_dict)) {
@@ -1324,7 +1324,7 @@ DBusMessage * wpas_dbus_iface_set_blobs(DBusMessage *message,
 
 	dbus_message_iter_init(message, &iter);
 
-	if (!wpa_dbus_dict_open_read(&iter, &iter_dict))
+	if (!wpa_dbus_dict_open_read(&iter, &iter_dict, NULL))
 		return wpas_dbus_new_invalid_opts_error(message, NULL);
 
 	while (wpa_dbus_dict_has_dict_entry(&iter_dict)) {
-- 
1.7.4.4