/*
 * WPA Supplicant / dbus-based control interface (P2P)
 * Copyright (c) 2011-2012, Intel Corporation
 *
 * This software may be distributed under the terms of the BSD license.
 * See README for more details.
 */

#include "includes.h"

#include "utils/includes.h"
#include "common.h"
#include "../config.h"
#include "../wpa_supplicant_i.h"
#include "../wps_supplicant.h"
#include "../notify.h"
#include "dbus_new_helpers.h"
#include "dbus_new.h"
#include "dbus_new_handlers.h"
#include "dbus_new_handlers_p2p.h"
#include "dbus_dict_helpers.h"
#include "p2p/p2p.h"
#include "common/ieee802_11_defs.h"
#include "ap/hostapd.h"
#include "ap/ap_config.h"
#include "ap/wps_hostapd.h"

#include "../p2p_supplicant.h"
#include "../wifi_display.h"

/**
 * Parses out the mac address from the peer object path.
 * @peer_path - object path of the form
 *	/fi/w1/wpa_supplicant1/Interfaces/n/Peers/00112233445566 (no colons)
 * @addr - out param must be of ETH_ALEN size
 * Returns 0 if valid (including MAC), -1 otherwise
 */
static int parse_peer_object_path(const char *peer_path, u8 addr[ETH_ALEN])
{
	const char *p;

	if (!peer_path)
		return -1;
	p = os_strrchr(peer_path, '/');
	if (!p)
		return -1;
	p++;
	return hwaddr_compact_aton(p, addr);
}


/**
 * wpas_dbus_error_persistent_group_unknown - Return a new PersistentGroupUnknown
 * error message
 * @message: Pointer to incoming dbus message this error refers to
 * Returns: a dbus error message
 *
 * Convenience function to create and return an invalid persistent group error.
 */
static DBusMessage *
wpas_dbus_error_persistent_group_unknown(DBusMessage *message)
{
	return dbus_message_new_error(
		message, WPAS_DBUS_ERROR_NETWORK_UNKNOWN,
		"There is no such persistent group in this P2P device.");
}


DBusMessage * wpas_dbus_handler_p2p_find(DBusMessage *message,
					 struct wpa_supplicant *wpa_s)
{
	struct wpa_dbus_dict_entry entry;
	DBusMessage *reply = NULL;
	DBusMessageIter iter;
	DBusMessageIter iter_dict;
	unsigned int timeout = 0;
	enum p2p_discovery_type type = P2P_FIND_START_WITH_FULL;
	int num_req_dev_types = 0;
	unsigned int i;
	u8 *req_dev_types = NULL;

	dbus_message_iter_init(message, &iter);
	entry.key = NULL;

	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))
			goto error;

		if (os_strcmp(entry.key, "Timeout") == 0 &&
		    entry.type == DBUS_TYPE_INT32) {
			timeout = entry.uint32_value;
		} else if (os_strcmp(entry.key, "RequestedDeviceTypes") == 0) {
			if (entry.type != DBUS_TYPE_ARRAY ||
			    entry.array_type != WPAS_DBUS_TYPE_BINARRAY)
				goto error_clear;

			os_free(req_dev_types);
			req_dev_types =
				os_malloc(WPS_DEV_TYPE_LEN * entry.array_len);
			if (!req_dev_types)
				goto error_clear;

			for (i = 0; i < entry.array_len; i++) {
				if (wpabuf_len(entry.binarray_value[i]) !=
				    WPS_DEV_TYPE_LEN)
					goto error_clear;
				os_memcpy(req_dev_types + i * WPS_DEV_TYPE_LEN,
					  wpabuf_head(entry.binarray_value[i]),
					  WPS_DEV_TYPE_LEN);
			}
			num_req_dev_types = entry.array_len;
		} else if (os_strcmp(entry.key, "DiscoveryType") == 0 &&
			   entry.type == DBUS_TYPE_STRING) {
			if (os_strcmp(entry.str_value, "start_with_full") == 0)
				type = P2P_FIND_START_WITH_FULL;
			else if (os_strcmp(entry.str_value, "social") == 0)
				type = P2P_FIND_ONLY_SOCIAL;
			else if (os_strcmp(entry.str_value, "progressive") == 0)
				type = P2P_FIND_PROGRESSIVE;
			else
				goto error_clear;
		} else
			goto error_clear;
		wpa_dbus_dict_entry_clear(&entry);
	}

	if (wpa_s->p2p_dev)
		wpa_s = wpa_s->p2p_dev;

	wpas_p2p_find(wpa_s, timeout, type, num_req_dev_types, req_dev_types,
		      NULL, 0, 0, NULL, 0);
	os_free(req_dev_types);
	return reply;

error_clear:
	wpa_dbus_dict_entry_clear(&entry);
error:
	os_free(req_dev_types);
	reply = wpas_dbus_error_invalid_args(message, entry.key);
	return reply;
}


DBusMessage * wpas_dbus_handler_p2p_stop_find(DBusMessage *message,
					      struct wpa_supplicant *wpa_s)
{
	if (wpa_s->p2p_dev)
		wpa_s = wpa_s->p2p_dev;

	wpas_p2p_stop_find(wpa_s);
	return NULL;
}


DBusMessage * wpas_dbus_handler_p2p_rejectpeer(DBusMessage *message,
					       struct wpa_supplicant *wpa_s)
{
	DBusMessageIter iter;
	char *peer_object_path = NULL;
	u8 peer_addr[ETH_ALEN];

	dbus_message_iter_init(message, &iter);
	dbus_message_iter_get_basic(&iter, &peer_object_path);

	if (parse_peer_object_path(peer_object_path, peer_addr) < 0)
		return wpas_dbus_error_invalid_args(message, NULL);

	if (wpa_s->p2p_dev)
		wpa_s = wpa_s->p2p_dev;

	if (wpas_p2p_reject(wpa_s, peer_addr) < 0)
		return wpas_dbus_error_unknown_error(message,
				"Failed to call wpas_p2p_reject method.");

	return NULL;
}


DBusMessage * wpas_dbus_handler_p2p_listen(DBusMessage *message,
					   struct wpa_supplicant *wpa_s)
{
	dbus_int32_t timeout = 0;

	if (!dbus_message_get_args(message, NULL, DBUS_TYPE_INT32, &timeout,
				   DBUS_TYPE_INVALID))
		return wpas_dbus_error_no_memory(message);

	if (wpa_s->p2p_dev)
		wpa_s = wpa_s->p2p_dev;

	if (wpas_p2p_listen(wpa_s, (unsigned int) timeout)) {
		return dbus_message_new_error(message,
					      WPAS_DBUS_ERROR_UNKNOWN_ERROR,
					      "Could not start P2P listen");
	}

	return NULL;
}


DBusMessage * wpas_dbus_handler_p2p_extendedlisten(
	DBusMessage *message, struct wpa_supplicant *wpa_s)
{
	unsigned int period = 0, interval = 0;
	struct wpa_dbus_dict_entry entry;
	DBusMessageIter iter;
	DBusMessageIter iter_dict;

	dbus_message_iter_init(message, &iter);
	entry.key = NULL;

	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))
			goto error;

		if (os_strcmp(entry.key, "period") == 0 &&
		    entry.type == DBUS_TYPE_INT32)
			period = entry.uint32_value;
		else if (os_strcmp(entry.key, "interval") == 0 &&
			 entry.type == DBUS_TYPE_INT32)
			interval = entry.uint32_value;
		else
			goto error_clear;
		wpa_dbus_dict_entry_clear(&entry);
	}

	if (wpa_s->p2p_dev)
		wpa_s = wpa_s->p2p_dev;

	if (wpas_p2p_ext_listen(wpa_s, period, interval))
		return wpas_dbus_error_unknown_error(
			message, "failed to initiate a p2p_ext_listen.");

	return NULL;

error_clear:
	wpa_dbus_dict_entry_clear(&entry);
error:
	return wpas_dbus_error_invalid_args(message, entry.key);
}


DBusMessage * wpas_dbus_handler_p2p_presence_request(
	DBusMessage *message, struct wpa_supplicant *wpa_s)
{
	unsigned int dur1 = 0, int1 = 0, dur2 = 0, int2 = 0;
	struct wpa_dbus_dict_entry entry;
	DBusMessageIter iter;
	DBusMessageIter iter_dict;

	dbus_message_iter_init(message, &iter);
	entry.key = NULL;

	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))
			goto error;

		if (os_strcmp(entry.key, "duration1") == 0 &&
		    entry.type == DBUS_TYPE_INT32)
			dur1 = entry.uint32_value;
		else if (os_strcmp(entry.key, "interval1") == 0 &&
			 entry.type == DBUS_TYPE_INT32)
			int1 = entry.uint32_value;
		else if (os_strcmp(entry.key, "duration2") == 0 &&
			 entry.type == DBUS_TYPE_INT32)
			dur2 = entry.uint32_value;
		else if (os_strcmp(entry.key, "interval2") == 0 &&
			 entry.type == DBUS_TYPE_INT32)
			int2 = entry.uint32_value;
		else
			goto error_clear;

		wpa_dbus_dict_entry_clear(&entry);
	}

	if (wpa_s->p2p_dev)
		wpa_s = wpa_s->p2p_dev;

	if (wpas_p2p_presence_req(wpa_s, dur1, int1, dur2, int2) < 0)
		return wpas_dbus_error_unknown_error(message,
				"Failed to invoke presence request.");

	return NULL;

error_clear:
	wpa_dbus_dict_entry_clear(&entry);
error:
	return wpas_dbus_error_invalid_args(message, entry.key);
}


DBusMessage * wpas_dbus_handler_p2p_group_add(DBusMessage *message,
					      struct wpa_supplicant *wpa_s)
{
	DBusMessageIter iter_dict;
	DBusMessage *reply = NULL;
	DBusMessageIter iter;
	struct wpa_dbus_dict_entry entry;
	char *pg_object_path = NULL;
	int persistent_group = 0;
	int freq = 0;
	char *iface = NULL;
	unsigned int group_id = 0;
	struct wpa_ssid *ssid;

	dbus_message_iter_init(message, &iter);

	if (!wpa_dbus_dict_open_read(&iter, &iter_dict, NULL))
		goto inv_args;

	while (wpa_dbus_dict_has_dict_entry(&iter_dict)) {
		if (!wpa_dbus_dict_get_entry(&iter_dict, &entry))
			goto inv_args;

		if (os_strcmp(entry.key, "persistent") == 0 &&
		    entry.type == DBUS_TYPE_BOOLEAN) {
			persistent_group = entry.bool_value;
		} else if (os_strcmp(entry.key, "frequency") == 0 &&
			   entry.type == DBUS_TYPE_INT32) {
			freq = entry.int32_value;
			if (freq <= 0)
				goto inv_args_clear;
		} else if (os_strcmp(entry.key, "persistent_group_object") ==
			   0 &&
			   entry.type == DBUS_TYPE_OBJECT_PATH)
			pg_object_path = os_strdup(entry.str_value);
		else
			goto inv_args_clear;

		wpa_dbus_dict_entry_clear(&entry);
	}

	if (wpa_s->p2p_dev)
		wpa_s = wpa_s->p2p_dev;

