/*
 * 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);
	}

	wpa_s = wpa_s->global->p2p_init_wpa_s;

	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)
{
	wpas_p2p_stop_find(wpa_s->global->p2p_init_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);

	wpa_s = wpa_s->global->p2p_init_wpa_s;

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

	wpa_s = wpa_s->global->p2p_init_wpa_s;

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

	wpa_s = wpa_s->global->p2p_init_wpa_s;

	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 (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);
	}

	wpa_s = wpa_s->global->p2p_init_wpa_s;

	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, 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_remove_client(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 *interface_addr = NULL;
	u8 peer_addr[ETH_ALEN];

	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) {
			os_free(peer_object_path);
			peer_object_path = os_strdup(entry.str_value);
			wpa_dbus_dict_entry_clear(&entry);
		} else if (os_strcmp(entry.key, "iface") == 0 &&
			   entry.type == DBUS_TYPE_STRING) {
			os_free(interface_addr);
			interface_addr = os_strdup(entry.str_value);
			wpa_dbus_dict_entry_clear(&entry);
		} else {
			wpa_dbus_dict_entry_clear(&entry);
			goto err;
		}
	}

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

	wpas_p2p_remove_client(wpa_s, peer_addr, interface_addr != NULL);
	reply = NULL;
out:
	os_free(peer_object_path);
	os_free(interface_addr);
	return reply;
err:
	reply = wpas_dbus_error_invalid_args(message, "Invalid address format");
	goto out;
}


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;

	wpa_s = wpa_s->global->p2p_init_wpa_s;

	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;

	wpa_s = wpa_s->global->p2p_init_wpa_s;

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


/**
 * wpas_dbus_handler_p2p_cancel - Cancel P2P group formation
 * @message: Pointer to incoming dbus message
 * @wpa_s: %wpa_supplicant data structure
 * Returns: NULL on success or DBus error on failure
 *
 * Handler for "Cancel" method call. Returns NULL if P2P cancel succeeds or DBus
 * error on P2P cancel failure
 */
DBusMessage * wpas_dbus_handler_p2p_cancel(DBusMessage *message,
					   struct wpa_supplicant *wpa_s)
{
	if (wpas_p2p_cancel(wpa_s))
		return wpas_dbus_error_unknown_error(message,
						     "P2P cancel failed");

	return NULL;
}


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;

	wpa_s = wpa_s->global->p2p_init_wpa_s;

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

	wpa_s = wpa_s->global->p2p_init_wpa_s;

	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;

	wpa_s = wpa_s->global->p2p_init_wpa_s;

	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;

	wpa_s = wpa_s->global->p2p_init_wpa_s;

	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_manufacturer(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->manufacturer);
	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_modelname(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->model_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_modelnumber(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->model_number);
	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_serialnumber(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->serial_number);
	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;
	wpa_s = wpa_s->global->p2p_init_wpa_s;

	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;

	wpa_s = wpa_s->global->p2p_init_wpa_s;
	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 - Set 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);

	wpa_s = wpa_s->global->p2p_init_wpa_s;
	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);

	wpa_s = wpa_s->global->p2p_init_wpa_s;

	/*
	 * 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;

	wpa_s = wpa_s->global->p2p_init_wpa_s;

	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 */