	if (pg_object_path != NULL) {
		char *net_id_str;

		/*
		 * A persistent group Object Path is defined meaning we want
		 * to re-invoke a persistent group.
		 */

		iface = wpas_dbus_new_decompose_object_path(
			pg_object_path, WPAS_DBUS_NEW_PERSISTENT_GROUPS_PART,
			&net_id_str);
		if (iface == NULL || net_id_str == NULL ||
		    !wpa_s->parent->dbus_new_path ||
		    os_strcmp(iface, wpa_s->parent->dbus_new_path) != 0) {
			reply =
			    wpas_dbus_error_invalid_args(message,
							 pg_object_path);
			goto out;
		}

		group_id = strtoul(net_id_str, NULL, 10);
		if (errno == EINVAL) {
			reply = wpas_dbus_error_invalid_args(
						message, pg_object_path);
			goto out;
		}

		/* Get the SSID structure from the persistent group id */
		ssid = wpa_config_get_network(wpa_s->conf, group_id);
		if (ssid == NULL || ssid->disabled != 2)
			goto inv_args;

		if (wpas_p2p_group_add_persistent(wpa_s, ssid, 0, freq, 0, 0, 0,
						  NULL, 0)) {
			reply = wpas_dbus_error_unknown_error(
				message,
				"Failed to reinvoke a persistent group");
			goto out;
		}
	} else if (wpas_p2p_group_add(wpa_s, persistent_group, freq, 0, 0))
		goto inv_args;

out:
	os_free(pg_object_path);
	os_free(iface);
	return reply;
inv_args_clear:
	wpa_dbus_dict_entry_clear(&entry);
inv_args:
	reply = wpas_dbus_error_invalid_args(message, NULL);
	goto out;
}


DBusMessage * wpas_dbus_handler_p2p_disconnect(DBusMessage *message,
					       struct wpa_supplicant *wpa_s)
{
	if (wpas_p2p_disconnect(wpa_s))
		return wpas_dbus_error_unknown_error(message,
						"failed to disconnect");

	return NULL;
}


static dbus_bool_t wpa_dbus_p2p_check_enabled(struct wpa_supplicant *wpa_s,
					      DBusMessage *message,
					      DBusMessage **out_reply,
					      DBusError *error)
{
	/* Return an error message or an error if P2P isn't available */
	if (wpa_s->global->p2p_disabled || wpa_s->global->p2p == NULL) {
		if (out_reply) {
			*out_reply = dbus_message_new_error(
				message, DBUS_ERROR_FAILED,
				"P2P is not available for this interface");
		}
		dbus_set_error_const(error, DBUS_ERROR_FAILED,
				     "P2P is not available for this interface");
		return FALSE;
	}
	return TRUE;
}


DBusMessage * wpas_dbus_handler_p2p_flush(DBusMessage *message,
					  struct wpa_supplicant *wpa_s)
{
	DBusMessage *reply = NULL;

	if (!wpa_dbus_p2p_check_enabled(wpa_s, message, &reply, NULL))
		return reply;

	if (wpa_s->p2p_dev)
		wpa_s = wpa_s->p2p_dev;

	os_memset(wpa_s->p2p_auth_invite, 0, ETH_ALEN);
	wpa_s->force_long_sd = 0;
	p2p_flush(wpa_s->global->p2p);

	return NULL;
}


DBusMessage * wpas_dbus_handler_p2p_connect(DBusMessage *message,
					    struct wpa_supplicant *wpa_s)
{
	DBusMessageIter iter_dict;
	DBusMessage *reply = NULL;
	DBusMessageIter iter;
	struct wpa_dbus_dict_entry entry;
	char *peer_object_path = NULL;
	int persistent_group = 0;
	int join = 0;
	int authorize_only = 0;
	int go_intent = -1;
	int freq = 0;
	u8 addr[ETH_ALEN];
	char *pin = NULL;
	enum p2p_wps_method wps_method = WPS_NOT_READY;
	int new_pin;
	char *err_msg = NULL;
	char *iface = NULL;

	if (!wpa_dbus_p2p_check_enabled(wpa_s, message, &reply, NULL))
		return reply;

	dbus_message_iter_init(message, &iter);

	if (!wpa_dbus_dict_open_read(&iter, &iter_dict, NULL))
		goto inv_args;

	while (wpa_dbus_dict_has_dict_entry(&iter_dict)) {
		if (!wpa_dbus_dict_get_entry(&iter_dict, &entry))
			goto inv_args;

		if (os_strcmp(entry.key, "peer") == 0 &&
		    entry.type == DBUS_TYPE_OBJECT_PATH) {
			peer_object_path = os_strdup(entry.str_value);
		} else if (os_strcmp(entry.key, "persistent") == 0 &&
			   entry.type == DBUS_TYPE_BOOLEAN) {
			persistent_group = entry.bool_value;
		} else if (os_strcmp(entry.key, "join") == 0 &&
			   entry.type == DBUS_TYPE_BOOLEAN) {
			join = entry.bool_value;
		} else if (os_strcmp(entry.key, "authorize_only") == 0 &&
			   entry.type == DBUS_TYPE_BOOLEAN) {
			authorize_only = entry.bool_value;
		} else if (os_strcmp(entry.key, "frequency") == 0 &&
			   entry.type == DBUS_TYPE_INT32) {
			freq = entry.int32_value;
			if (freq <= 0)
				goto inv_args_clear;
		} else if (os_strcmp(entry.key, "go_intent") == 0 &&
			   entry.type == DBUS_TYPE_INT32) {
			go_intent = entry.int32_value;
			if ((go_intent < 0) || (go_intent > 15))
				goto inv_args_clear;
		} else if (os_strcmp(entry.key, "wps_method") == 0 &&
			   entry.type == DBUS_TYPE_STRING) {
			if (os_strcmp(entry.str_value, "pbc") == 0)
				wps_method = WPS_PBC;
			else if (os_strcmp(entry.str_value, "pin") == 0)
				wps_method = WPS_PIN_DISPLAY;
			else if (os_strcmp(entry.str_value, "display") == 0)
				wps_method = WPS_PIN_DISPLAY;
			else if (os_strcmp(entry.str_value, "keypad") == 0)
				wps_method = WPS_PIN_KEYPAD;
			else
				goto inv_args_clear;
		} else if (os_strcmp(entry.key, "pin") == 0 &&
			   entry.type == DBUS_TYPE_STRING) {
			pin = os_strdup(entry.str_value);
		} else
			goto inv_args_clear;

		wpa_dbus_dict_entry_clear(&entry);
	}

	if (wps_method == WPS_NOT_READY ||
	    parse_peer_object_path(peer_object_path, addr) < 0 ||
	    !p2p_peer_known(wpa_s->global->p2p, addr))
		goto inv_args;

	/*
	 * Validate the wps_method specified and the pin value.
	 */
	if ((!pin || !pin[0]) && wps_method == WPS_PIN_KEYPAD)
		goto inv_args;

	if (wpa_s->p2p_dev)
		wpa_s = wpa_s->p2p_dev;

	new_pin = wpas_p2p_connect(wpa_s, addr, pin, wps_method,
				   persistent_group, 0, join, authorize_only,
				   go_intent, freq, -1, 0, 0, 0);

	if (new_pin >= 0) {
		char npin[9];
		char *generated_pin;

		os_snprintf(npin, sizeof(npin), "%08d", new_pin);
		generated_pin = npin;
		reply = dbus_message_new_method_return(message);
		dbus_message_append_args(reply, DBUS_TYPE_STRING,
					 &generated_pin, DBUS_TYPE_INVALID);
	} else {
		switch (new_pin) {
		case -2:
			err_msg =
				"connect failed due to channel unavailability.";
			iface = WPAS_DBUS_ERROR_CONNECT_CHANNEL_UNAVAILABLE;
			break;

		case -3:
			err_msg = "connect failed due to unsupported channel.";
			iface = WPAS_DBUS_ERROR_CONNECT_CHANNEL_UNSUPPORTED;
			break;

		default:
			err_msg = "connect failed due to unspecified error.";
			iface = WPAS_DBUS_ERROR_CONNECT_UNSPECIFIED_ERROR;
			break;
		}

		/*
		 * TODO:
		 * Do we need specialized errors corresponding to above
		 * error conditions as against just returning a different
		 * error message?
		 */
		reply = dbus_message_new_error(message, iface, err_msg);
	}

out:
	os_free(peer_object_path);
	os_free(pin);
	return reply;
inv_args_clear:
	wpa_dbus_dict_entry_clear(&entry);
inv_args:
	reply = wpas_dbus_error_invalid_args(message, NULL);
	goto out;
}


DBusMessage * wpas_dbus_handler_p2p_invite(DBusMessage *message,
					   struct wpa_supplicant *wpa_s)
{
	DBusMessageIter iter_dict;
	DBusMessage *reply = NULL;
	DBusMessageIter iter;
	struct wpa_dbus_dict_entry entry;
	char *peer_object_path = NULL;
	char *pg_object_path = NULL;
	char *iface = NULL;
	u8 peer_addr[ETH_ALEN];
	unsigned int group_id = 0;
	int persistent = 0;
	struct wpa_ssid *ssid;

	if (!wpa_dbus_p2p_check_enabled(wpa_s, message, &reply, NULL))
		return reply;

	dbus_message_iter_init(message, &iter);

	if (!wpa_dbus_dict_open_read(&iter, &iter_dict, NULL))
		goto err;

	while (wpa_dbus_dict_has_dict_entry(&iter_dict)) {
		if (!wpa_dbus_dict_get_entry(&iter_dict, &entry))
			goto err;

		if (os_strcmp(entry.key, "peer") == 0 &&
		    entry.type == DBUS_TYPE_OBJECT_PATH) {
			peer_object_path = os_strdup(entry.str_value);
			wpa_dbus_dict_entry_clear(&entry);
		} else if (os_strcmp(entry.key, "persistent_group_object") ==
			   0 &&
			   entry.type == DBUS_TYPE_OBJECT_PATH) {
			pg_object_path = os_strdup(entry.str_value);
			persistent = 1;
			wpa_dbus_dict_entry_clear(&entry);
		} else {
			wpa_dbus_dict_entry_clear(&entry);
			goto err;
		}
	}

	if (parse_peer_object_path(peer_object_path, peer_addr) < 0 ||
	    !p2p_peer_known(wpa_s->global->p2p, peer_addr))
		goto err;

	if (wpa_s->p2p_dev)
		wpa_s = wpa_s->p2p_dev;

	if (persistent) {
		char *net_id_str;
		/*
		 * A group ID is defined meaning we want to re-invoke a
		 * persistent group
		 */

		iface = wpas_dbus_new_decompose_object_path(
			pg_object_path,
			WPAS_DBUS_NEW_PERSISTENT_GROUPS_PART,
			&net_id_str);
		if (iface == NULL || net_id_str == NULL ||
		    !wpa_s->parent->dbus_new_path ||
		    os_strcmp(iface, wpa_s->parent->dbus_new_path) != 0) {
			reply = wpas_dbus_error_invalid_args(message,
							     pg_object_path);
			goto out;
		}

		group_id = strtoul(net_id_str, NULL, 10);
		if (errno == EINVAL) {
			reply = wpas_dbus_error_invalid_args(
				message, pg_object_path);
			goto out;
		}

		/* Get the SSID structure from the persistent group id */
		ssid = wpa_config_get_network(wpa_s->conf, group_id);
		if (ssid == NULL || ssid->disabled != 2)
			goto err;

		if (wpas_p2p_invite(wpa_s, peer_addr, ssid, NULL, 0, 0, 0, 0) <
		    0) {
			reply = wpas_dbus_error_unknown_error(
				message,
				"Failed to reinvoke a persistent group");
			goto out;
		}
	} else {
		/*
		 * No group ID means propose to a peer to join my active group
		 */
		if (wpas_p2p_invite_group(wpa_s, wpa_s->ifname,
					  peer_addr, NULL)) {
			reply = wpas_dbus_error_unknown_error(
				message, "Failed to join to an active group");
			goto out;
		}
	}

out:
	os_free(iface);
	os_free(pg_object_path);
	os_free(peer_object_path);
	return reply;

err:
	reply = wpas_dbus_error_invalid_args(message, NULL);
	goto out;
}


DBusMessage * wpas_dbus_handler_p2p_prov_disc_req(DBusMessage *message,
						  struct wpa_supplicant *wpa_s)
{
	DBusMessageIter iter;
	char *peer_object_path = NULL;
	char *config_method = NULL;
	u8 peer_addr[ETH_ALEN];

	dbus_message_iter_init(message, &iter);
	dbus_message_iter_get_basic(&iter, &peer_object_path);

	if (parse_peer_object_path(peer_object_path, peer_addr) < 0)
		return wpas_dbus_error_invalid_args(message, NULL);

	dbus_message_iter_next(&iter);
	dbus_message_iter_get_basic(&iter, &config_method);

	/*
	 * Validation checks on config_method are being duplicated here
	 * to be able to return invalid args reply since the error code
	 * from p2p module are not granular enough (yet).
	 */
	if (os_strcmp(config_method, "display") &&
	    os_strcmp(config_method, "keypad") &&
	    os_strcmp(config_method, "pbc") &&
	    os_strcmp(config_method, "pushbutton"))
		return wpas_dbus_error_invalid_args(message, NULL);

	if (wpa_s->p2p_dev)
		wpa_s = wpa_s->p2p_dev;

	if (wpas_p2p_prov_disc(wpa_s, peer_addr, config_method,
			       WPAS_P2P_PD_FOR_GO_NEG, NULL) < 0)
		return wpas_dbus_error_unknown_error(message,
				"Failed to send provision discovery request");

	return NULL;
}


/*
 * P2P Device property accessor methods.
 */

dbus_bool_t wpas_dbus_getter_p2p_device_config(DBusMessageIter *iter,
					       DBusError *error,
					       void *user_data)
{
	struct wpa_supplicant *wpa_s = user_data;
	DBusMessageIter variant_iter, dict_iter;
	DBusMessageIter iter_secdev_dict_entry, iter_secdev_dict_val,
		iter_secdev_dict_array;
	const char *dev_name;
	int num_vendor_extensions = 0;
	int i;
	const struct wpabuf *vendor_ext[P2P_MAX_WPS_VENDOR_EXT];

	if (!wpa_dbus_p2p_check_enabled(wpa_s, NULL, NULL, error))
		return FALSE;

	if (wpa_s->p2p_dev)
		wpa_s = wpa_s->p2p_dev;

	if (!dbus_message_iter_open_container(iter, DBUS_TYPE_VARIANT,
					      "a{sv}", &variant_iter) ||
	    !wpa_dbus_dict_open_write(&variant_iter, &dict_iter))
		goto err_no_mem;

	/* DeviceName */
	dev_name = wpa_s->conf->device_name;
	if (dev_name &&
	    !wpa_dbus_dict_append_string(&dict_iter, "DeviceName", dev_name))
		goto err_no_mem;

	/* Primary device type */
	if (!wpa_dbus_dict_append_byte_array(&dict_iter, "PrimaryDeviceType",
					     (char *) wpa_s->conf->device_type,
					     WPS_DEV_TYPE_LEN))
		goto err_no_mem;

	/* Secondary device types */
	if (wpa_s->conf->num_sec_device_types) {
		if (!wpa_dbus_dict_begin_array(&dict_iter,
					       "SecondaryDeviceTypes",
					       DBUS_TYPE_ARRAY_AS_STRING
					       DBUS_TYPE_BYTE_AS_STRING,
					       &iter_secdev_dict_entry,
					       &iter_secdev_dict_val,
					       &iter_secdev_dict_array))
			goto err_no_mem;

		for (i = 0; i < wpa_s->conf->num_sec_device_types; i++)
			wpa_dbus_dict_bin_array_add_element(
				&iter_secdev_dict_array,
				wpa_s->conf->sec_device_type[i],
				WPS_DEV_TYPE_LEN);

		if (!wpa_dbus_dict_end_array(&dict_iter,
					     &iter_secdev_dict_entry,
					     &iter_secdev_dict_val,
					     &iter_secdev_dict_array))
			goto err_no_mem;
	}

	/* Vendor Extensions */
	for (i = 0; i < P2P_MAX_WPS_VENDOR_EXT; i++) {
		if (wpa_s->conf->wps_vendor_ext[i] == NULL)
			continue;
		vendor_ext[num_vendor_extensions++] =
			wpa_s->conf->wps_vendor_ext[i];
	}

	if ((num_vendor_extensions &&
	     !wpa_dbus_dict_append_wpabuf_array(&dict_iter,
						"VendorExtension",
						vendor_ext,
						num_vendor_extensions)) ||
	    !wpa_dbus_dict_append_uint32(&dict_iter, "GOIntent",
					 wpa_s->conf->p2p_go_intent) ||
	    !wpa_dbus_dict_append_bool(&dict_iter, "PersistentReconnect",
				       wpa_s->conf->persistent_reconnect) ||
	    !wpa_dbus_dict_append_uint32(&dict_iter, "ListenRegClass",
					 wpa_s->conf->p2p_listen_reg_class) ||
	    !wpa_dbus_dict_append_uint32(&dict_iter, "ListenChannel",
					 wpa_s->conf->p2p_listen_channel) ||
	    !wpa_dbus_dict_append_uint32(&dict_iter, "OperRegClass",
					 wpa_s->conf->p2p_oper_reg_class) ||
	    !wpa_dbus_dict_append_uint32(&dict_iter, "OperChannel",
					 wpa_s->conf->p2p_oper_channel) ||
	    (wpa_s->conf->p2p_ssid_postfix &&
	     !wpa_dbus_dict_append_string(&dict_iter, "SsidPostfix",
					  wpa_s->conf->p2p_ssid_postfix)) ||
	    !wpa_dbus_dict_append_bool(&dict_iter, "IntraBss",
				       wpa_s->conf->p2p_intra_bss) ||
	    !wpa_dbus_dict_append_uint32(&dict_iter, "GroupIdle",
					 wpa_s->conf->p2p_group_idle) ||
	    !wpa_dbus_dict_append_uint32(&dict_iter, "disassoc_low_ack",
					 wpa_s->conf->disassoc_low_ack) ||
	    !wpa_dbus_dict_append_bool(&dict_iter, "NoGroupIface",
				       wpa_s->conf->p2p_no_group_iface) ||
	    !wpa_dbus_dict_append_uint32(&dict_iter, "p2p_search_delay",
					 wpa_s->conf->p2p_search_delay) ||
	    !wpa_dbus_dict_close_write(&variant_iter, &dict_iter) ||
	    !dbus_message_iter_close_container(iter, &variant_iter))
		goto err_no_mem;

	return TRUE;

err_no_mem:
	dbus_set_error_const(error, DBUS_ERROR_NO_MEMORY, "no memory");
	return FALSE;
}


dbus_bool_t wpas_dbus_setter_p2p_device_config(DBusMessageIter *iter,
					       DBusError *error,
					       void *user_data)
{
	struct wpa_supplicant *wpa_s = user_data;
	DBusMessageIter variant_iter, iter_dict;
	struct wpa_dbus_dict_entry entry = {.type = DBUS_TYPE_STRING };
	unsigned int i;

	if (!wpa_dbus_p2p_check_enabled(wpa_s, NULL, NULL, error))
		return FALSE;

	if (wpa_s->p2p_dev)
		wpa_s = wpa_s->p2p_dev;

	dbus_message_iter_recurse(iter, &variant_iter);
	if (!wpa_dbus_dict_open_read(&variant_iter, &iter_dict, error))
		return FALSE;

	while (wpa_dbus_dict_has_dict_entry(&iter_dict)) {
		if (!wpa_dbus_dict_get_entry(&iter_dict, &entry)) {
			dbus_set_error_const(error, DBUS_ERROR_INVALID_ARGS,
					     "invalid message format");
			return FALSE;
		}

		if (os_strcmp(entry.key, "DeviceName") == 0) {
			char *devname;

			if (entry.type != DBUS_TYPE_STRING)
				goto error;

			devname = os_strdup(entry.str_value);
			if (devname == NULL)
				goto err_no_mem_clear;

			os_free(wpa_s->conf->device_name);
			wpa_s->conf->device_name = devname;

			wpa_s->conf->changed_parameters |=
				CFG_CHANGED_DEVICE_NAME;
		} else if (os_strcmp(entry.key, "PrimaryDeviceType") == 0) {
			if (entry.type != DBUS_TYPE_ARRAY ||
			    entry.array_type != DBUS_TYPE_BYTE ||
			    entry.array_len != WPS_DEV_TYPE_LEN)
				goto error;

			os_memcpy(wpa_s->conf->device_type,
				  entry.bytearray_value,
				  WPS_DEV_TYPE_LEN);
			wpa_s->conf->changed_parameters |=
				CFG_CHANGED_DEVICE_TYPE;
		} else if (os_strcmp(entry.key, "SecondaryDeviceTypes") == 0) {
			if (entry.type != DBUS_TYPE_ARRAY ||
			    entry.array_type != WPAS_DBUS_TYPE_BINARRAY ||
			    entry.array_len > MAX_SEC_DEVICE_TYPES)
				goto error;

			for (i = 0; i < entry.array_len; i++)
				if (wpabuf_len(entry.binarray_value[i]) !=
				    WPS_DEV_TYPE_LEN)
					goto err_no_mem_clear;
			for (i = 0; i < entry.array_len; i++)
				os_memcpy(wpa_s->conf->sec_device_type[i],
					  wpabuf_head(entry.binarray_value[i]),
					  WPS_DEV_TYPE_LEN);
			wpa_s->conf->num_sec_device_types = entry.array_len;
			wpa_s->conf->changed_parameters |=
					CFG_CHANGED_SEC_DEVICE_TYPE;
		} else if (os_strcmp(entry.key, "VendorExtension") == 0) {
			if (entry.type != DBUS_TYPE_ARRAY ||
			    entry.array_type != WPAS_DBUS_TYPE_BINARRAY ||
			    (entry.array_len > P2P_MAX_WPS_VENDOR_EXT))
				goto error;

			wpa_s->conf->changed_parameters |=
				CFG_CHANGED_VENDOR_EXTENSION;

			for (i = 0; i < P2P_MAX_WPS_VENDOR_EXT; i++) {
				wpabuf_free(wpa_s->conf->wps_vendor_ext[i]);
				if (i < entry.array_len) {
					wpa_s->conf->wps_vendor_ext[i] =
						entry.binarray_value[i];
					entry.binarray_value[i] = NULL;
				} else
					wpa_s->conf->wps_vendor_ext[i] = NULL;
			}
		} else if (os_strcmp(entry.key, "GOIntent") == 0 &&
			   entry.type == DBUS_TYPE_UINT32 &&
			   (entry.uint32_value <= 15))
			wpa_s->conf->p2p_go_intent = entry.uint32_value;
		else if (os_strcmp(entry.key, "PersistentReconnect") == 0 &&
			 entry.type == DBUS_TYPE_BOOLEAN)
			wpa_s->conf->persistent_reconnect = entry.bool_value;
		else if (os_strcmp(entry.key, "ListenRegClass") == 0 &&
			 entry.type == DBUS_TYPE_UINT32) {
			wpa_s->conf->p2p_listen_reg_class = entry.uint32_value;
			wpa_s->conf->changed_parameters |=
				CFG_CHANGED_P2P_LISTEN_CHANNEL;
		} else if (os_strcmp(entry.key, "ListenChannel") == 0 &&
			   entry.type == DBUS_TYPE_UINT32) {
			wpa_s->conf->p2p_listen_channel = entry.uint32_value;
			wpa_s->conf->changed_parameters |=
				CFG_CHANGED_P2P_LISTEN_CHANNEL;
		} else if (os_strcmp(entry.key, "OperRegClass") == 0 &&
			   entry.type == DBUS_TYPE_UINT32) {
			wpa_s->conf->p2p_oper_reg_class = entry.uint32_value;
			wpa_s->conf->changed_parameters |=
				CFG_CHANGED_P2P_OPER_CHANNEL;
		} else if (os_strcmp(entry.key, "OperChannel") == 0 &&
			   entry.type == DBUS_TYPE_UINT32) {
			wpa_s->conf->p2p_oper_channel = entry.uint32_value;
			wpa_s->conf->changed_parameters |=
				CFG_CHANGED_P2P_OPER_CHANNEL;
		} else if (os_strcmp(entry.key, "SsidPostfix") == 0) {
			char *postfix;

			if (entry.type != DBUS_TYPE_STRING)
				goto error;

			postfix = os_strdup(entry.str_value);
			if (!postfix)
				goto err_no_mem_clear;

			os_free(wpa_s->conf->p2p_ssid_postfix);
			wpa_s->conf->p2p_ssid_postfix = postfix;

			wpa_s->conf->changed_parameters |=
					CFG_CHANGED_P2P_SSID_POSTFIX;
		} else if (os_strcmp(entry.key, "IntraBss") == 0 &&
			   entry.type == DBUS_TYPE_BOOLEAN) {
			wpa_s->conf->p2p_intra_bss = entry.bool_value;
			wpa_s->conf->changed_parameters |=
				CFG_CHANGED_P2P_INTRA_BSS;
		} else if (os_strcmp(entry.key, "GroupIdle") == 0 &&
			   entry.type == DBUS_TYPE_UINT32)
			wpa_s->conf->p2p_group_idle = entry.uint32_value;
		else if (os_strcmp(entry.key, "disassoc_low_ack") == 0 &&
			 entry.type == DBUS_TYPE_UINT32)
			wpa_s->conf->disassoc_low_ack = entry.uint32_value;
		else if (os_strcmp(entry.key, "NoGroupIface") == 0 &&
			 entry.type == DBUS_TYPE_BOOLEAN)
			wpa_s->conf->p2p_no_group_iface = entry.bool_value;
		else if (os_strcmp(entry.key, "p2p_search_delay") == 0 &&
			 entry.type == DBUS_TYPE_UINT32)
			wpa_s->conf->p2p_search_delay = entry.uint32_value;
		else
			goto error;

		wpa_dbus_dict_entry_clear(&entry);
	}

	if (wpa_s->conf->changed_parameters) {
		/* Some changed parameters requires to update config*/
		wpa_supplicant_update_config(wpa_s);
	}

	return TRUE;

 error:
	dbus_set_error_const(error, DBUS_ERROR_INVALID_ARGS,
			     "invalid message format");
	wpa_dbus_dict_entry_clear(&entry);
	return FALSE;

 err_no_mem_clear:
	dbus_set_error_const(error, DBUS_ERROR_NO_MEMORY, "no memory");
	wpa_dbus_dict_entry_clear(&entry);
	return FALSE;
}


dbus_bool_t wpas_dbus_getter_p2p_peers(DBusMessageIter *iter, DBusError *error,
				       void *user_data)
{
	struct wpa_supplicant *wpa_s = user_data;
	struct p2p_data *p2p = wpa_s->global->p2p;
	int next = 0, i = 0;
	int num = 0, out_of_mem = 0;
	const u8 *addr;
	const struct p2p_peer_info *peer_info = NULL;
	dbus_bool_t success = FALSE;

	struct dl_list peer_objpath_list;
	struct peer_objpath_node {
		struct dl_list list;
		char path[WPAS_DBUS_OBJECT_PATH_MAX];
	} *node, *tmp;

	char **peer_obj_paths = NULL;

	if (!wpa_dbus_p2p_check_enabled(wpa_s, NULL, NULL, error) ||
	    !wpa_s->parent->parent->dbus_new_path)
		return FALSE;

	dl_list_init(&peer_objpath_list);

	/* Get the first peer info */
	peer_info = p2p_get_peer_found(p2p, NULL, next);

	/* Get next and accumulate them */
	next = 1;
	while (peer_info != NULL) {
		node = os_zalloc(sizeof(struct peer_objpath_node));
		if (!node) {
			out_of_mem = 1;
			goto error;
		}

		addr = peer_info->p2p_device_addr;
		os_snprintf(node->path, WPAS_DBUS_OBJECT_PATH_MAX,
			    "%s/" WPAS_DBUS_NEW_P2P_PEERS_PART
			    "/" COMPACT_MACSTR,
			    wpa_s->parent->parent->dbus_new_path,
			    MAC2STR(addr));
		dl_list_add_tail(&peer_objpath_list, &node->list);
		num++;

		peer_info = p2p_get_peer_found(p2p, addr, next);
	}

	/*
	 * Now construct the peer object paths in a form suitable for
	 * array_property_getter helper below.
	 */
	peer_obj_paths = os_calloc(num, sizeof(char *));

	if (!peer_obj_paths) {
		out_of_mem = 1;
		goto error;
	}

	dl_list_for_each_safe(node, tmp, &peer_objpath_list,
			      struct peer_objpath_node, list)
		peer_obj_paths[i++] = node->path;

	success = wpas_dbus_simple_array_property_getter(iter,
							 DBUS_TYPE_OBJECT_PATH,
							 peer_obj_paths, num,
							 error);

error:
	if (peer_obj_paths)
		os_free(peer_obj_paths);

	dl_list_for_each_safe(node, tmp, &peer_objpath_list,
			      struct peer_objpath_node, list) {
		dl_list_del(&node->list);
		os_free(node);
	}
	if (out_of_mem)
		dbus_set_error_const(error, DBUS_ERROR_NO_MEMORY, "no memory");

	return success;
}


enum wpas_p2p_role {
	WPAS_P2P_ROLE_DEVICE,
	WPAS_P2P_ROLE_GO,
	WPAS_P2P_ROLE_CLIENT,
};

static enum wpas_p2p_role wpas_get_p2p_role(struct wpa_supplicant *wpa_s)
{
	struct wpa_ssid *ssid = wpa_s->current_ssid;

	if (!ssid)
		return WPAS_P2P_ROLE_DEVICE;
	if (wpa_s->wpa_state != WPA_COMPLETED)
		return WPAS_P2P_ROLE_DEVICE;

	switch (ssid->mode) {
	case WPAS_MODE_P2P_GO:
	case WPAS_MODE_P2P_GROUP_FORMATION:
		return WPAS_P2P_ROLE_GO;
	case WPAS_MODE_INFRA:
		if (ssid->p2p_group)
			return WPAS_P2P_ROLE_CLIENT;
		return WPAS_P2P_ROLE_DEVICE;
	default:
		return WPAS_P2P_ROLE_DEVICE;
	}
}


dbus_bool_t wpas_dbus_getter_p2p_role(DBusMessageIter *iter, DBusError *error,
				      void *user_data)
{
	struct wpa_supplicant *wpa_s = user_data;
	char *str;

	switch (wpas_get_p2p_role(wpa_s)) {
	case WPAS_P2P_ROLE_GO:
		str = "GO";
		break;
	case WPAS_P2P_ROLE_CLIENT:
		str = "client";
		break;
	default:
		str = "device";
		break;
	}

	return wpas_dbus_simple_property_getter(iter, DBUS_TYPE_STRING, &str,
						error);
}


dbus_bool_t wpas_dbus_getter_p2p_group(DBusMessageIter *iter, DBusError *error,
				       void *user_data)
{
	struct wpa_supplicant *wpa_s = user_data;
	char path_buf[WPAS_DBUS_OBJECT_PATH_MAX];
	char *dbus_groupobj_path = path_buf;

	if (wpa_s->dbus_groupobj_path == NULL)
		os_snprintf(dbus_groupobj_path, WPAS_DBUS_OBJECT_PATH_MAX,
			    "/");
	else
		os_snprintf(dbus_groupobj_path, WPAS_DBUS_OBJECT_PATH_MAX,
			    "%s", wpa_s->dbus_groupobj_path);

	return wpas_dbus_simple_property_getter(iter, DBUS_TYPE_OBJECT_PATH,
						&dbus_groupobj_path, error);
}


dbus_bool_t wpas_dbus_getter_p2p_peergo(DBusMessageIter *iter,
					DBusError *error, void *user_data)
{
	struct wpa_supplicant *wpa_s = user_data;
	char go_peer_obj_path[WPAS_DBUS_OBJECT_PATH_MAX], *path;

	if (!wpa_s->parent->parent->dbus_new_path)
		return FALSE;

	if (wpas_get_p2p_role(wpa_s) != WPAS_P2P_ROLE_CLIENT)
		os_snprintf(go_peer_obj_path, WPAS_DBUS_OBJECT_PATH_MAX, "/");
	else
		os_snprintf(go_peer_obj_path, WPAS_DBUS_OBJECT_PATH_MAX,
			    "%s/" WPAS_DBUS_NEW_P2P_PEERS_PART "/"
			    COMPACT_MACSTR,
			    wpa_s->parent->parent->dbus_new_path,
			    MAC2STR(wpa_s->go_dev_addr));

	path = go_peer_obj_path;
	return wpas_dbus_simple_property_getter(iter, DBUS_TYPE_OBJECT_PATH,
						&path, error);
}


/*
 * Peer object properties accessor methods
 */

dbus_bool_t wpas_dbus_getter_p2p_peer_device_name(DBusMessageIter *iter,
						  DBusError *error,
						  void *user_data)
{
	struct peer_handler_args *peer_args = user_data;
	const struct p2p_peer_info *info;
	char *tmp;

	if (!wpa_dbus_p2p_check_enabled(peer_args->wpa_s, NULL, NULL, error))
		return FALSE;

	/* get the peer info */
	info = p2p_get_peer_found(peer_args->wpa_s->global->p2p,
				  peer_args->p2p_device_addr, 0);
	if (info == NULL) {
		dbus_set_error(error, DBUS_ERROR_FAILED,
			       "failed to find peer");
		return FALSE;
	}

	tmp = os_strdup(info->device_name);
	if (!tmp) {
		dbus_set_error_const(error, DBUS_ERROR_NO_MEMORY, "no memory");
		return FALSE;
	}

	if (!wpas_dbus_simple_property_getter(iter, DBUS_TYPE_STRING, &tmp,
					      error)) {
		dbus_set_error_const(error, DBUS_ERROR_NO_MEMORY, "no memory");
		os_free(tmp);
		return FALSE;
	}

	os_free(tmp);
	return TRUE;
}


dbus_bool_t wpas_dbus_getter_p2p_peer_primary_device_type(
	DBusMessageIter *iter, DBusError *error, void *user_data)
{
	struct peer_handler_args *peer_args = user_data;
	const struct p2p_peer_info *info;

	info = p2p_get_peer_found(peer_args->wpa_s->global->p2p,
				  peer_args->p2p_device_addr, 0);
	if (info == NULL) {
		dbus_set_error(error, DBUS_ERROR_FAILED,
			       "failed to find peer");
		return FALSE;
	}

	if (!wpas_dbus_simple_array_property_getter(iter, DBUS_TYPE_BYTE,
						    (char *)
						    info->pri_dev_type,
						    WPS_DEV_TYPE_LEN, error)) {
		dbus_set_error_const(error, DBUS_ERROR_NO_MEMORY, "no memory");
		return FALSE;
	}

	return TRUE;
}


dbus_bool_t wpas_dbus_getter_p2p_peer_config_method(DBusMessageIter *iter,
						    DBusError *error,
						    void *user_data)
{
	struct peer_handler_args *peer_args = user_data;
	const struct p2p_peer_info *info;

	info = p2p_get_peer_found(peer_args->wpa_s->global->p2p,
				  peer_args->p2p_device_addr, 0);
	if (info == NULL) {
		dbus_set_error(error, DBUS_ERROR_FAILED,
			       "failed to find peer");
		return FALSE;
	}

	if (!wpas_dbus_simple_property_getter(iter, DBUS_TYPE_UINT16,
					      &info->config_methods, error)) {
		dbus_set_error_const(error, DBUS_ERROR_NO_MEMORY, "no memory");
		return FALSE;
	}

	return TRUE;
}


dbus_bool_t wpas_dbus_getter_p2p_peer_level(DBusMessageIter *iter,
					    DBusError *error,
					    void *user_data)
{
	struct peer_handler_args *peer_args = user_data;
	const struct p2p_peer_info *info;

	info = p2p_get_peer_found(peer_args->wpa_s->global->p2p,
				  peer_args->p2p_device_addr, 0);
	if (info == NULL) {
		dbus_set_error(error, DBUS_ERROR_FAILED,
			       "failed to find peer");
		return FALSE;
	}

	if (!wpas_dbus_simple_property_getter(iter, DBUS_TYPE_INT32,
					      &info->level, error)) {
		dbus_set_error_const(error, DBUS_ERROR_NO_MEMORY, "no memory");
		return FALSE;
	}

	return TRUE;
}


dbus_bool_t wpas_dbus_getter_p2p_peer_device_capability(DBusMessageIter *iter,
							DBusError *error,
							void *user_data)
{
	struct peer_handler_args *peer_args = user_data;
	const struct p2p_peer_info *info;

	info = p2p_get_peer_found(peer_args->wpa_s->global->p2p,
				  peer_args->p2p_device_addr, 0);
	if (info == NULL) {
		dbus_set_error(error, DBUS_ERROR_FAILED,
			       "failed to find peer");
		return FALSE;
	}

	if (!wpas_dbus_simple_property_getter(iter, DBUS_TYPE_BYTE,
					      &info->dev_capab, error)) {
		dbus_set_error_const(error, DBUS_ERROR_NO_MEMORY, "no memory");
		return FALSE;
	}

	return TRUE;
}


dbus_bool_t wpas_dbus_getter_p2p_peer_group_capability(DBusMessageIter *iter,
						       DBusError *error,
						       void *user_data)
{
	struct peer_handler_args *peer_args = user_data;
	const struct p2p_peer_info *info;

	info = p2p_get_peer_found(peer_args->wpa_s->global->p2p,
				  peer_args->p2p_device_addr, 0);
	if (info == NULL) {
		dbus_set_error(error, DBUS_ERROR_FAILED,
			       "failed to find peer");
		return FALSE;
	}

	if (!wpas_dbus_simple_property_getter(iter, DBUS_TYPE_BYTE,
					      &info->group_capab, error)) {
		dbus_set_error_const(error, DBUS_ERROR_NO_MEMORY, "no memory");
		return FALSE;
	}

	return TRUE;
}


dbus_bool_t wpas_dbus_getter_p2p_peer_secondary_device_types(
	DBusMessageIter *iter, DBusError *error, void *user_data)
{
	struct peer_handler_args *peer_args = user_data;
	const struct p2p_peer_info *info;
	DBusMessageIter variant_iter, array_iter;

	info = p2p_get_peer_found(peer_args->wpa_s->global->p2p,
				  peer_args->p2p_device_addr, 0);
	if (info == NULL) {
		dbus_set_error(error, DBUS_ERROR_FAILED, "failed to find peer");
		return FALSE;
	}

	if (!dbus_message_iter_open_container(iter, DBUS_TYPE_VARIANT,
					      DBUS_TYPE_ARRAY_AS_STRING
					      DBUS_TYPE_ARRAY_AS_STRING
					      DBUS_TYPE_BYTE_AS_STRING,
					      &variant_iter) ||
	    !dbus_message_iter_open_container(&variant_iter, DBUS_TYPE_ARRAY,
					      DBUS_TYPE_ARRAY_AS_STRING
					      DBUS_TYPE_BYTE_AS_STRING,
					      &array_iter)) {
		dbus_set_error(error, DBUS_ERROR_FAILED,
			       "%s: failed to construct message 1", __func__);
		return FALSE;
	}

	if (info->wps_sec_dev_type_list_len) {
		const u8 *sec_dev_type_list = info->wps_sec_dev_type_list;
		int num_sec_device_types =
			info->wps_sec_dev_type_list_len / WPS_DEV_TYPE_LEN;
		int i;
		DBusMessageIter inner_array_iter;

		for (i = 0; i < num_sec_device_types; i++) {
			if (!dbus_message_iter_open_container(
				    &array_iter, DBUS_TYPE_ARRAY,
				    DBUS_TYPE_BYTE_AS_STRING,
				    &inner_array_iter) ||
			    !dbus_message_iter_append_fixed_array(
				    &inner_array_iter, DBUS_TYPE_BYTE,
				    &sec_dev_type_list, WPS_DEV_TYPE_LEN) ||
			    !dbus_message_iter_close_container(
				    &array_iter, &inner_array_iter)) {
				dbus_set_error(error, DBUS_ERROR_FAILED,
					       "%s: failed to construct message 2 (%d)",
					       __func__, i);
				return FALSE;
			}

			sec_dev_type_list += WPS_DEV_TYPE_LEN;
		}
	}

	if (!dbus_message_iter_close_container(&variant_iter, &array_iter) ||
	    !dbus_message_iter_close_container(iter, &variant_iter)) {
		dbus_set_error(error, DBUS_ERROR_FAILED,
			       "%s: failed to construct message 3", __func__);
		return FALSE;
	}

	return TRUE;
}


dbus_bool_t wpas_dbus_getter_p2p_peer_vendor_extension(DBusMessageIter *iter,
						       DBusError *error,
						       void *user_data)
{
	struct wpabuf *vendor_extension[P2P_MAX_WPS_VENDOR_EXT];
	unsigned int i, num = 0;
	struct peer_handler_args *peer_args = user_data;
	const struct p2p_peer_info *info;

	info = p2p_get_peer_found(peer_args->wpa_s->global->p2p,
				  peer_args->p2p_device_addr, 0);
	if (info == NULL) {
		dbus_set_error(error, DBUS_ERROR_FAILED,
			       "failed to find peer");
		return FALSE;
	}

	/* Add WPS vendor extensions attribute */
	os_memset(vendor_extension, 0, sizeof(vendor_extension));
	for (i = 0; i < P2P_MAX_WPS_VENDOR_EXT; i++) {
		if (info->wps_vendor_ext[i] == NULL)
			continue;
		vendor_extension[num] = info->wps_vendor_ext[i];
		num++;
	}

	if (!wpas_dbus_simple_array_array_property_getter(iter, DBUS_TYPE_BYTE,
							  vendor_extension,
							  num, error))
		return FALSE;

	return TRUE;
}


dbus_bool_t wpas_dbus_getter_p2p_peer_ies(DBusMessageIter *iter,
					  DBusError *error, void *user_data)
{
	struct peer_handler_args *peer_args = user_data;
	const struct p2p_peer_info *info;

	info = p2p_get_peer_found(peer_args->wpa_s->global->p2p,
				  peer_args->p2p_device_addr, 0);
	if (info == NULL) {
		dbus_set_error(error, DBUS_ERROR_FAILED,
			       "failed to find peer");
		return FALSE;
	}

	if (info->wfd_subelems == NULL)
		return wpas_dbus_simple_array_property_getter(iter,
							      DBUS_TYPE_BYTE,
							      NULL, 0, error);

	return wpas_dbus_simple_array_property_getter(
		iter, DBUS_TYPE_BYTE, (char *) info->wfd_subelems->buf,
		info->wfd_subelems->used, error);
}


dbus_bool_t wpas_dbus_getter_p2p_peer_device_address(DBusMessageIter *iter,
						     DBusError *error,
						     void *user_data)
{
	struct peer_handler_args *peer_args = user_data;
	const struct p2p_peer_info *info;

	info = p2p_get_peer_found(peer_args->wpa_s->global->p2p,
				  peer_args->p2p_device_addr, 0);
	if (info == NULL) {
		dbus_set_error(error, DBUS_ERROR_FAILED,
			       "failed to find peer");
		return FALSE;
	}

	return wpas_dbus_simple_array_property_getter(
		iter, DBUS_TYPE_BYTE, (char *) info->p2p_device_addr,
		ETH_ALEN, error);
}


struct peer_group_data {
	struct wpa_supplicant *wpa_s;
	const struct p2p_peer_info *info;
	char **paths;
	unsigned int nb_paths;
	int error;
};


static int match_group_where_peer_is_client(struct p2p_group *group,
					    void *user_data)
{
	struct peer_group_data *data = user_data;
	const struct p2p_group_config *cfg;
	struct wpa_supplicant *wpa_s_go;
	char **paths;

	if (!p2p_group_is_client_connected(group, data->info->p2p_device_addr))
		return 1;

	cfg = p2p_group_get_config(group);

	wpa_s_go = wpas_get_p2p_go_iface(data->wpa_s, cfg->ssid,
					 cfg->ssid_len);
	if (wpa_s_go == NULL)
		return 1;

	paths = os_realloc_array(data->paths, data->nb_paths + 1,
				 sizeof(char *));
	if (paths == NULL)
		goto out_of_memory;

	data->paths = paths;
	data->paths[data->nb_paths] = wpa_s_go->dbus_groupobj_path;
	data->nb_paths++;

	return 1;

out_of_memory:
	data->error = ENOMEM;
	return 0;
}


dbus_bool_t wpas_dbus_getter_p2p_peer_groups(DBusMessageIter *iter,
					     DBusError *error,
					     void *user_data)
{
	struct peer_handler_args *peer_args = user_data;
	const struct p2p_peer_info *info;
	struct peer_group_data data;
	struct wpa_supplicant *wpa_s, *wpa_s_go;
	dbus_bool_t success = FALSE;

	info = p2p_get_peer_found(peer_args->wpa_s->global->p2p,
				  peer_args->p2p_device_addr, 0);
	if (info == NULL) {
		dbus_set_error(error, DBUS_ERROR_FAILED,
			       "failed to find peer");
		return FALSE;
	}

	os_memset(&data, 0, sizeof(data));

	wpa_s = peer_args->wpa_s;
	if (wpa_s->p2p_dev)
		wpa_s = wpa_s->p2p_dev;

	wpa_s_go = wpas_get_p2p_client_iface(wpa_s, info->p2p_device_addr);
	if (wpa_s_go) {
		data.paths = os_calloc(1, sizeof(char *));
		if (data.paths == NULL)
			goto out_of_memory;
		data.paths[0] = wpa_s_go->dbus_groupobj_path;
		data.nb_paths = 1;
	}

	data.wpa_s = peer_args->wpa_s;
	data.info = info;

	p2p_loop_on_all_groups(peer_args->wpa_s->global->p2p,
			       match_group_where_peer_is_client, &data);
	if (data.error)
		goto out_of_memory;

	if (data.paths == NULL) {
		return wpas_dbus_simple_array_property_getter(
			iter, DBUS_TYPE_OBJECT_PATH, NULL, 0, error);
	}

	success = wpas_dbus_simple_array_property_getter(iter,
							 DBUS_TYPE_OBJECT_PATH,
							 data.paths,
							 data.nb_paths, error);
	goto out;

out_of_memory:
	dbus_set_error_const(error, DBUS_ERROR_NO_MEMORY, "no memory");
out:
	os_free(data.paths);
	return success;
}


/**
 * wpas_dbus_getter_persistent_groups - Get array of persistent group objects
 * @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 "PersistentGroups" property.
 */
dbus_bool_t wpas_dbus_getter_persistent_groups(DBusMessageIter *iter,
					       DBusError *error,
					       void *user_data)
{
	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->p2p_dev)
		wpa_s = wpa_s->p2p_dev;
	if (!wpa_s->parent->dbus_new_path)
		return FALSE;

	for (ssid = wpa_s->conf->ssid; ssid; ssid = ssid->next)
		if (network_is_persistent_group(ssid))
			num++;

	paths = os_calloc(num, sizeof(char *));
	if (!paths) {
		dbus_set_error_const(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) {
		if (!network_is_persistent_group(ssid))
			continue;
		paths[i] = os_zalloc(WPAS_DBUS_OBJECT_PATH_MAX);
		if (paths[i] == NULL) {
			dbus_set_error_const(error, DBUS_ERROR_NO_MEMORY,
					     "no memory");
			goto out;
		}
		/* Construct the object path for this network. */
		os_snprintf(paths[i++], WPAS_DBUS_OBJECT_PATH_MAX,
			    "%s/" WPAS_DBUS_NEW_PERSISTENT_GROUPS_PART "/%d",
			    wpa_s->parent->dbus_new_path, ssid->id);
	}

	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 success;
}


/**
 * wpas_dbus_getter_persistent_group_properties - Get options for a persistent
 *	group
 * @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 persistent group.
 */
dbus_bool_t wpas_dbus_getter_persistent_group_properties(DBusMessageIter *iter,
							 DBusError *error,
							 void *user_data)
{
	struct network_handler_args *net = user_data;

	/* Leveraging the fact that persistent group object is still
	 * represented in same manner as network within.
	 */
	return wpas_dbus_getter_network_properties(iter, error, net);
}


/**
 * wpas_dbus_setter_persistent_group_properties - Get options for a persistent
 *	group
 * @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 persistent group.
 */
dbus_bool_t wpas_dbus_setter_persistent_group_properties(DBusMessageIter *iter,
							 DBusError *error,
							 void *user_data)
{
	struct network_handler_args *net = user_data;
	struct wpa_ssid *ssid = net->ssid;
	DBusMessageIter	variant_iter;

	/*
	 * Leveraging the fact that persistent group object is still
	 * represented in same manner as network within.
	 */
	dbus_message_iter_recurse(iter, &variant_iter);
	return set_network_properties(net->wpa_s, ssid, &variant_iter, error);
}


/**
 * wpas_dbus_new_iface_add_persistent_group - Add a new configured
 *	persistent_group
 * @message: Pointer to incoming dbus message
 * @wpa_s: wpa_supplicant structure for a network interface
 * Returns: A dbus message containing the object path of the new
 * persistent group
 *
 * Handler function for "AddPersistentGroup" method call of a P2P Device
 * interface.
 */
DBusMessage * wpas_dbus_handler_add_persistent_group(
	DBusMessage *message, struct wpa_supplicant *wpa_s)
{
	DBusMessage *reply = NULL;
	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);

	if (wpa_s->p2p_dev)
		wpa_s = wpa_s->p2p_dev;
	if (wpa_s->parent->dbus_new_path)
		ssid = wpa_config_add_network(wpa_s->conf);
	if (ssid == NULL) {
		wpa_printf(MSG_ERROR,
			   "dbus: %s: Cannot add new persistent group",
			   __func__);
		reply = wpas_dbus_error_unknown_error(
			message,
			"wpa_supplicant could not add a persistent group on this interface.");
		goto err;
	}

	/* Mark the ssid as being a persistent group before the notification */
	ssid->disabled = 2;
	ssid->p2p_persistent_group = 1;
	wpas_notify_persistent_group_added(wpa_s, ssid);

	wpa_config_set_network_defaults(ssid);

	dbus_error_init(&error);
	if (!set_network_properties(wpa_s, ssid, &iter, &error)) {
		wpa_printf(MSG_DEBUG,
			   "dbus: %s: Control interface could not set persistent group properties",
			   __func__);
		reply = wpas_dbus_reply_new_from_error(
			message, &error, DBUS_ERROR_INVALID_ARGS,
			"Failed to set network properties");
		dbus_error_free(&error);
		goto err;
	}

	/* Construct the object path for this network. */
	os_snprintf(path, WPAS_DBUS_OBJECT_PATH_MAX,
		    "%s/" WPAS_DBUS_NEW_PERSISTENT_GROUPS_PART "/%d",
		    wpa_s->parent->dbus_new_path, ssid->id);

	reply = dbus_message_new_method_return(message);
	if (reply == NULL) {
		reply = wpas_dbus_error_no_memory(message);
		goto err;
	}
	if (!dbus_message_append_args(reply, DBUS_TYPE_OBJECT_PATH, &path,
				      DBUS_TYPE_INVALID)) {
		dbus_message_unref(reply);
		reply = wpas_dbus_error_no_memory(message);
		goto err;
	}

	return reply;

err:
	if (ssid) {
		wpas_notify_persistent_group_removed(wpa_s, ssid);
		wpa_config_remove_network(wpa_s->conf, ssid->id);
	}
	return reply;
}


/**
 * wpas_dbus_handler_remove_persistent_group - Remove a configured persistent
 *	group
 * @message: Pointer to incoming dbus message
 * @wpa_s: wpa_supplicant structure for a network interface
 * Returns: NULL on success or dbus error on failure
 *
 * Handler function for "RemovePersistentGroup" method call of a P2P Device
 * interface.
 */
DBusMessage * wpas_dbus_handler_remove_persistent_group(
	DBusMessage *message, struct wpa_supplicant *wpa_s)
{
	DBusMessage *reply = NULL;
	const char *op;
	char *iface = NULL, *persistent_group_id;
	int id;
	struct wpa_ssid *ssid;

	dbus_message_get_args(message, NULL, DBUS_TYPE_OBJECT_PATH, &op,
			      DBUS_TYPE_INVALID);

	if (wpa_s->p2p_dev)
		wpa_s = wpa_s->p2p_dev;

	/*
	 * Extract the network ID and ensure the network is actually a child of
	 * this interface.
	 */
	iface = wpas_dbus_new_decompose_object_path(
		op, WPAS_DBUS_NEW_PERSISTENT_GROUPS_PART,
		&persistent_group_id);
	if (iface == NULL || persistent_group_id == NULL ||
	    !wpa_s->parent->dbus_new_path ||
	    os_strcmp(iface, wpa_s->parent->dbus_new_path) != 0) {
		reply = wpas_dbus_error_invalid_args(message, op);
		goto out;
	}

	id = strtoul(persistent_group_id, NULL, 10);
	if (errno == EINVAL) {
		reply = wpas_dbus_error_invalid_args(message, op);
		goto out;
	}

	ssid = wpa_config_get_network(wpa_s->conf, id);
	if (ssid == NULL) {
		reply = wpas_dbus_error_persistent_group_unknown(message);
		goto out;
	}

	wpas_notify_persistent_group_removed(wpa_s, ssid);

	if (wpa_config_remove_network(wpa_s->conf, id) < 0) {
		wpa_printf(MSG_ERROR,
			   "dbus: %s: error occurred when removing persistent group %d",
			   __func__, id);
		reply = wpas_dbus_error_unknown_error(
			message,
			"error removing the specified persistent group on this interface.");
		goto out;
	}

out:
	os_free(iface);
	return reply;
}


static void remove_persistent_group(struct wpa_supplicant *wpa_s,
				    struct wpa_ssid *ssid)
{
	wpas_notify_persistent_group_removed(wpa_s, ssid);

	if (wpa_config_remove_network(wpa_s->conf, ssid->id) < 0) {
		wpa_printf(MSG_ERROR,
			   "dbus: %s: error occurred when removing persistent group %d",
			   __func__, ssid->id);
		return;
	}
}


/**
 * wpas_dbus_handler_remove_all_persistent_groups - Remove all configured
 * persistent groups
 * @message: Pointer to incoming dbus message
 * @wpa_s: wpa_supplicant structure for a network interface
 * Returns: NULL on success or dbus error on failure
 *
 * Handler function for "RemoveAllPersistentGroups" method call of a
 * P2P Device interface.
 */
DBusMessage * wpas_dbus_handler_remove_all_persistent_groups(
	DBusMessage *message, struct wpa_supplicant *wpa_s)
{
	struct wpa_ssid *ssid, *next;
	struct wpa_config *config;

	if (wpa_s->p2p_dev)
		wpa_s = wpa_s->p2p_dev;
	config = wpa_s->conf;
	ssid = config->ssid;
	while (ssid) {
		next = ssid->next;
		if (network_is_persistent_group(ssid))
			remove_persistent_group(wpa_s, ssid);
		ssid = next;
	}
	return NULL;
}


/*
 * Group object properties accessor methods
 */

dbus_bool_t wpas_dbus_getter_p2p_group_members(DBusMessageIter *iter,
					       DBusError *error,
					       void *user_data)
{
	struct wpa_supplicant *wpa_s = user_data;
	struct wpa_ssid *ssid;
	unsigned int num_members;
	char **paths;
	unsigned int i;
	void *next = NULL;
	const u8 *addr;
	dbus_bool_t success = FALSE;

	if (!wpa_s->parent->parent->dbus_new_path)
		return FALSE;

	/* Verify correct role for this property */
	if (wpas_get_p2p_role(wpa_s) != WPAS_P2P_ROLE_GO) {
		return wpas_dbus_simple_array_property_getter(
			iter, DBUS_TYPE_OBJECT_PATH, NULL, 0, error);
	}

	ssid = wpa_s->conf->ssid;
	/* At present WPAS P2P_GO mode only applicable for p2p_go */
	if (ssid->mode != WPAS_MODE_P2P_GO &&
	    ssid->mode != WPAS_MODE_AP &&
	    ssid->mode != WPAS_MODE_P2P_GROUP_FORMATION)
		return FALSE;

	num_members = p2p_get_group_num_members(wpa_s->p2p_group);

	paths = os_calloc(num_members, sizeof(char *));
	if (!paths)
		goto out_of_memory;

	i = 0;
	while ((addr = p2p_iterate_group_members(wpa_s->p2p_group, &next))) {
		paths[i] = os_zalloc(WPAS_DBUS_OBJECT_PATH_MAX);
		if (!paths[i])
			goto out_of_memory;
		os_snprintf(paths[i], WPAS_DBUS_OBJECT_PATH_MAX,
			    "%s/" WPAS_DBUS_NEW_P2P_PEERS_PART
			    "/" COMPACT_MACSTR,
			    wpa_s->parent->parent->dbus_new_path,
			    MAC2STR(addr));
		i++;
	}

	success = wpas_dbus_simple_array_property_getter(iter,
							 DBUS_TYPE_OBJECT_PATH,
							 paths, num_members,
							 error);

	for (i = 0; i < num_members; i++)
		os_free(paths[i]);
	os_free(paths);
	return success;

out_of_memory:
	dbus_set_error_const(error, DBUS_ERROR_NO_MEMORY, "no memory");
	if (paths) {
		for (i = 0; i < num_members; i++)
			os_free(paths[i]);
		os_free(paths);
	}
	return FALSE;
}


dbus_bool_t wpas_dbus_getter_p2p_group_ssid(DBusMessageIter *iter,
					    DBusError *error, void *user_data)
{
	struct wpa_supplicant *wpa_s = user_data;

	if (wpa_s->current_ssid == NULL)
		return FALSE;
	return wpas_dbus_simple_array_property_getter(
		iter, DBUS_TYPE_BYTE, wpa_s->current_ssid->ssid,
		wpa_s->current_ssid->ssid_len, error);
}


dbus_bool_t wpas_dbus_getter_p2p_group_bssid(DBusMessageIter *iter,
					     DBusError *error,
					     void *user_data)
{
	struct wpa_supplicant *wpa_s = user_data;
	u8 role = wpas_get_p2p_role(wpa_s);
	u8 *p_bssid;

	if (role == WPAS_P2P_ROLE_CLIENT) {
		if (wpa_s->current_ssid == NULL)
			return FALSE;
		p_bssid = wpa_s->current_ssid->bssid;
	} else {
		if (wpa_s->ap_iface == NULL)
			return FALSE;
		p_bssid = wpa_s->ap_iface->bss[0]->own_addr;
	}

	return wpas_dbus_simple_array_property_getter(iter, DBUS_TYPE_BYTE,
						      p_bssid, ETH_ALEN,
						      error);
}


dbus_bool_t wpas_dbus_getter_p2p_group_frequency(DBusMessageIter *iter,
						 DBusError *error,
						 void *user_data)
{
	struct wpa_supplicant *wpa_s = user_data;
	u16 op_freq;
	u8 role = wpas_get_p2p_role(wpa_s);

	if (role == WPAS_P2P_ROLE_CLIENT) {
		if (wpa_s->go_params == NULL)
			return FALSE;
		op_freq = wpa_s->go_params->freq;
	} else {
		if (wpa_s->ap_iface == NULL)
			return FALSE;
		op_freq = wpa_s->ap_iface->freq;
	}

	return wpas_dbus_simple_property_getter(iter, DBUS_TYPE_UINT16,
						&op_freq, error);
}


dbus_bool_t wpas_dbus_getter_p2p_group_passphrase(DBusMessageIter *iter,
						  DBusError *error,
						  void *user_data)
{
	struct wpa_supplicant *wpa_s = user_data;
	char *p_pass;
	struct wpa_ssid *ssid = wpa_s->current_ssid;

	if (ssid == NULL)
		return FALSE;

	p_pass = ssid->passphrase;
	if (!p_pass)
		p_pass = "";

	return wpas_dbus_simple_property_getter(iter, DBUS_TYPE_STRING,
						&p_pass, error);

}


dbus_bool_t wpas_dbus_getter_p2p_group_psk(DBusMessageIter *iter,
					   DBusError *error, void *user_data)
{
	struct wpa_supplicant *wpa_s = user_data;
	u8 *p_psk = NULL;
	u8 psk_len = 0;
	struct wpa_ssid *ssid = wpa_s->current_ssid;

	if (ssid == NULL)
		return FALSE;

	if (ssid->psk_set) {
		p_psk = ssid->psk;
		psk_len = sizeof(ssid->psk);
	}

	return wpas_dbus_simple_array_property_getter(iter, DBUS_TYPE_BYTE,
						      p_psk, psk_len, error);
}


dbus_bool_t wpas_dbus_getter_p2p_group_vendor_ext(DBusMessageIter *iter,
						  DBusError *error,
						  void *user_data)
{
	struct wpa_supplicant *wpa_s = user_data;
	struct hostapd_data *hapd;
	struct wpabuf *vendor_ext[MAX_WPS_VENDOR_EXTENSIONS];
	unsigned int i, num_vendor_ext = 0;

	os_memset(vendor_ext, 0, sizeof(vendor_ext));

	/* Verify correct role for this property */
	if (wpas_get_p2p_role(wpa_s) == WPAS_P2P_ROLE_GO) {
		if (wpa_s->ap_iface == NULL)
			return FALSE;
		hapd = wpa_s->ap_iface->bss[0];

		/* Parse WPS Vendor Extensions sent in Beacon/Probe Response */
		for (i = 0; i < MAX_WPS_VENDOR_EXTENSIONS; i++) {
			if (hapd->conf->wps_vendor_ext[i] == NULL)
				continue;
			vendor_ext[num_vendor_ext++] =
				hapd->conf->wps_vendor_ext[i];
		}
	}

	/* Return vendor extensions or no data */
	return wpas_dbus_simple_array_array_property_getter(iter,
							    DBUS_TYPE_BYTE,
							    vendor_ext,
							    num_vendor_ext,
							    error);
}


dbus_bool_t wpas_dbus_setter_p2p_group_vendor_ext(DBusMessageIter *iter,
						  DBusError *error,
						  void *user_data)
{
	struct wpa_supplicant *wpa_s = user_data;
	DBusMessageIter variant_iter, iter_dict, array_iter, sub;
	struct wpa_dbus_dict_entry entry = { .type = DBUS_TYPE_STRING };
	unsigned int i;
	struct hostapd_data *hapd = NULL;

	if (wpas_get_p2p_role(wpa_s) == WPAS_P2P_ROLE_GO &&
	    wpa_s->ap_iface != NULL)
		hapd = wpa_s->ap_iface->bss[0];
	else
		return FALSE;

	dbus_message_iter_recurse(iter, &variant_iter);
	if (dbus_message_iter_get_arg_type(&variant_iter) != DBUS_TYPE_ARRAY)
		return FALSE;

	/*
	 * This is supposed to be array of bytearrays (aay), but the earlier
	 * implementation used a dict with "WPSVendorExtensions" as the key in
	 * this setter function which does not match the format used by the
	 * getter function. For backwards compatibility, allow both formats to
	 * be used in the setter.
	 */
	if (dbus_message_iter_get_element_type(&variant_iter) ==
	    DBUS_TYPE_ARRAY) {
		/* This is the proper format matching the getter */
		struct wpabuf *vals[MAX_WPS_VENDOR_EXTENSIONS];

		dbus_message_iter_recurse(&variant_iter, &array_iter);

		if (dbus_message_iter_get_arg_type(&array_iter) !=
		    DBUS_TYPE_ARRAY ||
		    dbus_message_iter_get_element_type(&array_iter) !=
		    DBUS_TYPE_BYTE) {
			wpa_printf(MSG_DEBUG,
				   "dbus: Not an array of array of bytes");
			return FALSE;
		}

		i = 0;
		os_memset(vals, 0, sizeof(vals));

		while (dbus_message_iter_get_arg_type(&array_iter) ==
		       DBUS_TYPE_ARRAY) {
			char *val;
			int len;

			if (i == MAX_WPS_VENDOR_EXTENSIONS) {
				wpa_printf(MSG_DEBUG,
					   "dbus: Too many WPSVendorExtensions values");
				i = MAX_WPS_VENDOR_EXTENSIONS + 1;
				break;
			}

			dbus_message_iter_recurse(&array_iter, &sub);
			dbus_message_iter_get_fixed_array(&sub, &val, &len);
			wpa_hexdump(MSG_DEBUG, "dbus: WPSVendorExtentions[]",
				    val, len);
			vals[i] = wpabuf_alloc_copy(val, len);
			if (vals[i] == NULL) {
				i = MAX_WPS_VENDOR_EXTENSIONS + 1;
				break;
			}
			i++;
			dbus_message_iter_next(&array_iter);
		}

		if (i > MAX_WPS_VENDOR_EXTENSIONS) {
			for (i = 0; i < MAX_WPS_VENDOR_EXTENSIONS; i++)
				wpabuf_free(vals[i]);
			return FALSE;
		}

		for (i = 0; i < MAX_WPS_VENDOR_EXTENSIONS; i++) {
			wpabuf_free(hapd->conf->wps_vendor_ext[i]);
			hapd->conf->wps_vendor_ext[i] = vals[i];
		}

		hostapd_update_wps(hapd);

		return TRUE;
	}

	if (dbus_message_iter_get_element_type(&variant_iter) !=
	    DBUS_TYPE_DICT_ENTRY)
		return FALSE;

	wpa_printf(MSG_DEBUG,
		   "dbus: Try to use backwards compatibility version of WPSVendorExtensions setter");
	if (!wpa_dbus_dict_open_read(&variant_iter, &iter_dict, error))
		return FALSE;

	while (wpa_dbus_dict_has_dict_entry(&iter_dict)) {
		if (!wpa_dbus_dict_get_entry(&iter_dict, &entry)) {
			dbus_set_error_const(error, DBUS_ERROR_INVALID_ARGS,
					     "invalid message format");
			return FALSE;
		}

		if (os_strcmp(entry.key, "WPSVendorExtensions") == 0) {
			if (entry.type != DBUS_TYPE_ARRAY ||
			    entry.array_type != WPAS_DBUS_TYPE_BINARRAY ||
			    entry.array_len > MAX_WPS_VENDOR_EXTENSIONS)
				goto error;

			for (i = 0; i < MAX_WPS_VENDOR_EXTENSIONS; i++) {
				wpabuf_free(hapd->conf->wps_vendor_ext[i]);
				if (i < entry.array_len) {
					hapd->conf->wps_vendor_ext[i] =
						entry.binarray_value[i];
					entry.binarray_value[i] = NULL;
				} else
					hapd->conf->wps_vendor_ext[i] = NULL;
			}

			hostapd_update_wps(hapd);
		} else
			goto error;

		wpa_dbus_dict_entry_clear(&entry);
	}

	return TRUE;

error:
	wpa_dbus_dict_entry_clear(&entry);
	dbus_set_error_const(error, DBUS_ERROR_INVALID_ARGS,
			     "invalid message format");
	return FALSE;
}


DBusMessage * wpas_dbus_handler_p2p_add_service(DBusMessage *message,
						struct wpa_supplicant *wpa_s)
{
	DBusMessageIter iter_dict;
	DBusMessage *reply = NULL;
	DBusMessageIter iter;
	struct wpa_dbus_dict_entry entry;
	int upnp = 0;
	int bonjour = 0;
	char *service = NULL;
	struct wpabuf *query = NULL;
	struct wpabuf *resp = NULL;
	u8 version = 0;

	dbus_message_iter_init(message, &iter);

	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))
			goto error;

		if (os_strcmp(entry.key, "service_type") == 0 &&
		    entry.type == DBUS_TYPE_STRING) {
			if (os_strcmp(entry.str_value, "upnp") == 0)
				upnp = 1;
			else if (os_strcmp(entry.str_value, "bonjour") == 0)
				bonjour = 1;
			else
				goto error_clear;
		} else if (os_strcmp(entry.key, "version") == 0 &&
			   entry.type == DBUS_TYPE_INT32) {
			version = entry.uint32_value;
		} else if (os_strcmp(entry.key, "service") == 0 &&
			   entry.type == DBUS_TYPE_STRING) {
			os_free(service);
			service = os_strdup(entry.str_value);
		} else if (os_strcmp(entry.key, "query") == 0) {
			if (entry.type != DBUS_TYPE_ARRAY ||
			    entry.array_type != DBUS_TYPE_BYTE)
				goto error_clear;
			query = wpabuf_alloc_copy(
				entry.bytearray_value,
				entry.array_len);
		} else if (os_strcmp(entry.key, "response") == 0) {
			if (entry.type != DBUS_TYPE_ARRAY ||
			    entry.array_type != DBUS_TYPE_BYTE)
				goto error_clear;
			resp = wpabuf_alloc_copy(entry.bytearray_value,
						 entry.array_len);
		}
		wpa_dbus_dict_entry_clear(&entry);
	}

	if (upnp == 1) {
		if (version <= 0 || service == NULL)
			goto error;

		if (wpas_p2p_service_add_upnp(wpa_s, version, service) != 0)
			goto error;

	} else if (bonjour == 1) {
		if (query == NULL || resp == NULL)
			goto error;

		if (wpas_p2p_service_add_bonjour(wpa_s, query, resp) < 0)
			goto error;
		query = NULL;
		resp = NULL;
	} else
		goto error;

	os_free(service);
	return reply;
error_clear:
	wpa_dbus_dict_entry_clear(&entry);
error:
	os_free(service);
	wpabuf_free(query);
	wpabuf_free(resp);
	return wpas_dbus_error_invalid_args(message, NULL);
}


DBusMessage * wpas_dbus_handler_p2p_delete_service(
	DBusMessage *message, struct wpa_supplicant *wpa_s)
{
	DBusMessageIter iter_dict;
	DBusMessage *reply = NULL;
	DBusMessageIter iter;
	struct wpa_dbus_dict_entry entry;
	int upnp = 0;
	int bonjour = 0;
	int ret = 0;
	char *service = NULL;
	struct wpabuf *query = NULL;
	u8 version = 0;

	dbus_message_iter_init(message, &iter);

	if (!wpa_dbus_dict_open_read(&iter, &iter_dict, NULL))
		goto error;

	if (wpa_dbus_dict_has_dict_entry(&iter_dict)) {
		if (!wpa_dbus_dict_get_entry(&iter_dict, &entry))
			goto error;

		if (os_strcmp(entry.key, "service_type") == 0 &&
		    entry.type == DBUS_TYPE_STRING) {
			if (os_strcmp(entry.str_value, "upnp") == 0)
				upnp = 1;
			else if (os_strcmp(entry.str_value, "bonjour") == 0)
				bonjour = 1;
			else
				goto error_clear;
			wpa_dbus_dict_entry_clear(&entry);
		}
	}
	if (upnp == 1) {
		while (wpa_dbus_dict_has_dict_entry(&iter_dict)) {
			if (!wpa_dbus_dict_get_entry(&iter_dict, &entry))
				goto error;
			if (os_strcmp(entry.key, "version") == 0 &&
			    entry.type == DBUS_TYPE_INT32)
				version = entry.uint32_value;
			else if (os_strcmp(entry.key, "service") == 0 &&
				 entry.type == DBUS_TYPE_STRING) {
				os_free(service);
				service = os_strdup(entry.str_value);
			} else
				goto error_clear;

			wpa_dbus_dict_entry_clear(&entry);
		}

		if (version <= 0 || service == NULL)
			goto error;

		ret = wpas_p2p_service_del_upnp(wpa_s, version, service);
		if (ret != 0)
			goto error;
	} else if (bonjour == 1) {
		while (wpa_dbus_dict_has_dict_entry(&iter_dict)) {
			if (!wpa_dbus_dict_get_entry(&iter_dict, &entry))
				goto error;

			if (os_strcmp(entry.key, "query") == 0) {
				if (entry.type != DBUS_TYPE_ARRAY ||
				    entry.array_type != DBUS_TYPE_BYTE)
					goto error_clear;
				wpabuf_free(query);
				query = wpabuf_alloc_copy(
					entry.bytearray_value,
					entry.array_len);
			} else
				goto error_clear;

			wpa_dbus_dict_entry_clear(&entry);
		}

		if (query == NULL)
			goto error;

		ret = wpas_p2p_service_del_bonjour(wpa_s, query);
		if (ret != 0)
			goto error;
	} else
		goto error;

	wpabuf_free(query);
	os_free(service);
	return reply;
error_clear:
	wpa_dbus_dict_entry_clear(&entry);
error:
	wpabuf_free(query);
	os_free(service);
	return wpas_dbus_error_invalid_args(message, NULL);
}


DBusMessage * wpas_dbus_handler_p2p_flush_service(DBusMessage *message,
						  struct wpa_supplicant *wpa_s)
{
	wpas_p2p_service_flush(wpa_s);
	return NULL;
}


DBusMessage * wpas_dbus_handler_p2p_service_sd_req(
	DBusMessage *message, struct wpa_supplicant *wpa_s)
{
	DBusMessageIter iter_dict;
	DBusMessage *reply = NULL;
	DBusMessageIter iter;
	struct wpa_dbus_dict_entry entry;
	int upnp = 0;
	char *service = NULL;
	char *peer_object_path = NULL;
	struct wpabuf *tlv = NULL;
	u8 version = 0;
	u64 ref = 0;
	u8 addr_buf[ETH_ALEN], *addr;

	dbus_message_iter_init(message, &iter);

	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))
			goto error;
		if (os_strcmp(entry.key, "peer_object") == 0 &&
		    entry.type == DBUS_TYPE_OBJECT_PATH) {
			peer_object_path = os_strdup(entry.str_value);
		} else if (os_strcmp(entry.key, "service_type") == 0 &&
			   entry.type == DBUS_TYPE_STRING) {
			if (os_strcmp(entry.str_value, "upnp") == 0)
				upnp = 1;
			else
				goto error_clear;
		} else if (os_strcmp(entry.key, "version") == 0 &&
			   entry.type == DBUS_TYPE_INT32) {
			version = entry.uint32_value;
		} else if (os_strcmp(entry.key, "service") == 0 &&
			   entry.type == DBUS_TYPE_STRING) {
			service = os_strdup(entry.str_value);
		} else if (os_strcmp(entry.key, "tlv") == 0) {
			if (entry.type != DBUS_TYPE_ARRAY ||
			    entry.array_type != DBUS_TYPE_BYTE)
				goto error_clear;
			tlv = wpabuf_alloc_copy(entry.bytearray_value,
						entry.array_len);
		} else
			goto error_clear;

		wpa_dbus_dict_entry_clear(&entry);
	}

	if (!peer_object_path) {
		addr = NULL;
	} else {
		if (parse_peer_object_path(peer_object_path, addr_buf) < 0 ||
		    !p2p_peer_known(wpa_s->global->p2p, addr_buf))
			goto error;

		addr = addr_buf;
	}

	if (upnp == 1) {
		if (version <= 0 || service == NULL)
			goto error;

		ref = wpas_p2p_sd_request_upnp(wpa_s, addr, version, service);
	} else {
		if (tlv == NULL)
			goto error;
		ref = wpas_p2p_sd_request(wpa_s, addr, tlv);
		wpabuf_free(tlv);
	}

	if (ref != 0) {
		reply = dbus_message_new_method_return(message);
		dbus_message_append_args(reply, DBUS_TYPE_UINT64,
					 &ref, DBUS_TYPE_INVALID);
	} else {
		reply = wpas_dbus_error_unknown_error(
			message, "Unable to send SD request");
	}
out:
	os_free(service);
	os_free(peer_object_path);
	return reply;
error_clear:
	wpa_dbus_dict_entry_clear(&entry);
error:
	if (tlv)
		wpabuf_free(tlv);
	reply = wpas_dbus_error_invalid_args(message, NULL);
	goto out;
}


DBusMessage * wpas_dbus_handler_p2p_service_sd_res(
	DBusMessage *message, struct wpa_supplicant *wpa_s)
{
	DBusMessageIter iter_dict;
	DBusMessage *reply = NULL;
	DBusMessageIter iter;
	struct wpa_dbus_dict_entry entry;
	char *peer_object_path = NULL;
	struct wpabuf *tlv = NULL;
	int freq = 0;
	int dlg_tok = 0;
	u8 addr[ETH_ALEN];

	dbus_message_iter_init(message, &iter);

	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))
			goto error;

		if (os_strcmp(entry.key, "peer_object") == 0 &&
		    entry.type == DBUS_TYPE_OBJECT_PATH) {
			peer_object_path = os_strdup(entry.str_value);
		} else if (os_strcmp(entry.key, "frequency") == 0 &&
			   entry.type == DBUS_TYPE_INT32) {
			freq = entry.uint32_value;
		} else if (os_strcmp(entry.key, "dialog_token") == 0 &&
			   (entry.type == DBUS_TYPE_UINT32 ||
			    entry.type == DBUS_TYPE_INT32)) {
			dlg_tok = entry.uint32_value;
		} else if (os_strcmp(entry.key, "tlvs") == 0) {
			if (entry.type != DBUS_TYPE_ARRAY ||
			    entry.array_type != DBUS_TYPE_BYTE)
				goto error_clear;
			tlv = wpabuf_alloc_copy(entry.bytearray_value,
						entry.array_len);
		} else
			goto error_clear;

		wpa_dbus_dict_entry_clear(&entry);
	}
	if (parse_peer_object_path(peer_object_path, addr) < 0 ||
	    !p2p_peer_known(wpa_s->global->p2p, addr) ||
	    tlv == NULL)
		goto error;

	wpas_p2p_sd_response(wpa_s, freq, addr, (u8) dlg_tok, tlv);
	wpabuf_free(tlv);
out:
	os_free(peer_object_path);
	return reply;
error_clear:
	wpa_dbus_dict_entry_clear(&entry);
error:
	reply = wpas_dbus_error_invalid_args(message, NULL);
	goto out;
}


DBusMessage * wpas_dbus_handler_p2p_service_sd_cancel_req(
	DBusMessage *message, struct wpa_supplicant *wpa_s)
{
	DBusMessageIter iter;
	u64 req = 0;

	dbus_message_iter_init(message, &iter);
	dbus_message_iter_get_basic(&iter, &req);

	if (req == 0)
		goto error;

	if (wpas_p2p_sd_cancel_request(wpa_s, req) < 0)
		goto error;

	return NULL;
error:
	return wpas_dbus_error_invalid_args(message, NULL);
}


DBusMessage * wpas_dbus_handler_p2p_service_update(
	DBusMessage *message, struct wpa_supplicant *wpa_s)
{
	wpas_p2p_sd_service_update(wpa_s);
	return NULL;
}


DBusMessage * wpas_dbus_handler_p2p_serv_disc_external(
	DBusMessage *message, struct wpa_supplicant *wpa_s)
{
	DBusMessageIter iter;
	int ext = 0;

	dbus_message_iter_init(message, &iter);
	dbus_message_iter_get_basic(&iter, &ext);

	wpa_s->p2p_sd_over_ctrl_iface = ext;

	return NULL;

}


#ifdef CONFIG_WIFI_DISPLAY

dbus_bool_t wpas_dbus_getter_global_wfd_ies(DBusMessageIter *iter,
					    DBusError *error, void *user_data)
{
	struct wpa_global *global = user_data;
	struct wpabuf *ie;
	dbus_bool_t ret;

	ie = wifi_display_get_wfd_ie(global);
	if (ie == NULL)
		return wpas_dbus_simple_array_property_getter(iter,
							      DBUS_TYPE_BYTE,
							      NULL, 0, error);

	ret = wpas_dbus_simple_array_property_getter(iter, DBUS_TYPE_BYTE,
						     wpabuf_head(ie),
						     wpabuf_len(ie), error);
	wpabuf_free(ie);

	return ret;
}


dbus_bool_t wpas_dbus_setter_global_wfd_ies(DBusMessageIter *iter,
					    DBusError *error, void *user_data)
{
	struct wpa_global *global = user_data;
	DBusMessageIter variant, array;
	struct wpabuf *ie = NULL;
	const u8 *data;
	int len;

	if (dbus_message_iter_get_arg_type(iter) != DBUS_TYPE_VARIANT)
		goto err;

	dbus_message_iter_recurse(iter, &variant);
	if (dbus_message_iter_get_arg_type(&variant) != DBUS_TYPE_ARRAY)
		goto err;

	dbus_message_iter_recurse(&variant, &array);
	dbus_message_iter_get_fixed_array(&array, &data, &len);
	if (len == 0) {
		wifi_display_enable(global, 0);
		wifi_display_deinit(global);

		return TRUE;
	}

	ie = wpabuf_alloc(len);
	if (ie == NULL)
		goto err;

	wpabuf_put_data(ie, data, len);
	if (wifi_display_subelem_set_from_ies(global, ie) != 0)
		goto err;

	if (global->wifi_display == 0)
		wifi_display_enable(global, 1);

	wpabuf_free(ie);

	return TRUE;
err:
	wpabuf_free(ie);

	dbus_set_error_const(error, DBUS_ERROR_INVALID_ARGS,
			     "invalid message format");
	return FALSE;
}

#endif /* CONFIG_WIFI_DISPLAY */
