/*
 * Wi-Fi Direct - P2P module
 * Copyright (c) 2009-2010, Atheros Communications
 *
 * This software may be distributed under the terms of the BSD license.
 * See README for more details.
 */

#include "includes.h"

#include "common.h"
#include "eloop.h"
#include "common/ieee802_11_defs.h"
#include "common/ieee802_11_common.h"
#include "common/wpa_ctrl.h"
#include "wps/wps_i.h"
#include "p2p_i.h"
#include "p2p.h"


static void p2p_state_timeout(void *eloop_ctx, void *timeout_ctx);
static void p2p_device_free(struct p2p_data *p2p, struct p2p_device *dev);
static void p2p_process_presence_req(struct p2p_data *p2p, const u8 *da,
				     const u8 *sa, const u8 *data, size_t len,
				     int rx_freq);
static void p2p_process_presence_resp(struct p2p_data *p2p, const u8 *da,
				      const u8 *sa, const u8 *data,
				      size_t len);
static void p2p_ext_listen_timeout(void *eloop_ctx, void *timeout_ctx);
static void p2p_scan_timeout(void *eloop_ctx, void *timeout_ctx);


/*
 * p2p_scan recovery timeout
 *
 * Many drivers are using 30 second timeout on scan results. Allow a bit larger
 * timeout for this to avoid hitting P2P timeout unnecessarily.
 */
#define P2P_SCAN_TIMEOUT 35

/**
 * P2P_PEER_EXPIRATION_AGE - Number of seconds after which inactive peer
 * entries will be removed
 */
#ifdef ANDROID_P2P
#define P2P_PEER_EXPIRATION_AGE 30
#else
#define P2P_PEER_EXPIRATION_AGE 300
#endif

#define P2P_PEER_EXPIRATION_INTERVAL (P2P_PEER_EXPIRATION_AGE / 2)

#ifdef ANDROID_P2P
int p2p_connection_in_progress(struct p2p_data *p2p)
{
	int ret = 0;

	switch (p2p->state) {
		case P2P_CONNECT:
		case P2P_CONNECT_LISTEN:
		case P2P_GO_NEG:
		case P2P_WAIT_PEER_CONNECT:
		case P2P_WAIT_PEER_IDLE:
		case P2P_PROVISIONING:
		case P2P_INVITE:
		case P2P_INVITE_LISTEN:
			ret = 1;
			break;

		default:
			wpa_printf(MSG_DEBUG, "p2p_connection_in_progress state %d", p2p->state);
			ret = 0;
	}

	return ret;
}
#endif

static void p2p_expire_peers(struct p2p_data *p2p)
{
	struct p2p_device *dev, *n;
	struct os_time now;
	size_t i;

	os_get_time(&now);
	dl_list_for_each_safe(dev, n, &p2p->devices, struct p2p_device, list) {
		if (dev->last_seen.sec + P2P_PEER_EXPIRATION_AGE >= now.sec)
			continue;

		if (p2p->cfg->go_connected &&
		    p2p->cfg->go_connected(p2p->cfg->cb_ctx,
					   dev->info.p2p_device_addr)) {
			/*
			 * We are connected as a client to a group in which the
			 * peer is the GO, so do not expire the peer entry.
			 */
			os_get_time(&dev->last_seen);
			continue;
		}

		for (i = 0; i < p2p->num_groups; i++) {
			if (p2p_group_is_client_connected(
				    p2p->groups[i], dev->info.p2p_device_addr))
				break;
		}
		if (i < p2p->num_groups) {
			/*
			 * The peer is connected as a client in a group where
			 * we are the GO, so do not expire the peer entry.
			 */
			os_get_time(&dev->last_seen);
			continue;
		}

#ifdef ANDROID_P2P
		/* If Connection is in progress, don't expire the peer
		*/
		if (p2p_connection_in_progress(p2p))
			continue;
#endif

		wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG, "P2P: Expiring old peer "
			"entry " MACSTR, MAC2STR(dev->info.p2p_device_addr));
#ifdef ANDROID_P2P
		/* SD_FAIR_POLICY: Update the current sd_dev_list pointer to next device */
		if(&dev->list == p2p->sd_dev_list)
			p2p->sd_dev_list = dev->list.next;
#endif
		dl_list_del(&dev->list);
		p2p_device_free(p2p, dev);
	}
}


static void p2p_expiration_timeout(void *eloop_ctx, void *timeout_ctx)
{
	struct p2p_data *p2p = eloop_ctx;
	p2p_expire_peers(p2p);
	eloop_register_timeout(P2P_PEER_EXPIRATION_INTERVAL, 0,
			       p2p_expiration_timeout, p2p, NULL);
}


static const char * p2p_state_txt(int state)
{
	switch (state) {
	case P2P_IDLE:
		return "IDLE";
	case P2P_SEARCH:
		return "SEARCH";
	case P2P_CONNECT:
		return "CONNECT";
	case P2P_CONNECT_LISTEN:
		return "CONNECT_LISTEN";
	case P2P_GO_NEG:
		return "GO_NEG";
	case P2P_LISTEN_ONLY:
		return "LISTEN_ONLY";
	case P2P_WAIT_PEER_CONNECT:
		return "WAIT_PEER_CONNECT";
	case P2P_WAIT_PEER_IDLE:
		return "WAIT_PEER_IDLE";
	case P2P_SD_DURING_FIND:
		return "SD_DURING_FIND";
	case P2P_PROVISIONING:
		return "PROVISIONING";
	case P2P_PD_DURING_FIND:
		return "PD_DURING_FIND";
	case P2P_INVITE:
		return "INVITE";
	case P2P_INVITE_LISTEN:
		return "INVITE_LISTEN";
	case P2P_SEARCH_WHEN_READY:
		return "SEARCH_WHEN_READY";
	case P2P_CONTINUE_SEARCH_WHEN_READY:
		return "CONTINUE_SEARCH_WHEN_READY";
	default:
		return "?";
	}
}


u16 p2p_get_provisioning_info(struct p2p_data *p2p, const u8 *addr)
{
	struct p2p_device *dev = NULL;

	if (!addr || !p2p)
		return 0;

	dev = p2p_get_device(p2p, addr);
	if (dev)
		return dev->wps_prov_info;
	else
		return 0;
}


void p2p_clear_provisioning_info(struct p2p_data *p2p, const u8 *addr)
{
	struct p2p_device *dev = NULL;

	if (!addr || !p2p)
		return;

	dev = p2p_get_device(p2p, addr);
	if (dev)
		dev->wps_prov_info = 0;
}


void p2p_set_state(struct p2p_data *p2p, int new_state)
{
	wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG, "P2P: State %s -> %s",
		p2p_state_txt(p2p->state), p2p_state_txt(new_state));
	p2p->state = new_state;
}


void p2p_set_timeout(struct p2p_data *p2p, unsigned int sec, unsigned int usec)
{
	wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG,
		"P2P: Set timeout (state=%s): %u.%06u sec",
		p2p_state_txt(p2p->state), sec, usec);
	eloop_cancel_timeout(p2p_state_timeout, p2p, NULL);
	eloop_register_timeout(sec, usec, p2p_state_timeout, p2p, NULL);
}


void p2p_clear_timeout(struct p2p_data *p2p)
{
	wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG, "P2P: Clear timeout (state=%s)",
		p2p_state_txt(p2p->state));
	eloop_cancel_timeout(p2p_state_timeout, p2p, NULL);
}


void p2p_go_neg_failed(struct p2p_data *p2p, struct p2p_device *peer,
		       int status)
{
	struct p2p_go_neg_results res;
	p2p_clear_timeout(p2p);
	p2p_set_state(p2p, P2P_IDLE);
	if (p2p->go_neg_peer)
		p2p->go_neg_peer->wps_method = WPS_NOT_READY;
	p2p->go_neg_peer = NULL;

	os_memset(&res, 0, sizeof(res));
	res.status = status;
	if (peer) {
		os_memcpy(res.peer_device_addr, peer->info.p2p_device_addr,
			  ETH_ALEN);
		os_memcpy(res.peer_interface_addr, peer->intended_addr,
			  ETH_ALEN);
	}
	p2p->cfg->go_neg_completed(p2p->cfg->cb_ctx, &res);
}


static void p2p_listen_in_find(struct p2p_data *p2p)
{
	unsigned int r, tu;
	int freq;
	struct wpabuf *ies;

	wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG,
		"P2P: Starting short listen state (state=%s)",
		p2p_state_txt(p2p->state));

	freq = p2p_channel_to_freq(p2p->cfg->country, p2p->cfg->reg_class,
				   p2p->cfg->channel);
	if (freq < 0) {
		wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG,
			"P2P: Unknown regulatory class/channel");
		return;
	}

	os_get_random((u8 *) &r, sizeof(r));
	tu = (r % ((p2p->max_disc_int - p2p->min_disc_int) + 1) +
	      p2p->min_disc_int) * 100;

	p2p->pending_listen_freq = freq;
	p2p->pending_listen_sec = 0;
	p2p->pending_listen_usec = 1024 * tu;

	ies = p2p_build_probe_resp_ies(p2p);
	if (ies == NULL)
		return;

	if (p2p->cfg->start_listen(p2p->cfg->cb_ctx, freq, 1024 * tu / 1000,
		    ies) < 0) {
		wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG,
			"P2P: Failed to start listen mode");
		p2p->pending_listen_freq = 0;
	}
	wpabuf_free(ies);
}


int p2p_listen(struct p2p_data *p2p, unsigned int timeout)
{
	int freq;
	struct wpabuf *ies;

	wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG,
		"P2P: Going to listen(only) state");

	freq = p2p_channel_to_freq(p2p->cfg->country, p2p->cfg->reg_class,
				   p2p->cfg->channel);
	if (freq < 0) {
		wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG,
			"P2P: Unknown regulatory class/channel");
		return -1;
	}

	p2p->pending_listen_freq = freq;
	p2p->pending_listen_sec = timeout / 1000;
	p2p->pending_listen_usec = (timeout % 1000) * 1000;

	if (p2p->p2p_scan_running) {
		if (p2p->start_after_scan == P2P_AFTER_SCAN_CONNECT) {
			wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG,
				"P2P: p2p_scan running - connect is already "
				"pending - skip listen");
			return 0;
		}
		wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG,
			"P2P: p2p_scan running - delay start of listen state");
		p2p->start_after_scan = P2P_AFTER_SCAN_LISTEN;
		return 0;
	}

	ies = p2p_build_probe_resp_ies(p2p);
	if (ies == NULL)
		return -1;

	if (p2p->cfg->start_listen(p2p->cfg->cb_ctx, freq, timeout, ies) < 0) {
		wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG,
			"P2P: Failed to start listen mode");
		p2p->pending_listen_freq = 0;
		wpabuf_free(ies);
		return -1;
	}
	wpabuf_free(ies);

	p2p_set_state(p2p, P2P_LISTEN_ONLY);

	return 0;
}


static void p2p_device_clear_reported(struct p2p_data *p2p)
{
	struct p2p_device *dev;
	dl_list_for_each(dev, &p2p->devices, struct p2p_device, list)
		dev->flags &= ~P2P_DEV_REPORTED;
}


/**
 * p2p_get_device - Fetch a peer entry
 * @p2p: P2P module context from p2p_init()
 * @addr: P2P Device Address of the peer
 * Returns: Pointer to the device entry or %NULL if not found
 */
struct p2p_device * p2p_get_device(struct p2p_data *p2p, const u8 *addr)
{
	struct p2p_device *dev;
	dl_list_for_each(dev, &p2p->devices, struct p2p_device, list) {
		if (os_memcmp(dev->info.p2p_device_addr, addr, ETH_ALEN) == 0)
			return dev;
	}
	return NULL;
}


/**
 * p2p_get_device_interface - Fetch a peer entry based on P2P Interface Address
 * @p2p: P2P module context from p2p_init()
 * @addr: P2P Interface Address of the peer
 * Returns: Pointer to the device entry or %NULL if not found
 */
struct p2p_device * p2p_get_device_interface(struct p2p_data *p2p,
					     const u8 *addr)
{
	struct p2p_device *dev;
	dl_list_for_each(dev, &p2p->devices, struct p2p_device, list) {
		if (os_memcmp(dev->interface_addr, addr, ETH_ALEN) == 0)
			return dev;
	}
	return NULL;
}


/**
 * p2p_create_device - Create a peer entry
 * @p2p: P2P module context from p2p_init()
 * @addr: P2P Device Address of the peer
 * Returns: Pointer to the device entry or %NULL on failure
 *
 * If there is already an entry for the peer, it will be returned instead of
 * creating a new one.
 */
static struct p2p_device * p2p_create_device(struct p2p_data *p2p,
					     const u8 *addr)
{
	struct p2p_device *dev, *oldest = NULL;
	size_t count = 0;

	dev = p2p_get_device(p2p, addr);
	if (dev)
		return dev;

	dl_list_for_each(dev, &p2p->devices, struct p2p_device, list) {
		count++;
		if (oldest == NULL ||
		    os_time_before(&dev->last_seen, &oldest->last_seen))
			oldest = dev;
	}
	if (count + 1 > p2p->cfg->max_peers && oldest) {
		wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG,
			"P2P: Remove oldest peer entry to make room for a new "
			"peer");
#ifdef ANDROID_P2P
		/* SD_FAIR_POLICY: Update the current sd_dev_list pointer to next device */
		if(&oldest->list == p2p->sd_dev_list)
			p2p->sd_dev_list = oldest->list.next;
#endif
		dl_list_del(&oldest->list);
		p2p_device_free(p2p, oldest);
	}

	dev = os_zalloc(sizeof(*dev));
	if (dev == NULL)
		return NULL;
	dl_list_add(&p2p->devices, &dev->list);
	os_memcpy(dev->info.p2p_device_addr, addr, ETH_ALEN);

	return dev;
}


static void p2p_copy_client_info(struct p2p_device *dev,
				 struct p2p_client_info *cli)
{
	os_memcpy(dev->info.device_name, cli->dev_name, cli->dev_name_len);
	dev->info.device_name[cli->dev_name_len] = '\0';
	dev->info.dev_capab = cli->dev_capab;
	dev->info.config_methods = cli->config_methods;
	os_memcpy(dev->info.pri_dev_type, cli->pri_dev_type, 8);
	dev->info.wps_sec_dev_type_list_len = 8 * cli->num_sec_dev_types;
	os_memcpy(dev->info.wps_sec_dev_type_list, cli->sec_dev_types,
		  dev->info.wps_sec_dev_type_list_len);
}


static int p2p_add_group_clients(struct p2p_data *p2p, const u8 *go_dev_addr,
				 const u8 *go_interface_addr, int freq,
				 const u8 *gi, size_t gi_len)
{
	struct p2p_group_info info;
	size_t c;
	struct p2p_device *dev;

	if (gi == NULL)
		return 0;

	if (p2p_group_info_parse(gi, gi_len, &info) < 0)
		return -1;

	/*
	 * Clear old data for this group; if the devices are still in the
	 * group, the information will be restored in the loop following this.
	 */
	dl_list_for_each(dev, &p2p->devices, struct p2p_device, list) {
		if (os_memcmp(dev->member_in_go_iface, go_interface_addr,
			      ETH_ALEN) == 0) {
			os_memset(dev->member_in_go_iface, 0, ETH_ALEN);
			os_memset(dev->member_in_go_dev, 0, ETH_ALEN);
		}
	}

	for (c = 0; c < info.num_clients; c++) {
		struct p2p_client_info *cli = &info.client[c];
		if (os_memcmp(cli->p2p_device_addr, p2p->cfg->dev_addr,
			      ETH_ALEN) == 0)
			continue; /* ignore our own entry */
		dev = p2p_get_device(p2p, cli->p2p_device_addr);
		if (dev) {
			if (dev->flags & (P2P_DEV_GROUP_CLIENT_ONLY |
					  P2P_DEV_PROBE_REQ_ONLY)) {
				/*
				 * Update information since we have not
				 * received this directly from the client.
				 */
				p2p_copy_client_info(dev, cli);
			} else {
				/*
				 * Need to update P2P Client Discoverability
				 * flag since it is valid only in P2P Group
				 * Info attribute.
				 */
				dev->info.dev_capab &=
					~P2P_DEV_CAPAB_CLIENT_DISCOVERABILITY;
				dev->info.dev_capab |=
					cli->dev_capab &
					P2P_DEV_CAPAB_CLIENT_DISCOVERABILITY;
			}
			if (dev->flags & P2P_DEV_PROBE_REQ_ONLY) {
				dev->flags &= ~P2P_DEV_PROBE_REQ_ONLY;
			}
		} else {
			dev = p2p_create_device(p2p, cli->p2p_device_addr);
			if (dev == NULL)
				continue;
			dev->flags |= P2P_DEV_GROUP_CLIENT_ONLY;
			p2p_copy_client_info(dev, cli);
			dev->oper_freq = freq;
			p2p->cfg->dev_found(p2p->cfg->cb_ctx,
					    dev->info.p2p_device_addr,
					    &dev->info, 1);
			dev->flags |= P2P_DEV_REPORTED | P2P_DEV_REPORTED_ONCE;
		}

		os_memcpy(dev->interface_addr, cli->p2p_interface_addr,
			  ETH_ALEN);
		os_get_time(&dev->last_seen);
		os_memcpy(dev->member_in_go_dev, go_dev_addr, ETH_ALEN);
		os_memcpy(dev->member_in_go_iface, go_interface_addr,
			  ETH_ALEN);
	}

	return 0;
}


static void p2p_copy_wps_info(struct p2p_device *dev, int probe_req,
			      const struct p2p_message *msg)
{
	os_memcpy(dev->info.device_name, msg->device_name,
		  sizeof(dev->info.device_name));

	if (msg->manufacturer &&
	    msg->manufacturer_len < sizeof(dev->info.manufacturer)) {
		os_memset(dev->info.manufacturer, 0,
			  sizeof(dev->info.manufacturer));
		os_memcpy(dev->info.manufacturer, msg->manufacturer,
			  msg->manufacturer_len);
	}

	if (msg->model_name &&
	    msg->model_name_len < sizeof(dev->info.model_name)) {
		os_memset(dev->info.model_name, 0,
			  sizeof(dev->info.model_name));
		os_memcpy(dev->info.model_name, msg->model_name,
			  msg->model_name_len);
	}

	if (msg->model_number &&
	    msg->model_number_len < sizeof(dev->info.model_number)) {
		os_memset(dev->info.model_number, 0,
			  sizeof(dev->info.model_number));
		os_memcpy(dev->info.model_number, msg->model_number,
			  msg->model_number_len);
	}

	if (msg->serial_number &&
	    msg->serial_number_len < sizeof(dev->info.serial_number)) {
		os_memset(dev->info.serial_number, 0,
			  sizeof(dev->info.serial_number));
		os_memcpy(dev->info.serial_number, msg->serial_number,
			  msg->serial_number_len);
	}

	if (msg->pri_dev_type)
		os_memcpy(dev->info.pri_dev_type, msg->pri_dev_type,
			  sizeof(dev->info.pri_dev_type));
	else if (msg->wps_pri_dev_type)
		os_memcpy(dev->info.pri_dev_type, msg->wps_pri_dev_type,
			  sizeof(dev->info.pri_dev_type));

	if (msg->wps_sec_dev_type_list) {
		os_memcpy(dev->info.wps_sec_dev_type_list,
			  msg->wps_sec_dev_type_list,
			  msg->wps_sec_dev_type_list_len);
		dev->info.wps_sec_dev_type_list_len =
			msg->wps_sec_dev_type_list_len;
	}

	if (msg->capability) {
		/*
		 * P2P Client Discoverability bit is reserved in all frames
		 * that use this function, so do not change its value here.
		 */
		dev->info.dev_capab &= P2P_DEV_CAPAB_CLIENT_DISCOVERABILITY;
		dev->info.dev_capab |= msg->capability[0] &
			~P2P_DEV_CAPAB_CLIENT_DISCOVERABILITY;
		dev->info.group_capab = msg->capability[1];
	}

	if (msg->ext_listen_timing) {
		dev->ext_listen_period = WPA_GET_LE16(msg->ext_listen_timing);
		dev->ext_listen_interval =
			WPA_GET_LE16(msg->ext_listen_timing + 2);
	}

	if (!probe_req) {
		dev->info.config_methods = msg->config_methods ?
			msg->config_methods : msg->wps_config_methods;
	}
}


/**
 * p2p_add_device - Add peer entries based on scan results or P2P frames
 * @p2p: P2P module context from p2p_init()
 * @addr: Source address of Beacon or Probe Response frame (may be either
 *	P2P Device Address or P2P Interface Address)
 * @level: Signal level (signal strength of the received frame from the peer)
 * @freq: Frequency on which the Beacon or Probe Response frame was received
 * @ies: IEs from the Beacon or Probe Response frame
 * @ies_len: Length of ies buffer in octets
 * @scan_res: Whether this was based on scan results
 * Returns: 0 on success, -1 on failure
 *
 * If the scan result is for a GO, the clients in the group will also be added
 * to the peer table. This function can also be used with some other frames
 * like Provision Discovery Request that contains P2P Capability and P2P Device
 * Info attributes.
 */
int p2p_add_device(struct p2p_data *p2p, const u8 *addr, int freq, int level,
		   const u8 *ies, size_t ies_len, int scan_res)
{
	struct p2p_device *dev;
	struct p2p_message msg;
	const u8 *p2p_dev_addr;
	int i;

	os_memset(&msg, 0, sizeof(msg));
	if (p2p_parse_ies(ies, ies_len, &msg)) {
		wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG,
			"P2P: Failed to parse P2P IE for a device entry");
		p2p_parse_free(&msg);
		return -1;
	}

	if (msg.p2p_device_addr)
		p2p_dev_addr = msg.p2p_device_addr;
	else if (msg.device_id)
		p2p_dev_addr = msg.device_id;
	else {
		wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG,
			"P2P: Ignore scan data without P2P Device Info or "
			"P2P Device Id");
		p2p_parse_free(&msg);
		return -1;
	}

	if (!is_zero_ether_addr(p2p->peer_filter) &&
	    os_memcmp(p2p_dev_addr, p2p->peer_filter, ETH_ALEN) != 0) {
		wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG, "P2P: Do not add peer "
			"filter for " MACSTR " due to peer filter",
			MAC2STR(p2p_dev_addr));
		return 0;
	}

	dev = p2p_create_device(p2p, p2p_dev_addr);
	if (dev == NULL) {
		p2p_parse_free(&msg);
		return -1;
	}
	os_get_time(&dev->last_seen);
	dev->flags &= ~(P2P_DEV_PROBE_REQ_ONLY | P2P_DEV_GROUP_CLIENT_ONLY);

	if (os_memcmp(addr, p2p_dev_addr, ETH_ALEN) != 0)
		os_memcpy(dev->interface_addr, addr, ETH_ALEN);
	if (msg.ssid &&
	    (msg.ssid[1] != P2P_WILDCARD_SSID_LEN ||
	     os_memcmp(msg.ssid + 2, P2P_WILDCARD_SSID, P2P_WILDCARD_SSID_LEN)
	     != 0)) {
		os_memcpy(dev->oper_ssid, msg.ssid + 2, msg.ssid[1]);
		dev->oper_ssid_len = msg.ssid[1];
	}

	if (freq >= 2412 && freq <= 2484 && msg.ds_params &&
	    *msg.ds_params >= 1 && *msg.ds_params <= 14) {
		int ds_freq;
		if (*msg.ds_params == 14)
			ds_freq = 2484;
		else
			ds_freq = 2407 + *msg.ds_params * 5;
		if (freq != ds_freq) {
			wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG,
				"P2P: Update Listen frequency based on DS "
				"Parameter Set IE: %d -> %d MHz",
				freq, ds_freq);
			freq = ds_freq;
		}
	}

	if (dev->listen_freq && dev->listen_freq != freq && scan_res) {
		wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG,
			"P2P: Update Listen frequency based on scan "
			"results (" MACSTR " %d -> %d MHz (DS param %d)",
			MAC2STR(dev->info.p2p_device_addr), dev->listen_freq,
			freq, msg.ds_params ? *msg.ds_params : -1);
	}
	if (scan_res) {
		dev->listen_freq = freq;
		if (msg.group_info)
			dev->oper_freq = freq;
	}
	dev->info.level = level;

	p2p_copy_wps_info(dev, 0, &msg);

	for (i = 0; i < P2P_MAX_WPS_VENDOR_EXT; i++) {
		wpabuf_free(dev->info.wps_vendor_ext[i]);
		dev->info.wps_vendor_ext[i] = NULL;
	}

	for (i = 0; i < P2P_MAX_WPS_VENDOR_EXT; i++) {
		if (msg.wps_vendor_ext[i] == NULL)
			break;
		dev->info.wps_vendor_ext[i] = wpabuf_alloc_copy(
			msg.wps_vendor_ext[i], msg.wps_vendor_ext_len[i]);
		if (dev->info.wps_vendor_ext[i] == NULL)
			break;
	}

	if (msg.wfd_subelems) {
		wpabuf_free(dev->info.wfd_subelems);
		dev->info.wfd_subelems = wpabuf_dup(msg.wfd_subelems);
	}

	if (scan_res) {
		p2p_add_group_clients(p2p, p2p_dev_addr, addr, freq,
				      msg.group_info, msg.group_info_len);
	}

	p2p_parse_free(&msg);

	if (p2p_pending_sd_req(p2p, dev))
		dev->flags |= P2P_DEV_SD_SCHEDULE;

	if (dev->flags & P2P_DEV_REPORTED)
		return 0;

	wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG,
		"P2P: Peer found with Listen frequency %d MHz", freq);
	if (dev->flags & P2P_DEV_USER_REJECTED) {
		wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG,
			"P2P: Do not report rejected device");
		return 0;
	}

	p2p->cfg->dev_found(p2p->cfg->cb_ctx, addr, &dev->info,
			    !(dev->flags & P2P_DEV_REPORTED_ONCE));
	dev->flags |= P2P_DEV_REPORTED | P2P_DEV_REPORTED_ONCE;

	return 0;
}


static void p2p_device_free(struct p2p_data *p2p, struct p2p_device *dev)
{
	int i;

	if (p2p->go_neg_peer == dev) {
		/*
		 * If GO Negotiation is in progress, report that it has failed.
		 */
		p2p_go_neg_failed(p2p, dev, -1);
		p2p->go_neg_peer = NULL;
	}
	if (p2p->invite_peer == dev)
		p2p->invite_peer = NULL;
	if (p2p->sd_peer == dev)
		p2p->sd_peer = NULL;
	if (p2p->pending_client_disc_go == dev)
		p2p->pending_client_disc_go = NULL;

	/* dev_lost() device, but only if it was previously dev_found() */
	if (dev->flags & P2P_DEV_REPORTED_ONCE)
		p2p->cfg->dev_lost(p2p->cfg->cb_ctx,
				   dev->info.p2p_device_addr);

	for (i = 0; i < P2P_MAX_WPS_VENDOR_EXT; i++) {
		wpabuf_free(dev->info.wps_vendor_ext[i]);
		dev->info.wps_vendor_ext[i] = NULL;
	}

	wpabuf_free(dev->info.wfd_subelems);

	os_free(dev);
}


static int p2p_get_next_prog_freq(struct p2p_data *p2p)
{
	struct p2p_channels *c;
	struct p2p_reg_class *cla;
	size_t cl, ch;
	int found = 0;
	u8 reg_class;
	u8 channel;
	int freq;

	c = &p2p->cfg->channels;
	for (cl = 0; cl < c->reg_classes; cl++) {
		cla = &c->reg_class[cl];
		if (cla->reg_class != p2p->last_prog_scan_class)
			continue;
		for (ch = 0; ch < cla->channels; ch++) {
			if (cla->channel[ch] == p2p->last_prog_scan_chan) {
				found = 1;
				break;
			}
		}
		if (found)
			break;
	}

	if (!found) {
		/* Start from beginning */
		reg_class = c->reg_class[0].reg_class;
		channel = c->reg_class[0].channel[0];
	} else {
		/* Pick the next channel */
		ch++;
		if (ch == cla->channels) {
			cl++;
			if (cl == c->reg_classes)
				cl = 0;
			ch = 0;
		}
		reg_class = c->reg_class[cl].reg_class;
		channel = c->reg_class[cl].channel[ch];
	}

	freq = p2p_channel_to_freq(p2p->cfg->country, reg_class, channel);
	wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG, "P2P: Next progressive search "
		"channel: reg_class %u channel %u -> %d MHz",
		reg_class, channel, freq);
	p2p->last_prog_scan_class = reg_class;
	p2p->last_prog_scan_chan = channel;

	if (freq == 2412 || freq == 2437 || freq == 2462)
		return 0; /* No need to add social channels */
	return freq;
}


static void p2p_search(struct p2p_data *p2p)
{
	int freq = 0;
	enum p2p_scan_type type;
	u16 pw_id = DEV_PW_DEFAULT;
	int res;

	if (p2p->drv_in_listen) {
		wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG, "P2P: Driver is still "
			"in Listen state - wait for it to end before "
			"continuing");
		return;
	}
	p2p->cfg->stop_listen(p2p->cfg->cb_ctx);

	if (p2p->find_type == P2P_FIND_PROGRESSIVE &&
	    (freq = p2p_get_next_prog_freq(p2p)) > 0) {
		type = P2P_SCAN_SOCIAL_PLUS_ONE;
		wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG, "P2P: Starting search "
			"(+ freq %u)", freq);
	} else {
		type = P2P_SCAN_SOCIAL;
		wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG, "P2P: Starting search");
	}

	res = p2p->cfg->p2p_scan(p2p->cfg->cb_ctx, type, freq,
				 p2p->num_req_dev_types, p2p->req_dev_types,
				 p2p->find_dev_id, pw_id);
	if (res < 0) {
		wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG,
			"P2P: Scan request failed");
		p2p_continue_find(p2p);
	} else if (res == 1) {
		wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG, "P2P: Could not start "
			"p2p_scan at this point - will try again after "
			"previous scan completes");
		p2p_set_state(p2p, P2P_CONTINUE_SEARCH_WHEN_READY);
	} else {
		wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG, "P2P: Running p2p_scan");
		p2p->p2p_scan_running = 1;
		eloop_cancel_timeout(p2p_scan_timeout, p2p, NULL);
		eloop_register_timeout(P2P_SCAN_TIMEOUT, 0, p2p_scan_timeout,
				       p2p, NULL);
	}
}


static void p2p_find_timeout(void *eloop_ctx, void *timeout_ctx)
{
	struct p2p_data *p2p = eloop_ctx;
	wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG, "P2P: Find timeout -> stop");
	p2p_stop_find(p2p);
}


static int p2p_run_after_scan(struct p2p_data *p2p)
{
	struct p2p_device *dev;
	enum p2p_after_scan op;

	if (p2p->after_scan_tx) {
		/* TODO: schedule p2p_run_after_scan to be called from TX
		 * status callback(?) */
		wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG, "P2P: Send pending "
			"Action frame at p2p_scan completion");
		p2p->cfg->send_action(p2p->cfg->cb_ctx,
				      p2p->after_scan_tx->freq,
				      p2p->after_scan_tx->dst,
				      p2p->after_scan_tx->src,
				      p2p->after_scan_tx->bssid,
				      (u8 *) (p2p->after_scan_tx + 1),
				      p2p->after_scan_tx->len,
				      p2p->after_scan_tx->wait_time);
		os_free(p2p->after_scan_tx);
		p2p->after_scan_tx = NULL;
#ifdef ANDROID_P2P
		/* For SD frames, there is a scenario, where we can receive a SD request frame during p2p_scan.
		 * At that moment, we will send the SD response from this context. After sending the SD response,
		 * we need to continue p2p_find. But if we return 1 from here, p2p_find is going to be stopped.
		 */
		return 0;
#else
		return 1;
#endif
	}

	op = p2p->start_after_scan;
	p2p->start_after_scan = P2P_AFTER_SCAN_NOTHING;
	switch (op) {
	case P2P_AFTER_SCAN_NOTHING:
		break;
	case P2P_AFTER_SCAN_LISTEN:
		wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG, "P2P: Start previously "
			"requested Listen state");
		p2p_listen(p2p, p2p->pending_listen_sec * 1000 +
			   p2p->pending_listen_usec / 1000);
		return 1;
	case P2P_AFTER_SCAN_CONNECT:
		wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG, "P2P: Start previously "
			"requested connect with " MACSTR,
			MAC2STR(p2p->after_scan_peer));
		dev = p2p_get_device(p2p, p2p->after_scan_peer);
		if (dev == NULL) {
			wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG, "P2P: Peer not "
				"known anymore");
			break;
		}
		p2p_connect_send(p2p, dev);
		return 1;
	}

	return 0;
}


static void p2p_scan_timeout(void *eloop_ctx, void *timeout_ctx)
{
	struct p2p_data *p2p = eloop_ctx;
	int running;
	wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG, "P2P: p2p_scan timeout "
		"(running=%d)", p2p->p2p_scan_running);
	running = p2p->p2p_scan_running;
	/* Make sure we recover from missed scan results callback */
	p2p->p2p_scan_running = 0;

	if (running)
		p2p_run_after_scan(p2p);
}


static void p2p_free_req_dev_types(struct p2p_data *p2p)
{
	p2p->num_req_dev_types = 0;
	os_free(p2p->req_dev_types);
	p2p->req_dev_types = NULL;
}


int p2p_find(struct p2p_data *p2p, unsigned int timeout,
	     enum p2p_discovery_type type,
	     unsigned int num_req_dev_types, const u8 *req_dev_types,
	     const u8 *dev_id, unsigned int search_delay)
{
	int res;

	wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG, "P2P: Starting find (type=%d)",
		type);
	if (p2p->p2p_scan_running) {
		wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG, "P2P: p2p_scan is "
			"already running");
	}

	p2p_free_req_dev_types(p2p);
	if (req_dev_types && num_req_dev_types) {
		p2p->req_dev_types = os_malloc(num_req_dev_types *
					       WPS_DEV_TYPE_LEN);
		if (p2p->req_dev_types == NULL)
			return -1;
		os_memcpy(p2p->req_dev_types, req_dev_types,
			  num_req_dev_types * WPS_DEV_TYPE_LEN);
		p2p->num_req_dev_types = num_req_dev_types;
	}

	if (dev_id) {
		os_memcpy(p2p->find_dev_id_buf, dev_id, ETH_ALEN);
		p2p->find_dev_id = p2p->find_dev_id_buf;
	} else
		p2p->find_dev_id = NULL;

	p2p->start_after_scan = P2P_AFTER_SCAN_NOTHING;
	p2p_clear_timeout(p2p);
	p2p->cfg->stop_listen(p2p->cfg->cb_ctx);
	p2p->find_type = type;
	p2p_device_clear_reported(p2p);
	p2p_set_state(p2p, P2P_SEARCH);
	p2p->search_delay = search_delay;
	p2p->in_search_delay = 0;
	eloop_cancel_timeout(p2p_find_timeout, p2p, NULL);
	p2p->last_p2p_find_timeout = timeout;
	if (timeout)
		eloop_register_timeout(timeout, 0, p2p_find_timeout,
				       p2p, NULL);
	switch (type) {
	case P2P_FIND_START_WITH_FULL:
	case P2P_FIND_PROGRESSIVE:
		res = p2p->cfg->p2p_scan(p2p->cfg->cb_ctx, P2P_SCAN_FULL, 0,
					 p2p->num_req_dev_types,
					 p2p->req_dev_types, dev_id,
					 DEV_PW_DEFAULT);
		break;
	case P2P_FIND_ONLY_SOCIAL:
		res = p2p->cfg->p2p_scan(p2p->cfg->cb_ctx, P2P_SCAN_SOCIAL, 0,
					 p2p->num_req_dev_types,
					 p2p->req_dev_types, dev_id,
					 DEV_PW_DEFAULT);
		break;
	default:
		return -1;
	}

	if (res == 0) {
		wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG, "P2P: Running p2p_scan");
		p2p->p2p_scan_running = 1;
		eloop_cancel_timeout(p2p_scan_timeout, p2p, NULL);
		eloop_register_timeout(P2P_SCAN_TIMEOUT, 0, p2p_scan_timeout,
				       p2p, NULL);
	} else if (res == 1) {
		wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG, "P2P: Could not start "
			"p2p_scan at this point - will try again after "
			"previous scan completes");
		res = 0;
		p2p_set_state(p2p, P2P_SEARCH_WHEN_READY);
		eloop_cancel_timeout(p2p_find_timeout, p2p, NULL);
	} else {
		wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG, "P2P: Failed to start "
			"p2p_scan");
		p2p_set_state(p2p, P2P_IDLE);
		eloop_cancel_timeout(p2p_find_timeout, p2p, NULL);
	}

	return res;
}

#ifdef ANDROID_P2P
int p2p_search_pending(struct p2p_data *p2p)
{
	if(p2p == NULL)
		return 0;

	if(p2p->state == P2P_SEARCH_WHEN_READY)
		return 1;

	return 0;
}
#endif

int p2p_other_scan_completed(struct p2p_data *p2p)
{
	if (p2p->state == P2P_CONTINUE_SEARCH_WHEN_READY) {
		p2p_set_state(p2p, P2P_SEARCH);
		p2p_search(p2p);
		return 1;
	}
	if (p2p->state != P2P_SEARCH_WHEN_READY)
		return 0;
	wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG, "P2P: Starting pending P2P find "
		"now that previous scan was completed");
	if (p2p_find(p2p, p2p->last_p2p_find_timeout, p2p->find_type,
		     p2p->num_req_dev_types, p2p->req_dev_types,
		     p2p->find_dev_id, p2p->search_delay) < 0)
		return 0;
	return 1;
}


void p2p_stop_find_for_freq(struct p2p_data *p2p, int freq)
{
	wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG, "P2P: Stopping find");
	eloop_cancel_timeout(p2p_find_timeout, p2p, NULL);
	p2p_clear_timeout(p2p);
	if (p2p->state == P2P_SEARCH)
		wpa_msg(p2p->cfg->msg_ctx, MSG_INFO, P2P_EVENT_FIND_STOPPED);
	p2p_set_state(p2p, P2P_IDLE);
	p2p_free_req_dev_types(p2p);
	p2p->start_after_scan = P2P_AFTER_SCAN_NOTHING;
	p2p->go_neg_peer = NULL;
	p2p->sd_peer = NULL;
	p2p->invite_peer = NULL;
	p2p_stop_listen_for_freq(p2p, freq);
}


void p2p_stop_listen_for_freq(struct p2p_data *p2p, int freq)
{
	if (freq > 0 && p2p->drv_in_listen == freq && p2p->in_listen) {
		wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG, "P2P: Skip stop_listen "
			"since we are on correct channel for response");
		return;
	}
	if (p2p->in_listen) {
		p2p->in_listen = 0;
		p2p_clear_timeout(p2p);
	}
	if (p2p->drv_in_listen) {
		/*
		 * The driver may not deliver callback to p2p_listen_end()
		 * when the operation gets canceled, so clear the internal
		 * variable that is tracking driver state.
		 */
		wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG, "P2P: Clear "
			"drv_in_listen (%d)", p2p->drv_in_listen);
		p2p->drv_in_listen = 0;
	}
	p2p->cfg->stop_listen(p2p->cfg->cb_ctx);
}


void p2p_stop_find(struct p2p_data *p2p)
{
	p2p_stop_find_for_freq(p2p, 0);
}


static int p2p_prepare_channel(struct p2p_data *p2p, unsigned int force_freq)
{
	if (force_freq) {
		u8 op_reg_class, op_channel;
		if (p2p_freq_to_channel(p2p->cfg->country, force_freq,
					&op_reg_class, &op_channel) < 0) {
			wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG,
				"P2P: Unsupported frequency %u MHz",
				force_freq);
			return -1;
		}
		if (!p2p_channels_includes(&p2p->cfg->channels, op_reg_class,
					   op_channel)) {
			wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG,
				"P2P: Frequency %u MHz (oper_class %u "
				"channel %u) not allowed for P2P",
				force_freq, op_reg_class, op_channel);
			return -1;
		}
		p2p->op_reg_class = op_reg_class;
		p2p->op_channel = op_channel;
#ifndef ANDROID_P2P
		p2p->channels.reg_classes = 1;
		p2p->channels.reg_class[0].channels = 1;
		p2p->channels.reg_class[0].reg_class = p2p->op_reg_class;
		p2p->channels.reg_class[0].channel[0] = p2p->op_channel;
#else
		if(p2p->cfg->p2p_concurrency == P2P_MULTI_CHANNEL_CONCURRENT) {
			/* We we are requesting for a preferred channel. But since
			 * are multichannel concurrent, we have to poplulate the
			 * p2p_channels with list of channels that we support.
			 */
#ifdef ANDROID_P2P
			wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG, "Full channel list");
#endif
			os_memcpy(&p2p->channels, &p2p->cfg->channels,
				sizeof(struct p2p_channels));
		} else {
#ifdef ANDROID_P2P
			wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG, "Single channel list %d", p2p->op_channel);
#endif
			p2p->channels.reg_classes = 1;
			p2p->channels.reg_class[0].channels = 1;
			p2p->channels.reg_class[0].reg_class = p2p->op_reg_class;
			p2p->channels.reg_class[0].channel[0] = p2p->op_channel;
		}
#endif
	} else {
		u8 op_reg_class, op_channel;

		if (!p2p->cfg->cfg_op_channel && p2p->best_freq_overall > 0 &&
		    p2p_supported_freq(p2p, p2p->best_freq_overall) &&
		    p2p_freq_to_channel(p2p->cfg->country,
					p2p->best_freq_overall,
					&op_reg_class, &op_channel) == 0) {
			wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG,
				"P2P: Select best overall channel as "
				"operating channel preference");
			p2p->op_reg_class = op_reg_class;
			p2p->op_channel = op_channel;
		} else if (!p2p->cfg->cfg_op_channel && p2p->best_freq_5 > 0 &&
			   p2p_supported_freq(p2p, p2p->best_freq_5) &&
			   p2p_freq_to_channel(p2p->cfg->country,
					       p2p->best_freq_5,
					       &op_reg_class, &op_channel) ==
			   0) {
			wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG,
				"P2P: Select best 5 GHz channel as "
				"operating channel preference");
			p2p->op_reg_class = op_reg_class;
			p2p->op_channel = op_channel;
		} else if (!p2p->cfg->cfg_op_channel &&
			   p2p->best_freq_24 > 0 &&
			   p2p_supported_freq(p2p, p2p->best_freq_24) &&
			   p2p_freq_to_channel(p2p->cfg->country,
					       p2p->best_freq_24,
					       &op_reg_class, &op_channel) ==
			   0) {
			wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG,
				"P2P: Select best 2.4 GHz channel as "
				"operating channel preference");
			p2p->op_reg_class = op_reg_class;
			p2p->op_channel = op_channel;
		} else {
			p2p->op_reg_class = p2p->cfg->op_reg_class;
			p2p->op_channel = p2p->cfg->op_channel;
		}

		os_memcpy(&p2p->channels, &p2p->cfg->channels,
			  sizeof(struct p2p_channels));
	}
	wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG,
		"P2P: Own preference for operation channel: "
		"Operating Class %u Channel %u%s",
		p2p->op_reg_class, p2p->op_channel,
		force_freq ? " (forced)" : "");

	return 0;
}


static void p2p_set_dev_persistent(struct p2p_device *dev,
				   int persistent_group)
{
	switch (persistent_group) {
	case 0:
		dev->flags &= ~(P2P_DEV_PREFER_PERSISTENT_GROUP |
				P2P_DEV_PREFER_PERSISTENT_RECONN);
		break;
	case 1:
		dev->flags |= P2P_DEV_PREFER_PERSISTENT_GROUP;
		dev->flags &= ~P2P_DEV_PREFER_PERSISTENT_RECONN;
		break;
	case 2:
		dev->flags |= P2P_DEV_PREFER_PERSISTENT_GROUP |
			P2P_DEV_PREFER_PERSISTENT_RECONN;
		break;
	}
}


int p2p_connect(struct p2p_data *p2p, const u8 *peer_addr,
		enum p2p_wps_method wps_method,
		int go_intent, const u8 *own_interface_addr,
		unsigned int force_freq, int persistent_group,
		const u8 *force_ssid, size_t force_ssid_len,
		int pd_before_go_neg)
{
	struct p2p_device *dev;

	wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG,
		"P2P: Request to start group negotiation - peer=" MACSTR
		"  GO Intent=%d  Intended Interface Address=" MACSTR
		" wps_method=%d persistent_group=%d pd_before_go_neg=%d force_freq %d",
		MAC2STR(peer_addr), go_intent, MAC2STR(own_interface_addr),
		wps_method, persistent_group, pd_before_go_neg, force_freq);

	if (p2p_prepare_channel(p2p, force_freq) < 0)
		return -1;

	dev = p2p_get_device(p2p, peer_addr);
	if (dev == NULL || (dev->flags & P2P_DEV_PROBE_REQ_ONLY)) {
		wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG,
			"P2P: Cannot connect to unknown P2P Device " MACSTR,
			MAC2STR(peer_addr));
		return -1;
	}

	if (dev->flags & P2P_DEV_GROUP_CLIENT_ONLY) {
		if (!(dev->info.dev_capab &
		      P2P_DEV_CAPAB_CLIENT_DISCOVERABILITY)) {
			wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG,
				"P2P: Cannot connect to P2P Device " MACSTR
				" that is in a group and is not discoverable",
				MAC2STR(peer_addr));
			return -1;
		}
		if (dev->oper_freq <= 0) {
			wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG,
				"P2P: Cannot connect to P2P Device " MACSTR
				" with incomplete information",
				MAC2STR(peer_addr));
			return -1;
		}

		/*
		 * First, try to connect directly. If the peer does not
		 * acknowledge frames, assume it is sleeping and use device
		 * discoverability via the GO at that point.
		 */
	}

	p2p->ssid_set = 0;
	if (force_ssid) {
		wpa_hexdump_ascii(MSG_DEBUG, "P2P: Forced SSID",
				  force_ssid, force_ssid_len);
		os_memcpy(p2p->ssid, force_ssid, force_ssid_len);
		p2p->ssid_len = force_ssid_len;
		p2p->ssid_set = 1;
	}

	dev->flags &= ~P2P_DEV_NOT_YET_READY;
	dev->flags &= ~P2P_DEV_USER_REJECTED;
	dev->flags &= ~P2P_DEV_WAIT_GO_NEG_RESPONSE;
	dev->flags &= ~P2P_DEV_WAIT_GO_NEG_CONFIRM;
	if (pd_before_go_neg)
		dev->flags |= P2P_DEV_PD_BEFORE_GO_NEG;
	else
		dev->flags &= ~P2P_DEV_PD_BEFORE_GO_NEG;
	dev->connect_reqs = 0;
	dev->go_neg_req_sent = 0;
	dev->go_state = UNKNOWN_GO;
	p2p_set_dev_persistent(dev, persistent_group);
	p2p->go_intent = go_intent;
	os_memcpy(p2p->intended_addr, own_interface_addr, ETH_ALEN);

	if (p2p->state != P2P_IDLE)
		p2p_stop_find(p2p);

	if (p2p->after_scan_tx) {
		/*
		 * We need to drop the pending frame to avoid issues with the
		 * new GO Negotiation, e.g., when the pending frame was from a
		 * previous attempt at starting a GO Negotiation.
		 */
		wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG, "P2P: Dropped "
			"previous pending Action frame TX that was waiting "
			"for p2p_scan completion");
		os_free(p2p->after_scan_tx);
		p2p->after_scan_tx = NULL;
	}

	dev->wps_method = wps_method;
	dev->status = P2P_SC_SUCCESS;

	if (force_freq)
		dev->flags |= P2P_DEV_FORCE_FREQ;
	else
		dev->flags &= ~P2P_DEV_FORCE_FREQ;

	if (p2p->p2p_scan_running) {
		wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG,
			"P2P: p2p_scan running - delay connect send");
		p2p->start_after_scan = P2P_AFTER_SCAN_CONNECT;
		os_memcpy(p2p->after_scan_peer, peer_addr, ETH_ALEN);
		return 0;
	}
	p2p->start_after_scan = P2P_AFTER_SCAN_NOTHING;

	return p2p_connect_send(p2p, dev);
}


int p2p_authorize(struct p2p_data *p2p, const u8 *peer_addr,
		  enum p2p_wps_method wps_method,
		  int go_intent, const u8 *own_interface_addr,
		  unsigned int force_freq, int persistent_group,
		  const u8 *force_ssid, size_t force_ssid_len)
{
	struct p2p_device *dev;

	wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG,
		"P2P: Request to authorize group negotiation - peer=" MACSTR
		"  GO Intent=%d  Intended Interface Address=" MACSTR
		" wps_method=%d  persistent_group=%d",
		MAC2STR(peer_addr), go_intent, MAC2STR(own_interface_addr),
		wps_method, persistent_group);

	if (p2p_prepare_channel(p2p, force_freq) < 0)
		return -1;

	dev = p2p_get_device(p2p, peer_addr);
	if (dev == NULL) {
		wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG,
			"P2P: Cannot authorize unknown P2P Device " MACSTR,
			MAC2STR(peer_addr));
		return -1;
	}

	p2p->ssid_set = 0;
	if (force_ssid) {
		wpa_hexdump_ascii(MSG_DEBUG, "P2P: Forced SSID",
				  force_ssid, force_ssid_len);
		os_memcpy(p2p->ssid, force_ssid, force_ssid_len);
		p2p->ssid_len = force_ssid_len;
		p2p->ssid_set = 1;
	}

	dev->flags &= ~P2P_DEV_NOT_YET_READY;
	dev->flags &= ~P2P_DEV_USER_REJECTED;
	dev->go_neg_req_sent = 0;
	dev->go_state = UNKNOWN_GO;
	p2p_set_dev_persistent(dev, persistent_group);
	p2p->go_intent = go_intent;
	os_memcpy(p2p->intended_addr, own_interface_addr, ETH_ALEN);

	dev->wps_method = wps_method;
	dev->status = P2P_SC_SUCCESS;

	if (force_freq)
		dev->flags |= P2P_DEV_FORCE_FREQ;
	else
		dev->flags &= ~P2P_DEV_FORCE_FREQ;

	return 0;
}


void p2p_add_dev_info(struct p2p_data *p2p, const u8 *addr,
		      struct p2p_device *dev, struct p2p_message *msg)
{
	os_get_time(&dev->last_seen);

	p2p_copy_wps_info(dev, 0, msg);

	if (msg->listen_channel) {
		int freq;
		freq = p2p_channel_to_freq((char *) msg->listen_channel,
					   msg->listen_channel[3],
					   msg->listen_channel[4]);
		if (freq < 0) {
			wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG,
				"P2P: Unknown peer Listen channel: "
				"country=%c%c(0x%02x) reg_class=%u channel=%u",
				msg->listen_channel[0],
				msg->listen_channel[1],
				msg->listen_channel[2],
				msg->listen_channel[3],
				msg->listen_channel[4]);
		} else {
			wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG, "P2P: Update "
				"peer " MACSTR " Listen channel: %u -> %u MHz",
				MAC2STR(dev->info.p2p_device_addr),
				dev->listen_freq, freq);
			dev->listen_freq = freq;
		}
	}

	if (msg->wfd_subelems) {
		wpabuf_free(dev->info.wfd_subelems);
		dev->info.wfd_subelems = wpabuf_dup(msg->wfd_subelems);
	}

	if (dev->flags & P2P_DEV_PROBE_REQ_ONLY) {
		dev->flags &= ~P2P_DEV_PROBE_REQ_ONLY;
		wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG,
			"P2P: Completed device entry based on data from "
			"GO Negotiation Request");
	} else {
		wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG,
			"P2P: Created device entry based on GO Neg Req: "
			MACSTR " dev_capab=0x%x group_capab=0x%x name='%s' "
			"listen_freq=%d",
			MAC2STR(dev->info.p2p_device_addr),
			dev->info.dev_capab, dev->info.group_capab,
			dev->info.device_name, dev->listen_freq);
	}

	dev->flags &= ~P2P_DEV_GROUP_CLIENT_ONLY;

	if (dev->flags & P2P_DEV_USER_REJECTED) {
		wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG,
			"P2P: Do not report rejected device");
		return;
	}

	p2p->cfg->dev_found(p2p->cfg->cb_ctx, addr, &dev->info,
			    !(dev->flags & P2P_DEV_REPORTED_ONCE));
	dev->flags |= P2P_DEV_REPORTED | P2P_DEV_REPORTED_ONCE;
}


void p2p_build_ssid(struct p2p_data *p2p, u8 *ssid, size_t *ssid_len)
{
	os_memcpy(ssid, P2P_WILDCARD_SSID, P2P_WILDCARD_SSID_LEN);
	p2p_random((char *) &ssid[P2P_WILDCARD_SSID_LEN], 2);
	os_memcpy(&ssid[P2P_WILDCARD_SSID_LEN + 2],
		  p2p->cfg->ssid_postfix, p2p->cfg->ssid_postfix_len);
	*ssid_len = P2P_WILDCARD_SSID_LEN + 2 + p2p->cfg->ssid_postfix_len;
}


int p2p_go_params(struct p2p_data *p2p, struct p2p_go_neg_results *params)
{
	p2p_build_ssid(p2p, params->ssid, &params->ssid_len);
	p2p_random(params->passphrase, 8);
	return 0;
}


void p2p_go_complete(struct p2p_data *p2p, struct p2p_device *peer)
{
	struct p2p_go_neg_results res;
	int go = peer->go_state == LOCAL_GO;
	struct p2p_channels intersection;
	int freqs;
	size_t i, j;

	wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG,
		"P2P: GO Negotiation with " MACSTR " completed (%s will be "
		"GO)", MAC2STR(peer->info.p2p_device_addr),
		go ? "local end" : "peer");

	os_memset(&res, 0, sizeof(res));
	res.role_go = go;
	os_memcpy(res.peer_device_addr, peer->info.p2p_device_addr, ETH_ALEN);
	os_memcpy(res.peer_interface_addr, peer->intended_addr, ETH_ALEN);
	res.wps_method = peer->wps_method;
	if (peer->flags & P2P_DEV_PREFER_PERSISTENT_GROUP) {
		if (peer->flags & P2P_DEV_PREFER_PERSISTENT_RECONN)
			res.persistent_group = 2;
		else
			res.persistent_group = 1;
	}

	if (go) {
		/* Setup AP mode for WPS provisioning */
		res.freq = p2p_channel_to_freq(p2p->cfg->country,
					       p2p->op_reg_class,
					       p2p->op_channel);
		os_memcpy(res.ssid, p2p->ssid, p2p->ssid_len);
		res.ssid_len = p2p->ssid_len;
		p2p_random(res.passphrase, 8);
	} else {
		res.freq = peer->oper_freq;
		if (p2p->ssid_len) {
			os_memcpy(res.ssid, p2p->ssid, p2p->ssid_len);
			res.ssid_len = p2p->ssid_len;
		}
	}

	p2p_channels_intersect(&p2p->channels, &peer->channels,
			       &intersection);
	freqs = 0;
	for (i = 0; i < intersection.reg_classes; i++) {
		struct p2p_reg_class *c = &intersection.reg_class[i];
		if (freqs + 1 == P2P_MAX_CHANNELS)
			break;
		for (j = 0; j < c->channels; j++) {
			int freq;
			if (freqs + 1 == P2P_MAX_CHANNELS)
				break;
			freq = p2p_channel_to_freq(peer->country, c->reg_class,
						   c->channel[j]);
			if (freq < 0)
				continue;
			res.freq_list[freqs++] = freq;
		}
	}

	res.peer_config_timeout = go ? peer->client_timeout : peer->go_timeout;

	p2p_clear_timeout(p2p);
	p2p->ssid_set = 0;
	peer->go_neg_req_sent = 0;
	peer->wps_method = WPS_NOT_READY;

	p2p_set_state(p2p, P2P_PROVISIONING);
	p2p->cfg->go_neg_completed(p2p->cfg->cb_ctx, &res);
}


static void p2p_rx_p2p_action(struct p2p_data *p2p, const u8 *sa,
			      const u8 *data, size_t len, int rx_freq)
{
	wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG,
		"P2P: RX P2P Public Action from " MACSTR, MAC2STR(sa));
	wpa_hexdump(MSG_MSGDUMP, "P2P: P2P Public Action contents", data, len);

	if (len < 1)
		return;

	switch (data[0]) {
	case P2P_GO_NEG_REQ:
		p2p_process_go_neg_req(p2p, sa, data + 1, len - 1, rx_freq);
		break;
	case P2P_GO_NEG_RESP:
		p2p_process_go_neg_resp(p2p, sa, data + 1, len - 1, rx_freq);
		break;
	case P2P_GO_NEG_CONF:
		p2p_process_go_neg_conf(p2p, sa, data + 1, len - 1);
		break;
	case P2P_INVITATION_REQ:
		p2p_process_invitation_req(p2p, sa, data + 1, len - 1,
					   rx_freq);
		break;
	case P2P_INVITATION_RESP:
		p2p_process_invitation_resp(p2p, sa, data + 1, len - 1);
		break;
	case P2P_PROV_DISC_REQ:
		p2p_process_prov_disc_req(p2p, sa, data + 1, len - 1, rx_freq);
		break;
	case P2P_PROV_DISC_RESP:
		p2p_process_prov_disc_resp(p2p, sa, data + 1, len - 1);
		break;
	case P2P_DEV_DISC_REQ:
		p2p_process_dev_disc_req(p2p, sa, data + 1, len - 1, rx_freq);
		break;
	case P2P_DEV_DISC_RESP:
		p2p_process_dev_disc_resp(p2p, sa, data + 1, len - 1);
		break;
	default:
		wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG,
			"P2P: Unsupported P2P Public Action frame type %d",
			data[0]);
		break;
	}
}


static void p2p_rx_action_public(struct p2p_data *p2p, const u8 *da,
				 const u8 *sa, const u8 *bssid, const u8 *data,
				 size_t len, int freq)
{
	if (len < 1)
		return;

	switch (data[0]) {
	case WLAN_PA_VENDOR_SPECIFIC:
		data++;
		len--;
		if (len < 3)
			return;
		if (WPA_GET_BE24(data) != OUI_WFA)
			return;

		data += 3;
		len -= 3;
		if (len < 1)
			return;

		if (*data != P2P_OUI_TYPE)
			return;

		p2p_rx_p2p_action(p2p, sa, data + 1, len - 1, freq);
		break;
	case WLAN_PA_GAS_INITIAL_REQ:
		p2p_rx_gas_initial_req(p2p, sa, data + 1, len - 1, freq);
		break;
	case WLAN_PA_GAS_INITIAL_RESP:
		p2p_rx_gas_initial_resp(p2p, sa, data + 1, len - 1, freq);
		break;
	case WLAN_PA_GAS_COMEBACK_REQ:
		p2p_rx_gas_comeback_req(p2p, sa, data + 1, len - 1, freq);
		break;
	case WLAN_PA_GAS_COMEBACK_RESP:
		p2p_rx_gas_comeback_resp(p2p, sa, data + 1, len - 1, freq);
		break;
	}
}


void p2p_rx_action(struct p2p_data *p2p, const u8 *da, const u8 *sa,
		   const u8 *bssid, u8 category,
		   const u8 *data, size_t len, int freq)
{
	if (category == WLAN_ACTION_PUBLIC) {
		p2p_rx_action_public(p2p, da, sa, bssid, data, len, freq);
		return;
	}

	if (category != WLAN_ACTION_VENDOR_SPECIFIC)
		return;

	if (len < 4)
		return;

	if (WPA_GET_BE24(data) != OUI_WFA)
		return;
	data += 3;
	len -= 3;

	if (*data != P2P_OUI_TYPE)
		return;
	data++;
	len--;

	/* P2P action frame */
	wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG,
		"P2P: RX P2P Action from " MACSTR, MAC2STR(sa));
	wpa_hexdump(MSG_MSGDUMP, "P2P: P2P Action contents", data, len);

	if (len < 1)
		return;
	switch (data[0]) {
	case P2P_NOA:
		wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG,
			"P2P: Received P2P Action - Notice of Absence");
		/* TODO */
		break;
	case P2P_PRESENCE_REQ:
		p2p_process_presence_req(p2p, da, sa, data + 1, len - 1, freq);
		break;
	case P2P_PRESENCE_RESP:
		p2p_process_presence_resp(p2p, da, sa, data + 1, len - 1);
		break;
	case P2P_GO_DISC_REQ:
		p2p_process_go_disc_req(p2p, da, sa, data + 1, len - 1, freq);
		break;
	default:
		wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG,
			"P2P: Received P2P Action - unknown type %u", data[0]);
		break;
	}
}


static void p2p_go_neg_start(void *eloop_ctx, void *timeout_ctx)
{
	struct p2p_data *p2p = eloop_ctx;
	if (p2p->go_neg_peer == NULL)
		return;
	p2p->cfg->stop_listen(p2p->cfg->cb_ctx);
	p2p->go_neg_peer->status = P2P_SC_SUCCESS;
	p2p_connect_send(p2p, p2p->go_neg_peer);
}


static void p2p_invite_start(void *eloop_ctx, void *timeout_ctx)
{
	struct p2p_data *p2p = eloop_ctx;
	if (p2p->invite_peer == NULL)
		return;
	p2p->cfg->stop_listen(p2p->cfg->cb_ctx);
	p2p_invite_send(p2p, p2p->invite_peer, p2p->invite_go_dev_addr);
}


static void p2p_add_dev_from_probe_req(struct p2p_data *p2p, const u8 *addr,
				       const u8 *ie, size_t ie_len)
{
	struct p2p_message msg;
	struct p2p_device *dev;

	os_memset(&msg, 0, sizeof(msg));
	if (p2p_parse_ies(ie, ie_len, &msg) < 0 || msg.p2p_attributes == NULL)
	{
		p2p_parse_free(&msg);
		return; /* not a P2P probe */
	}

	if (msg.ssid == NULL || msg.ssid[1] != P2P_WILDCARD_SSID_LEN ||
	    os_memcmp(msg.ssid + 2, P2P_WILDCARD_SSID, P2P_WILDCARD_SSID_LEN)
	    != 0) {
		/* The Probe Request is not part of P2P Device Discovery. It is
		 * not known whether the source address of the frame is the P2P
		 * Device Address or P2P Interface Address. Do not add a new
		 * peer entry based on this frames.
		 */
		p2p_parse_free(&msg);
		return;
	}

	dev = p2p_get_device(p2p, addr);
	if (dev) {
		if (dev->country[0] == 0 && msg.listen_channel)
			os_memcpy(dev->country, msg.listen_channel, 3);
		os_get_time(&dev->last_seen);
		p2p_parse_free(&msg);
		return; /* already known */
	}

	dev = p2p_create_device(p2p, addr);
	if (dev == NULL) {
		p2p_parse_free(&msg);
		return;
	}

	os_get_time(&dev->last_seen);
	dev->flags |= P2P_DEV_PROBE_REQ_ONLY;

	if (msg.listen_channel) {
		os_memcpy(dev->country, msg.listen_channel, 3);
		dev->listen_freq = p2p_channel_to_freq(dev->country,
						       msg.listen_channel[3],
						       msg.listen_channel[4]);
	}

	p2p_copy_wps_info(dev, 1, &msg);

	if (msg.wfd_subelems) {
		wpabuf_free(dev->info.wfd_subelems);
		dev->info.wfd_subelems = wpabuf_dup(msg.wfd_subelems);
	}

	p2p_parse_free(&msg);

	wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG,
		"P2P: Created device entry based on Probe Req: " MACSTR
		" dev_capab=0x%x group_capab=0x%x name='%s' listen_freq=%d",
		MAC2STR(dev->info.p2p_device_addr), dev->info.dev_capab,
		dev->info.group_capab, dev->info.device_name,
		dev->listen_freq);
}


struct p2p_device * p2p_add_dev_from_go_neg_req(struct p2p_data *p2p,
						const u8 *addr,
						struct p2p_message *msg)
{
	struct p2p_device *dev;

	dev = p2p_get_device(p2p, addr);
	if (dev) {
		os_get_time(&dev->last_seen);
		return dev; /* already known */
	}

	dev = p2p_create_device(p2p, addr);
	if (dev == NULL)
		return NULL;

	p2p_add_dev_info(p2p, addr, dev, msg);

	return dev;
}


static int dev_type_match(const u8 *dev_type, const u8 *req_dev_type)
{
	if (os_memcmp(dev_type, req_dev_type, WPS_DEV_TYPE_LEN) == 0)
		return 1;
	if (os_memcmp(dev_type, req_dev_type, 2) == 0 &&
	    WPA_GET_BE32(&req_dev_type[2]) == 0 &&
	    WPA_GET_BE16(&req_dev_type[6]) == 0)
		return 1; /* Category match with wildcard OUI/sub-category */
	return 0;
}


int dev_type_list_match(const u8 *dev_type, const u8 *req_dev_type[],
			size_t num_req_dev_type)
{
	size_t i;
	for (i = 0; i < num_req_dev_type; i++) {
		if (dev_type_match(dev_type, req_dev_type[i]))
			return 1;
	}
	return 0;
}


/**
 * p2p_match_dev_type - Match local device type with requested type
 * @p2p: P2P module context from p2p_init()
 * @wps: WPS TLVs from Probe Request frame (concatenated WPS IEs)
 * Returns: 1 on match, 0 on mismatch
 *
 * This function can be used to match the Requested Device Type attribute in
 * WPS IE with the local device types for deciding whether to reply to a Probe
 * Request frame.
 */
int p2p_match_dev_type(struct p2p_data *p2p, struct wpabuf *wps)
{
	struct wps_parse_attr attr;
	size_t i;

	if (wps_parse_msg(wps, &attr))
		return 1; /* assume no Requested Device Type attributes */

	if (attr.num_req_dev_type == 0)
		return 1; /* no Requested Device Type attributes -> match */

	if (dev_type_list_match(p2p->cfg->pri_dev_type, attr.req_dev_type,
				attr.num_req_dev_type))
		return 1; /* Own Primary Device Type matches */

	for (i = 0; i < p2p->cfg->num_sec_dev_types; i++)
		if (dev_type_list_match(p2p->cfg->sec_dev_type[i],
					attr.req_dev_type,
					attr.num_req_dev_type))
		return 1; /* Own Secondary Device Type matches */

	/* No matching device type found */
	return 0;
}


struct wpabuf * p2p_build_probe_resp_ies(struct p2p_data *p2p)
{
	struct wpabuf *buf;
	u8 *len;
	int pw_id = -1;
	size_t extra = 0;

#ifdef CONFIG_WIFI_DISPLAY
	if (p2p->wfd_ie_probe_resp)
		extra = wpabuf_len(p2p->wfd_ie_probe_resp);
#endif /* CONFIG_WIFI_DISPLAY */

	buf = wpabuf_alloc(1000 + extra);
	if (buf == NULL)
		return NULL;

	if (p2p->go_neg_peer) {
		/* Advertise immediate availability of WPS credential */
		pw_id = p2p_wps_method_pw_id(p2p->go_neg_peer->wps_method);
	}

	p2p_build_wps_ie(p2p, buf, pw_id, 1);

#ifdef CONFIG_WIFI_DISPLAY
	if (p2p->wfd_ie_probe_resp)
		wpabuf_put_buf(buf, p2p->wfd_ie_probe_resp);
#endif /* CONFIG_WIFI_DISPLAY */

	/* P2P IE */
	len = p2p_buf_add_ie_hdr(buf);
	p2p_buf_add_capability(buf, p2p->dev_capab &
			       ~P2P_DEV_CAPAB_CLIENT_DISCOVERABILITY, 0);
	if (p2p->ext_listen_interval)
		p2p_buf_add_ext_listen_timing(buf, p2p->ext_listen_period,
					      p2p->ext_listen_interval);
	p2p_buf_add_device_info(buf, p2p, NULL);
	p2p_buf_update_ie_hdr(buf, len);

	return buf;
}


static int is_11b(u8 rate)
{
	return rate == 0x02 || rate == 0x04 || rate == 0x0b || rate == 0x16;
}


static int supp_rates_11b_only(struct ieee802_11_elems *elems)
{
	int num_11b = 0, num_others = 0;
	int i;

	if (elems->supp_rates == NULL && elems->ext_supp_rates == NULL)
		return 0;

	for (i = 0; elems->supp_rates && i < elems->supp_rates_len; i++) {
		if (is_11b(elems->supp_rates[i]))
			num_11b++;
		else
			num_others++;
	}

	for (i = 0; elems->ext_supp_rates && i < elems->ext_supp_rates_len;
	     i++) {
		if (is_11b(elems->ext_supp_rates[i]))
			num_11b++;
		else
			num_others++;
	}

	return num_11b > 0 && num_others == 0;
}


static enum p2p_probe_req_status
p2p_reply_probe(struct p2p_data *p2p, const u8 *addr, const u8 *dst,
		const u8 *bssid, const u8 *ie, size_t ie_len)
{
	struct ieee802_11_elems elems;
	struct wpabuf *buf;
	struct ieee80211_mgmt *resp;
	struct p2p_message msg;
	struct wpabuf *ies;

	if (!p2p->in_listen || !p2p->drv_in_listen) {
		/* not in Listen state - ignore Probe Request */
		return P2P_PREQ_NOT_LISTEN;
	}

	if (ieee802_11_parse_elems((u8 *) ie, ie_len, &elems, 0) ==
	    ParseFailed) {
		/* Ignore invalid Probe Request frames */
		return P2P_PREQ_MALFORMED;
	}

	if (elems.p2p == NULL) {
		/* not a P2P probe - ignore it */
		return P2P_PREQ_NOT_P2P;
	}

	if (dst && !is_broadcast_ether_addr(dst) &&
	    os_memcmp(dst, p2p->cfg->dev_addr, ETH_ALEN) != 0) {
		/* Not sent to the broadcast address or our P2P Device Address
		 */
		return P2P_PREQ_NOT_PROCESSED;
	}

	if (bssid && !is_broadcast_ether_addr(bssid)) {
		/* Not sent to the Wildcard BSSID */
		return P2P_PREQ_NOT_PROCESSED;
	}

	if (elems.ssid == NULL || elems.ssid_len != P2P_WILDCARD_SSID_LEN ||
	    os_memcmp(elems.ssid, P2P_WILDCARD_SSID, P2P_WILDCARD_SSID_LEN) !=
	    0) {
		/* not using P2P Wildcard SSID - ignore */
		return P2P_PREQ_NOT_PROCESSED;
	}

	if (supp_rates_11b_only(&elems)) {
		/* Indicates support for 11b rates only */
		return P2P_PREQ_NOT_P2P;
	}

	os_memset(&msg, 0, sizeof(msg));
	if (p2p_parse_ies(ie, ie_len, &msg) < 0) {
		/* Could not parse P2P attributes */
		return P2P_PREQ_NOT_P2P;
	}

	if (msg.device_id &&
	    os_memcmp(msg.device_id, p2p->cfg->dev_addr, ETH_ALEN) != 0) {
		/* Device ID did not match */
		p2p_parse_free(&msg);
		return P2P_PREQ_NOT_PROCESSED;
	}

	/* Check Requested Device Type match */
	if (msg.wps_attributes &&
	    !p2p_match_dev_type(p2p, msg.wps_attributes)) {
		/* No match with Requested Device Type */
		p2p_parse_free(&msg);
		return P2P_PREQ_NOT_PROCESSED;
	}
	p2p_parse_free(&msg);

	if (!p2p->cfg->send_probe_resp) {
		/* Response generated elsewhere */
		return P2P_PREQ_NOT_PROCESSED;
	}

	wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG,
		"P2P: Reply to P2P Probe Request in Listen state");

	/*
	 * We do not really have a specific BSS that this frame is advertising,
	 * so build a frame that has some information in valid format. This is
	 * really only used for discovery purposes, not to learn exact BSS
	 * parameters.
	 */
	ies = p2p_build_probe_resp_ies(p2p);
	if (ies == NULL)
		return P2P_PREQ_NOT_PROCESSED;

	buf = wpabuf_alloc(200 + wpabuf_len(ies));
	if (buf == NULL) {
		wpabuf_free(ies);
		return P2P_PREQ_NOT_PROCESSED;
	}

	resp = NULL;
	resp = wpabuf_put(buf, resp->u.probe_resp.variable - (u8 *) resp);

	resp->frame_control = host_to_le16((WLAN_FC_TYPE_MGMT << 2) |
					   (WLAN_FC_STYPE_PROBE_RESP << 4));
	os_memcpy(resp->da, addr, ETH_ALEN);
	os_memcpy(resp->sa, p2p->cfg->dev_addr, ETH_ALEN);
	os_memcpy(resp->bssid, p2p->cfg->dev_addr, ETH_ALEN);
	resp->u.probe_resp.beacon_int = host_to_le16(100);
	/* hardware or low-level driver will setup seq_ctrl and timestamp */
	resp->u.probe_resp.capab_info =
		host_to_le16(WLAN_CAPABILITY_SHORT_PREAMBLE |
			     WLAN_CAPABILITY_PRIVACY |
			     WLAN_CAPABILITY_SHORT_SLOT_TIME);

	wpabuf_put_u8(buf, WLAN_EID_SSID);
	wpabuf_put_u8(buf, P2P_WILDCARD_SSID_LEN);
	wpabuf_put_data(buf, P2P_WILDCARD_SSID, P2P_WILDCARD_SSID_LEN);

	wpabuf_put_u8(buf, WLAN_EID_SUPP_RATES);
	wpabuf_put_u8(buf, 8);
	wpabuf_put_u8(buf, (60 / 5) | 0x80);
	wpabuf_put_u8(buf, 90 / 5);
	wpabuf_put_u8(buf, (120 / 5) | 0x80);
	wpabuf_put_u8(buf, 180 / 5);
	wpabuf_put_u8(buf, (240 / 5) | 0x80);
	wpabuf_put_u8(buf, 360 / 5);
	wpabuf_put_u8(buf, 480 / 5);
	wpabuf_put_u8(buf, 540 / 5);

	wpabuf_put_u8(buf, WLAN_EID_DS_PARAMS);
	wpabuf_put_u8(buf, 1);
	wpabuf_put_u8(buf, p2p->cfg->channel);

	wpabuf_put_buf(buf, ies);
	wpabuf_free(ies);

	p2p->cfg->send_probe_resp(p2p->cfg->cb_ctx, buf);

	wpabuf_free(buf);

	return P2P_PREQ_NOT_PROCESSED;
}


enum p2p_probe_req_status
p2p_probe_req_rx(struct p2p_data *p2p, const u8 *addr, const u8 *dst,
		 const u8 *bssid, const u8 *ie, size_t ie_len)
{
	enum p2p_probe_req_status res;

	p2p_add_dev_from_probe_req(p2p, addr, ie, ie_len);

	res = p2p_reply_probe(p2p, addr, dst, bssid, ie, ie_len);

	if ((p2p->state == P2P_CONNECT || p2p->state == P2P_CONNECT_LISTEN) &&
	    p2p->go_neg_peer &&
	    os_memcmp(addr, p2p->go_neg_peer->info.p2p_device_addr, ETH_ALEN)
	    == 0) {
		/* Received a Probe Request from GO Negotiation peer */
		wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG,
			"P2P: Found GO Negotiation peer - try to start GO "
			"negotiation from timeout");
		eloop_register_timeout(0, 0, p2p_go_neg_start, p2p, NULL);
		return P2P_PREQ_PROCESSED;
	}

	if ((p2p->state == P2P_INVITE || p2p->state == P2P_INVITE_LISTEN) &&
	    p2p->invite_peer &&
	    os_memcmp(addr, p2p->invite_peer->info.p2p_device_addr, ETH_ALEN)
	    == 0) {
		/* Received a Probe Request from Invite peer */
		wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG,
			"P2P: Found Invite peer - try to start Invite from "
			"timeout");
		eloop_register_timeout(0, 0, p2p_invite_start, p2p, NULL);
		return P2P_PREQ_PROCESSED;
	}

	return res;
}


static int p2p_assoc_req_ie_wlan_ap(struct p2p_data *p2p, const u8 *bssid,
				    u8 *buf, size_t len, struct wpabuf *p2p_ie)
{
	struct wpabuf *tmp;
	u8 *lpos;
	size_t tmplen;
	int res;
	u8 group_capab;

	if (p2p_ie == NULL)
		return 0; /* WLAN AP is not a P2P manager */

	/*
	 * (Re)Association Request - P2P IE
	 * P2P Capability attribute (shall be present)
	 * P2P Interface attribute (present if concurrent device and
	 *	P2P Management is enabled)
	 */
	tmp = wpabuf_alloc(200);
	if (tmp == NULL)
		return -1;

	lpos = p2p_buf_add_ie_hdr(tmp);
	group_capab = 0;
	if (p2p->num_groups > 0) {
		group_capab |= P2P_GROUP_CAPAB_GROUP_OWNER;
		if ((p2p->dev_capab & P2P_DEV_CAPAB_CONCURRENT_OPER) &&
		    (p2p->dev_capab & P2P_DEV_CAPAB_INFRA_MANAGED) &&
		    p2p->cross_connect)
			group_capab |= P2P_GROUP_CAPAB_CROSS_CONN;
	}
	p2p_buf_add_capability(tmp, p2p->dev_capab, group_capab);
	if ((p2p->dev_capab & P2P_DEV_CAPAB_CONCURRENT_OPER) &&
	    (p2p->dev_capab & P2P_DEV_CAPAB_INFRA_MANAGED))
		p2p_buf_add_p2p_interface(tmp, p2p);
	p2p_buf_update_ie_hdr(tmp, lpos);

	tmplen = wpabuf_len(tmp);
	if (tmplen > len)
		res = -1;
	else {
		os_memcpy(buf, wpabuf_head(tmp), tmplen);
		res = tmplen;
	}
	wpabuf_free(tmp);

	return res;
}


int p2p_assoc_req_ie(struct p2p_data *p2p, const u8 *bssid, u8 *buf,
		     size_t len, int p2p_group, struct wpabuf *p2p_ie)
{
	struct wpabuf *tmp;
	u8 *lpos;
	struct p2p_device *peer;
	size_t tmplen;
	int res;
	size_t extra = 0;

	if (!p2p_group)
		return p2p_assoc_req_ie_wlan_ap(p2p, bssid, buf, len, p2p_ie);

#ifdef CONFIG_WIFI_DISPLAY
	if (p2p->wfd_ie_assoc_req)
		extra = wpabuf_len(p2p->wfd_ie_assoc_req);
#endif /* CONFIG_WIFI_DISPLAY */

	/*
	 * (Re)Association Request - P2P IE
	 * P2P Capability attribute (shall be present)
	 * Extended Listen Timing (may be present)
	 * P2P Device Info attribute (shall be present)
	 */
	tmp = wpabuf_alloc(200 + extra);
	if (tmp == NULL)
		return -1;

#ifdef CONFIG_WIFI_DISPLAY
	if (p2p->wfd_ie_assoc_req)
		wpabuf_put_buf(tmp, p2p->wfd_ie_assoc_req);
#endif /* CONFIG_WIFI_DISPLAY */

	peer = bssid ? p2p_get_device(p2p, bssid) : NULL;

	lpos = p2p_buf_add_ie_hdr(tmp);
	p2p_buf_add_capability(tmp, p2p->dev_capab, 0);
	if (p2p->ext_listen_interval)
		p2p_buf_add_ext_listen_timing(tmp, p2p->ext_listen_period,
					      p2p->ext_listen_interval);
	p2p_buf_add_device_info(tmp, p2p, peer);
	p2p_buf_update_ie_hdr(tmp, lpos);

	tmplen = wpabuf_len(tmp);
	if (tmplen > len)
		res = -1;
	else {
		os_memcpy(buf, wpabuf_head(tmp), tmplen);
		res = tmplen;
	}
	wpabuf_free(tmp);

	return res;
}


int p2p_scan_result_text(const u8 *ies, size_t ies_len, char *buf, char *end)
{
	struct wpabuf *p2p_ie;
	int ret;

	p2p_ie = ieee802_11_vendor_ie_concat(ies, ies_len, P2P_IE_VENDOR_TYPE);
	if (p2p_ie == NULL)
		return 0;

	ret = p2p_attr_text(p2p_ie, buf, end);
	wpabuf_free(p2p_ie);
	return ret;
}


int p2p_parse_dev_addr_in_p2p_ie(struct wpabuf *p2p_ie, u8 *dev_addr)
{
	struct p2p_message msg;

	os_memset(&msg, 0, sizeof(msg));
	if (p2p_parse_p2p_ie(p2p_ie, &msg))
		return -1;

	if (msg.p2p_device_addr) {
		os_memcpy(dev_addr, msg.p2p_device_addr, ETH_ALEN);
		return 0;
	} else if (msg.device_id) {
		os_memcpy(dev_addr, msg.device_id, ETH_ALEN);
		return 0;
	}
	return -1;
}


int p2p_parse_dev_addr(const u8 *ies, size_t ies_len, u8 *dev_addr)
{
	struct wpabuf *p2p_ie;
	int ret;

	p2p_ie = ieee802_11_vendor_ie_concat(ies, ies_len,
					     P2P_IE_VENDOR_TYPE);
	if (p2p_ie == NULL)
		return -1;
	ret = p2p_parse_dev_addr_in_p2p_ie(p2p_ie, dev_addr);
	wpabuf_free(p2p_ie);
	return ret;
}


static void p2p_clear_go_neg(struct p2p_data *p2p)
{
	p2p->go_neg_peer = NULL;
	p2p_clear_timeout(p2p);
	p2p_set_state(p2p, P2P_IDLE);
}


void p2p_wps_success_cb(struct p2p_data *p2p, const u8 *mac_addr)
{
	if (p2p->go_neg_peer == NULL) {
		wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG,
			"P2P: No pending Group Formation - "
			"ignore WPS registration success notification");
		return; /* No pending Group Formation */
	}

	if (os_memcmp(mac_addr, p2p->go_neg_peer->intended_addr, ETH_ALEN) !=
	    0) {
		wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG,
			"P2P: Ignore WPS registration success notification "
			"for " MACSTR " (GO Negotiation peer " MACSTR ")",
			MAC2STR(mac_addr),
			MAC2STR(p2p->go_neg_peer->intended_addr));
		return; /* Ignore unexpected peer address */
	}

	wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG,
		"P2P: Group Formation completed successfully with " MACSTR,
		MAC2STR(mac_addr));

	p2p_clear_go_neg(p2p);
}


void p2p_group_formation_failed(struct p2p_data *p2p)
{
	if (p2p->go_neg_peer == NULL) {
		wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG,
			"P2P: No pending Group Formation - "
			"ignore group formation failure notification");
		return; /* No pending Group Formation */
	}

	wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG,
		"P2P: Group Formation failed with " MACSTR,
		MAC2STR(p2p->go_neg_peer->intended_addr));

	p2p_clear_go_neg(p2p);
}


struct p2p_data * p2p_init(const struct p2p_config *cfg)
{
	struct p2p_data *p2p;

	if (cfg->max_peers < 1)
		return NULL;

	p2p = os_zalloc(sizeof(*p2p) + sizeof(*cfg));
	if (p2p == NULL)
		return NULL;
	p2p->cfg = (struct p2p_config *) (p2p + 1);
	os_memcpy(p2p->cfg, cfg, sizeof(*cfg));
	if (cfg->dev_name)
		p2p->cfg->dev_name = os_strdup(cfg->dev_name);
	if (cfg->manufacturer)
		p2p->cfg->manufacturer = os_strdup(cfg->manufacturer);
	if (cfg->model_name)
		p2p->cfg->model_name = os_strdup(cfg->model_name);
	if (cfg->model_number)
		p2p->cfg->model_number = os_strdup(cfg->model_number);
	if (cfg->serial_number)
		p2p->cfg->serial_number = os_strdup(cfg->serial_number);
	if (cfg->pref_chan) {
		p2p->cfg->pref_chan = os_malloc(cfg->num_pref_chan *
						sizeof(struct p2p_channel));
		if (p2p->cfg->pref_chan) {
			os_memcpy(p2p->cfg->pref_chan, cfg->pref_chan,
				  cfg->num_pref_chan *
				  sizeof(struct p2p_channel));
		} else
			p2p->cfg->num_pref_chan = 0;
	}

#ifdef ANDROID_P2P
	/* 100ms listen time is too less to receive the response frames in some scenarios
	 * increasing min listen time to 200ms.
	 */
	p2p->min_disc_int = 2;
	/* SD_FAIR_POLICY: Initializing the SD current serviced pointer to NULL */
	p2p->sd_dev_list = NULL;
#else
	p2p->min_disc_int = 1;
#endif
	p2p->max_disc_int = 3;

	os_get_random(&p2p->next_tie_breaker, 1);
	p2p->next_tie_breaker &= 0x01;
	if (cfg->sd_request)
		p2p->dev_capab |= P2P_DEV_CAPAB_SERVICE_DISCOVERY;
	p2p->dev_capab |= P2P_DEV_CAPAB_INVITATION_PROCEDURE;
	if (cfg->concurrent_operations)
		p2p->dev_capab |= P2P_DEV_CAPAB_CONCURRENT_OPER;
	p2p->dev_capab |= P2P_DEV_CAPAB_CLIENT_DISCOVERABILITY;

	dl_list_init(&p2p->devices);

	eloop_register_timeout(P2P_PEER_EXPIRATION_INTERVAL, 0,
			       p2p_expiration_timeout, p2p, NULL);

	p2p->go_timeout = 100;
	p2p->client_timeout = 20;

	return p2p;
}


void p2p_deinit(struct p2p_data *p2p)
{
#ifdef CONFIG_WIFI_DISPLAY
	wpabuf_free(p2p->wfd_ie_beacon);
	wpabuf_free(p2p->wfd_ie_probe_req);
	wpabuf_free(p2p->wfd_ie_probe_resp);
	wpabuf_free(p2p->wfd_ie_assoc_req);
	wpabuf_free(p2p->wfd_ie_invitation);
	wpabuf_free(p2p->wfd_ie_prov_disc_req);
	wpabuf_free(p2p->wfd_ie_prov_disc_resp);
	wpabuf_free(p2p->wfd_ie_go_neg);
	wpabuf_free(p2p->wfd_dev_info);
	wpabuf_free(p2p->wfd_assoc_bssid);
	wpabuf_free(p2p->wfd_coupled_sink_info);
#endif /* CONFIG_WIFI_DISPLAY */

	eloop_cancel_timeout(p2p_expiration_timeout, p2p, NULL);
	eloop_cancel_timeout(p2p_ext_listen_timeout, p2p, NULL);
	eloop_cancel_timeout(p2p_scan_timeout, p2p, NULL);
	p2p_flush(p2p);
	p2p_free_req_dev_types(p2p);
	os_free(p2p->cfg->dev_name);
	os_free(p2p->cfg->manufacturer);
	os_free(p2p->cfg->model_name);
	os_free(p2p->cfg->model_number);
	os_free(p2p->cfg->serial_number);
	os_free(p2p->cfg->pref_chan);
	os_free(p2p->groups);
	wpabuf_free(p2p->sd_resp);
	os_free(p2p->after_scan_tx);
	p2p_remove_wps_vendor_extensions(p2p);
	os_free(p2p);
}


void p2p_flush(struct p2p_data *p2p)
{
	struct p2p_device *dev, *prev;
	p2p_stop_find(p2p);
	dl_list_for_each_safe(dev, prev, &p2p->devices, struct p2p_device,
			      list) {
		dl_list_del(&dev->list);
		p2p_device_free(p2p, dev);
	}
#ifdef ANDROID_P2P
	/* SD_FAIR_POLICY: Initializing the SD current serviced pointer to NULL */
	p2p->sd_dev_list = NULL;
#endif
	p2p_free_sd_queries(p2p);
	os_free(p2p->after_scan_tx);
	p2p->after_scan_tx = NULL;
}


int p2p_unauthorize(struct p2p_data *p2p, const u8 *addr)
{
	struct p2p_device *dev;

	dev = p2p_get_device(p2p, addr);
	if (dev == NULL)
		return -1;

	wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG, "P2P: Unauthorizing " MACSTR,
		MAC2STR(addr));

	if (p2p->go_neg_peer == dev)
		p2p->go_neg_peer = NULL;

	dev->wps_method = WPS_NOT_READY;
	dev->flags &= ~P2P_DEV_WAIT_GO_NEG_RESPONSE;
	dev->flags &= ~P2P_DEV_WAIT_GO_NEG_CONFIRM;

	/* Check if after_scan_tx is for this peer. If so free it */
	if (p2p->after_scan_tx &&
	    os_memcmp(addr, p2p->after_scan_tx->dst, ETH_ALEN) == 0) {
		os_free(p2p->after_scan_tx);
		p2p->after_scan_tx = NULL;
	}

	return 0;
}


int p2p_set_dev_name(struct p2p_data *p2p, const char *dev_name)
{
	os_free(p2p->cfg->dev_name);
	if (dev_name) {
		p2p->cfg->dev_name = os_strdup(dev_name);
		if (p2p->cfg->dev_name == NULL)
			return -1;
	} else
		p2p->cfg->dev_name = NULL;
	return 0;
}


int p2p_set_manufacturer(struct p2p_data *p2p, const char *manufacturer)
{
	os_free(p2p->cfg->manufacturer);
	p2p->cfg->manufacturer = NULL;
	if (manufacturer) {
		p2p->cfg->manufacturer = os_strdup(manufacturer);
		if (p2p->cfg->manufacturer == NULL)
			return -1;
	}

	return 0;
}


int p2p_set_model_name(struct p2p_data *p2p, const char *model_name)
{
	os_free(p2p->cfg->model_name);
	p2p->cfg->model_name = NULL;
	if (model_name) {
		p2p->cfg->model_name = os_strdup(model_name);
		if (p2p->cfg->model_name == NULL)
			return -1;
	}

	return 0;
}


int p2p_set_model_number(struct p2p_data *p2p, const char *model_number)
{
	os_free(p2p->cfg->model_number);
	p2p->cfg->model_number = NULL;
	if (model_number) {
		p2p->cfg->model_number = os_strdup(model_number);
		if (p2p->cfg->model_number == NULL)
			return -1;
	}

	return 0;
}


int p2p_set_serial_number(struct p2p_data *p2p, const char *serial_number)
{
	os_free(p2p->cfg->serial_number);
	p2p->cfg->serial_number = NULL;
	if (serial_number) {
		p2p->cfg->serial_number = os_strdup(serial_number);
		if (p2p->cfg->serial_number == NULL)
			return -1;
	}

	return 0;
}


void p2p_set_config_methods(struct p2p_data *p2p, u16 config_methods)
{
	p2p->cfg->config_methods = config_methods;
}


void p2p_set_uuid(struct p2p_data *p2p, const u8 *uuid)
{
	os_memcpy(p2p->cfg->uuid, uuid, 16);
}


int p2p_set_pri_dev_type(struct p2p_data *p2p, const u8 *pri_dev_type)
{
	os_memcpy(p2p->cfg->pri_dev_type, pri_dev_type, 8);
	return 0;
}


int p2p_set_sec_dev_types(struct p2p_data *p2p, const u8 dev_types[][8],
			  size_t num_dev_types)
{
	if (num_dev_types > P2P_SEC_DEVICE_TYPES)
		num_dev_types = P2P_SEC_DEVICE_TYPES;
	p2p->cfg->num_sec_dev_types = num_dev_types;
	os_memcpy(p2p->cfg->sec_dev_type, dev_types, num_dev_types * 8);
	return 0;
}


void p2p_remove_wps_vendor_extensions(struct p2p_data *p2p)
{
	int i;

	for (i = 0; i < P2P_MAX_WPS_VENDOR_EXT; i++) {
		wpabuf_free(p2p->wps_vendor_ext[i]);
		p2p->wps_vendor_ext[i] = NULL;
	}
}


int p2p_add_wps_vendor_extension(struct p2p_data *p2p,
				 const struct wpabuf *vendor_ext)
{
	int i;

	if (vendor_ext == NULL)
		return -1;

	for (i = 0; i < P2P_MAX_WPS_VENDOR_EXT; i++) {
		if (p2p->wps_vendor_ext[i] == NULL)
			break;
	}
	if (i >= P2P_MAX_WPS_VENDOR_EXT)
		return -1;

	p2p->wps_vendor_ext[i] = wpabuf_dup(vendor_ext);
	if (p2p->wps_vendor_ext[i] == NULL)
		return -1;

	return 0;
}


int p2p_set_country(struct p2p_data *p2p, const char *country)
{
	os_memcpy(p2p->cfg->country, country, 3);
	return 0;
}


void p2p_continue_find(struct p2p_data *p2p)
{
	struct p2p_device *dev;
#ifdef ANDROID_P2P
	int skip=1;
#endif
	p2p_set_state(p2p, P2P_SEARCH);
	dl_list_for_each(dev, &p2p->devices, struct p2p_device, list) {
#ifdef ANDROID_P2P
		/* SD_FAIR_POLICY: We need to give chance to all devices in the device list
		 * There may be a scenario, where a particular peer device have
		 * not registered any query response. When we send a SD request to such device,
		 * no response will be received. And if we continue to get probe responses from that device, 
		 * and if that device happens to be on top in our device list, 
		 * we will always continue to send SD requests always to that peer only. 
		 * We will not be able to send SD requests to other devices in that case. 
		 * This implementation keeps track of last serviced peer device. 
		 * And then takes the next one from the device list, in the next iteration.
		 */
		if (p2p->sd_dev_list && p2p->sd_dev_list != &p2p->devices) {
			if(skip) {
				if ((&dev->list == p2p->sd_dev_list) ) {
					skip = 0;
					if (dev->list.next == &p2p->devices)
						p2p->sd_dev_list = NULL;
				}
				continue;
			}
		}
		p2p->sd_dev_list = &dev->list;
		wpa_printf(MSG_DEBUG, "P2P: ### Servicing %p dev->flags 0x%x SD schedule %s devaddr " MACSTR,
			p2p->sd_dev_list, dev->flags, dev->flags & P2P_DEV_SD_SCHEDULE ? "TRUE": "FALSE",
			MAC2STR(dev->info.p2p_device_addr));
#endif
		if (dev->flags & P2P_DEV_SD_SCHEDULE) {
			if (p2p_start_sd(p2p, dev) == 0)
				return;
			else
				break;
		} else if (dev->req_config_methods &&
			   !(dev->flags & P2P_DEV_PD_FOR_JOIN)) {
			wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG, "P2P: Send "
				"pending Provision Discovery Request to "
				MACSTR " (config methods 0x%x)",
				MAC2STR(dev->info.p2p_device_addr),
				dev->req_config_methods);
			if (p2p_send_prov_disc_req(p2p, dev, 0, 0) == 0)
				return;
		}
	}

	p2p_listen_in_find(p2p);
}


static void p2p_sd_cb(struct p2p_data *p2p, int success)
{
	wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG,
		"P2P: Service Discovery Query TX callback: success=%d",
		success);
	p2p->pending_action_state = P2P_NO_PENDING_ACTION;

	if (!success) {
		if (p2p->sd_peer) {
			p2p->sd_peer->flags &= ~P2P_DEV_SD_SCHEDULE;
			p2p->sd_peer = NULL;
		}
		p2p_continue_find(p2p);
		return;
	}

	if (p2p->sd_peer == NULL) {
		wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG,
			"P2P: No SD peer entry known");
		p2p_continue_find(p2p);
		return;
	}

	/* Wait for response from the peer */
	p2p_set_state(p2p, P2P_SD_DURING_FIND);
	p2p_set_timeout(p2p, 0, 200000);
}


/**
 * p2p_retry_pd - Retry any pending provision disc requests in IDLE state
 * @p2p: P2P module context from p2p_init()
 */
static void p2p_retry_pd(struct p2p_data *p2p)
{
	struct p2p_device *dev;

	if (p2p->state != P2P_IDLE)
		return;

	/*
	 * Retry the prov disc req attempt only for the peer that the user had
	 * requested for and provided a join has not been initiated on it
	 * in the meantime.
	 */

	dl_list_for_each(dev, &p2p->devices, struct p2p_device, list) {
		if (os_memcmp(p2p->pending_pd_devaddr,
			      dev->info.p2p_device_addr, ETH_ALEN) != 0)
			continue;
		if (!dev->req_config_methods)
			continue;
		if (dev->flags & P2P_DEV_PD_FOR_JOIN)
			continue;

		wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG, "P2P: Send "
			"pending Provision Discovery Request to "
			MACSTR " (config methods 0x%x)",
			MAC2STR(dev->info.p2p_device_addr),
			dev->req_config_methods);
		p2p_send_prov_disc_req(p2p, dev, 0, 0);
		return;
	}
}


static void p2p_prov_disc_cb(struct p2p_data *p2p, int success)
{
	wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG,
		"P2P: Provision Discovery Request TX callback: success=%d",
		success);

	/*
	 * Postpone resetting the pending action state till after we actually
	 * time out. This allows us to take some action like notifying any
	 * interested parties about no response to the request.
	 *
	 * When the timer (below) goes off we check in IDLE, SEARCH, or
	 * LISTEN_ONLY state, which are the only allowed states to issue a PD
	 * requests in, if this was still pending and then raise notification.
	 */

	if (!success) {
		p2p->pending_action_state = P2P_NO_PENDING_ACTION;

		if (p2p->user_initiated_pd &&
		    (p2p->state == P2P_SEARCH || p2p->state == P2P_LISTEN_ONLY))
		{
			/* Retry request from timeout to avoid busy loops */
			p2p->pending_action_state = P2P_PENDING_PD;
			p2p_set_timeout(p2p, 0, 50000);
		} else if (p2p->state != P2P_IDLE)
			p2p_continue_find(p2p);
		else if (p2p->user_initiated_pd) {
			p2p->pending_action_state = P2P_PENDING_PD;
			p2p_set_timeout(p2p, 0, 300000);
		}
		return;
	}

	/*
	 * This postponing, of resetting pending_action_state, needs to be
	 * done only for user initiated PD requests and not internal ones.
	 */
	if (p2p->user_initiated_pd)
		p2p->pending_action_state = P2P_PENDING_PD;
	else
		p2p->pending_action_state = P2P_NO_PENDING_ACTION;

	/* Wait for response from the peer */
	if (p2p->state == P2P_SEARCH)
		p2p_set_state(p2p, P2P_PD_DURING_FIND);
	p2p_set_timeout(p2p, 0, 200000);
}


int p2p_scan_res_handler(struct p2p_data *p2p, const u8 *bssid, int freq,
			 int level, const u8 *ies, size_t ies_len)
{
	p2p_add_device(p2p, bssid, freq, level, ies, ies_len, 1);

	return 0;
}


void p2p_scan_res_handled(struct p2p_data *p2p)
{
	if (!p2p->p2p_scan_running) {
		wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG, "P2P: p2p_scan was not "
			"running, but scan results received");
	}
	p2p->p2p_scan_running = 0;
	eloop_cancel_timeout(p2p_scan_timeout, p2p, NULL);

	if (p2p_run_after_scan(p2p))
		return;
	if (p2p->state == P2P_SEARCH)
		p2p_continue_find(p2p);
}


void p2p_scan_ie(struct p2p_data *p2p, struct wpabuf *ies, const u8 *dev_id)
{
	u8 *len;

#ifdef CONFIG_WIFI_DISPLAY
	if (p2p->wfd_ie_probe_req)
		wpabuf_put_buf(ies, p2p->wfd_ie_probe_req);
#endif /* CONFIG_WIFI_DISPLAY */

	len = p2p_buf_add_ie_hdr(ies);
	p2p_buf_add_capability(ies, p2p->dev_capab &
			       ~P2P_DEV_CAPAB_CLIENT_DISCOVERABILITY, 0);
	if (dev_id)
		p2p_buf_add_device_id(ies, dev_id);
	if (p2p->cfg->reg_class && p2p->cfg->channel)
		p2p_buf_add_listen_channel(ies, p2p->cfg->country,
					   p2p->cfg->reg_class,
					   p2p->cfg->channel);
	if (p2p->ext_listen_interval)
		p2p_buf_add_ext_listen_timing(ies, p2p->ext_listen_period,
					      p2p->ext_listen_interval);
	/* TODO: p2p_buf_add_operating_channel() if GO */
	p2p_buf_update_ie_hdr(ies, len);
}


size_t p2p_scan_ie_buf_len(struct p2p_data *p2p)
{
	size_t len = 100;

#ifdef CONFIG_WIFI_DISPLAY
	if (p2p && p2p->wfd_ie_probe_req)
		len += wpabuf_len(p2p->wfd_ie_probe_req);
#endif /* CONFIG_WIFI_DISPLAY */

	return len;
}


int p2p_ie_text(struct wpabuf *p2p_ie, char *buf, char *end)
{
	return p2p_attr_text(p2p_ie, buf, end);
}


static void p2p_go_neg_req_cb(struct p2p_data *p2p, int success)
{
	struct p2p_device *dev = p2p->go_neg_peer;

	wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG,
		"P2P: GO Negotiation Request TX callback: success=%d",
		success);

	if (dev == NULL) {
		wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG,
			"P2P: No pending GO Negotiation");
		return;
	}

	if (success) {
		if (dev->flags & P2P_DEV_USER_REJECTED) {
			p2p_set_state(p2p, P2P_IDLE);
			return;
		}
	} else if (dev->go_neg_req_sent) {
		/* Cancel the increment from p2p_connect_send() on failure */
		dev->go_neg_req_sent--;
	}

	if (!success &&
	    (dev->info.dev_capab & P2P_DEV_CAPAB_CLIENT_DISCOVERABILITY) &&
	    !is_zero_ether_addr(dev->member_in_go_dev)) {
		wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG,
			"P2P: Peer " MACSTR " did not acknowledge request - "
			"try to use device discoverability through its GO",
			MAC2STR(dev->info.p2p_device_addr));
		p2p->cfg->send_action_done(p2p->cfg->cb_ctx);
		p2p_send_dev_disc_req(p2p, dev);
		return;
	}

	/*
	 * Use P2P find, if needed, to find the other device from its listen
	 * channel.
	 */
	p2p_set_state(p2p, P2P_CONNECT);
	p2p_set_timeout(p2p, 0, success ? 200000 : 100000);
}


static void p2p_go_neg_resp_cb(struct p2p_data *p2p, int success)
{
	wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG,
		"P2P: GO Negotiation Response TX callback: success=%d",
		success);
	if (!p2p->go_neg_peer && p2p->state == P2P_PROVISIONING) {
		wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG,
			"P2P: Ignore TX callback event - GO Negotiation is "
			"not running anymore");
		return;
	}
	p2p_set_state(p2p, P2P_CONNECT);
	p2p_set_timeout(p2p, 0, 250000);
}


static void p2p_go_neg_resp_failure_cb(struct p2p_data *p2p, int success)
{
	wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG,
		"P2P: GO Negotiation Response (failure) TX callback: "
		"success=%d", success);
	if (p2p->go_neg_peer && p2p->go_neg_peer->status != P2P_SC_SUCCESS) {
		p2p_go_neg_failed(p2p, p2p->go_neg_peer,
				  p2p->go_neg_peer->status);
	}
}


static void p2p_go_neg_conf_cb(struct p2p_data *p2p,
			       enum p2p_send_action_result result)
{
	struct p2p_device *dev;

	wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG,
		"P2P: GO Negotiation Confirm TX callback: result=%d",
		result);
	p2p->cfg->send_action_done(p2p->cfg->cb_ctx);
	if (result == P2P_SEND_ACTION_FAILED) {
		p2p_go_neg_failed(p2p, p2p->go_neg_peer, -1);
		return;
	}
	if (result == P2P_SEND_ACTION_NO_ACK) {
		/*
		 * It looks like the TX status for GO Negotiation Confirm is
		 * often showing failure even when the peer has actually
		 * received the frame. Since the peer may change channels
		 * immediately after having received the frame, we may not see
		 * an Ack for retries, so just dropping a single frame may
		 * trigger this. To allow the group formation to succeed if the
		 * peer did indeed receive the frame, continue regardless of
		 * the TX status.
		 */
		wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG,
			"P2P: Assume GO Negotiation Confirm TX was actually "
			"received by the peer even though Ack was not "
			"reported");
	}

	dev = p2p->go_neg_peer;
	if (dev == NULL)
		return;

	p2p_go_complete(p2p, dev);
}


void p2p_send_action_cb(struct p2p_data *p2p, unsigned int freq, const u8 *dst,
			const u8 *src, const u8 *bssid,
			enum p2p_send_action_result result)
{
	enum p2p_pending_action_state state;
	int success;

	wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG,
		"P2P: Action frame TX callback (state=%d freq=%u dst=" MACSTR
		" src=" MACSTR " bssid=" MACSTR " result=%d",
		p2p->pending_action_state, freq, MAC2STR(dst), MAC2STR(src),
		MAC2STR(bssid), result);
	success = result == P2P_SEND_ACTION_SUCCESS;
	state = p2p->pending_action_state;
	p2p->pending_action_state = P2P_NO_PENDING_ACTION;
	switch (state) {
	case P2P_NO_PENDING_ACTION:
		break;
	case P2P_PENDING_GO_NEG_REQUEST:
		p2p_go_neg_req_cb(p2p, success);
		break;
	case P2P_PENDING_GO_NEG_RESPONSE:
		p2p_go_neg_resp_cb(p2p, success);
		break;
	case P2P_PENDING_GO_NEG_RESPONSE_FAILURE:
		p2p_go_neg_resp_failure_cb(p2p, success);
		break;
	case P2P_PENDING_GO_NEG_CONFIRM:
		p2p_go_neg_conf_cb(p2p, result);
		break;
	case P2P_PENDING_SD:
		p2p_sd_cb(p2p, success);
		break;
	case P2P_PENDING_PD:
		p2p_prov_disc_cb(p2p, success);
		break;
	case P2P_PENDING_INVITATION_REQUEST:
		p2p_invitation_req_cb(p2p, success);
		break;
	case P2P_PENDING_INVITATION_RESPONSE:
		p2p_invitation_resp_cb(p2p, success);
		break;
	case P2P_PENDING_DEV_DISC_REQUEST:
		p2p_dev_disc_req_cb(p2p, success);
		break;
	case P2P_PENDING_DEV_DISC_RESPONSE:
		p2p_dev_disc_resp_cb(p2p, success);
		break;
	case P2P_PENDING_GO_DISC_REQ:
		p2p_go_disc_req_cb(p2p, success);
		break;
	}
}


void p2p_listen_cb(struct p2p_data *p2p, unsigned int freq,
		   unsigned int duration)
{
	if (freq == p2p->pending_client_disc_freq) {
		wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG,
			"P2P: Client discoverability remain-awake completed");
		p2p->pending_client_disc_freq = 0;
		return;
	}

	if (freq != p2p->pending_listen_freq) {
		wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG,
			"P2P: Unexpected listen callback for freq=%u "
			"duration=%u (pending_listen_freq=%u)",
			freq, duration, p2p->pending_listen_freq);
		return;
	}

	wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG,
		"P2P: Starting Listen timeout(%u,%u) on freq=%u based on "
		"callback",
		p2p->pending_listen_sec, p2p->pending_listen_usec,
		p2p->pending_listen_freq);
	p2p->in_listen = 1;
	p2p->drv_in_listen = freq;
	if (p2p->pending_listen_sec || p2p->pending_listen_usec) {
		/*
		 * Add 20 msec extra wait to avoid race condition with driver
		 * remain-on-channel end event, i.e., give driver more time to
		 * complete the operation before our timeout expires.
		 */
		p2p_set_timeout(p2p, p2p->pending_listen_sec,
				p2p->pending_listen_usec + 20000);
	}

	p2p->pending_listen_freq = 0;
}


int p2p_listen_end(struct p2p_data *p2p, unsigned int freq)
{
	wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG, "P2P: Driver ended Listen "
		"state (freq=%u)", freq);
	p2p->drv_in_listen = 0;
	if (p2p->in_listen)
		return 0; /* Internal timeout will trigger the next step */

	if (p2p->state == P2P_CONNECT_LISTEN && p2p->go_neg_peer) {
		if (p2p->go_neg_peer->connect_reqs >= 120) {
			wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG,
				"P2P: Timeout on sending GO Negotiation "
				"Request without getting response");
			p2p_go_neg_failed(p2p, p2p->go_neg_peer, -1);
			return 0;
		}

		p2p_set_state(p2p, P2P_CONNECT);
		p2p_connect_send(p2p, p2p->go_neg_peer);
		return 1;
	} else if (p2p->state == P2P_SEARCH) {
		if (p2p->p2p_scan_running) {
			 /*
			  * Search is already in progress. This can happen if
			  * an Action frame RX is reported immediately after
			  * the end of a remain-on-channel operation and the
			  * response frame to that is sent using an offchannel
			  * operation while in p2p_find. Avoid an attempt to
			  * restart a scan here.
			  */
			wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG, "P2P: p2p_scan "
				"already in progress - do not try to start a "
				"new one");
			return 1;
		}
		if (p2p->pending_listen_freq) {
			/*
			 * Better wait a bit if the driver is unable to start
			 * offchannel operation for some reason. p2p_search()
			 * will be started from internal timeout.
			 */
			wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG, "P2P: Listen "
				"operation did not seem to start - delay "
				"search phase to avoid busy loop");
			p2p_set_timeout(p2p, 0, 100000);
			return 1;
		}
		if (p2p->search_delay) {
			wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG, "P2P: Delay "
				"search operation by %u ms",
				p2p->search_delay);
			p2p_set_timeout(p2p, p2p->search_delay / 1000,
					(p2p->search_delay % 1000) * 1000);
			return 1;
		}
		p2p_search(p2p);
		return 1;
	}

	return 0;
}


static void p2p_timeout_connect(struct p2p_data *p2p)
{
	p2p->cfg->send_action_done(p2p->cfg->cb_ctx);
	if (p2p->go_neg_peer &&
	    (p2p->go_neg_peer->flags & P2P_DEV_WAIT_GO_NEG_CONFIRM)) {
		wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG, "P2P: Wait for GO "
			"Negotiation Confirm timed out - assume GO "
			"Negotiation failed");
		p2p_go_neg_failed(p2p, p2p->go_neg_peer, -1);
		return;
	}
	p2p_set_state(p2p, P2P_CONNECT_LISTEN);
	p2p_listen_in_find(p2p);
}


static void p2p_timeout_connect_listen(struct p2p_data *p2p)
{
	if (p2p->go_neg_peer) {
		if (p2p->drv_in_listen) {
			wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG, "P2P: Driver is "
				"still in Listen state; wait for it to "
				"complete");
			return;
		}

		if (p2p->go_neg_peer->connect_reqs >= 120) {
			wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG,
				"P2P: Timeout on sending GO Negotiation "
				"Request without getting response");
			p2p_go_neg_failed(p2p, p2p->go_neg_peer, -1);
			return;
		}

		p2p_set_state(p2p, P2P_CONNECT);
		p2p_connect_send(p2p, p2p->go_neg_peer);
	} else
		p2p_set_state(p2p, P2P_IDLE);
}


static void p2p_timeout_wait_peer_connect(struct p2p_data *p2p)
{
	/*
	 * TODO: could remain constantly in Listen state for some time if there
	 * are no other concurrent uses for the radio. For now, go to listen
	 * state once per second to give other uses a chance to use the radio.
	 */
	p2p_set_state(p2p, P2P_WAIT_PEER_IDLE);
	p2p_set_timeout(p2p, 0, 500000);
}


static void p2p_timeout_wait_peer_idle(struct p2p_data *p2p)
{
	struct p2p_device *dev = p2p->go_neg_peer;

	if (dev == NULL) {
		wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG,
			"P2P: Unknown GO Neg peer - stop GO Neg wait");
		return;
	}

	dev->wait_count++;
	if (dev->wait_count >= 120) {
		wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG,
			"P2P: Timeout on waiting peer to become ready for GO "
			"Negotiation");
		p2p_go_neg_failed(p2p, dev, -1);
		return;
	}

	wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG,
		"P2P: Go to Listen state while waiting for the peer to become "
		"ready for GO Negotiation");
	p2p_set_state(p2p, P2P_WAIT_PEER_CONNECT);
	p2p_listen_in_find(p2p);
}


static void p2p_timeout_sd_during_find(struct p2p_data *p2p)
{
	wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG,
		"P2P: Service Discovery Query timeout");
	if (p2p->sd_peer) {
		p2p->cfg->send_action_done(p2p->cfg->cb_ctx);
		p2p->sd_peer->flags &= ~P2P_DEV_SD_SCHEDULE;
		p2p->sd_peer = NULL;
	}
	p2p_continue_find(p2p);
}


static void p2p_timeout_prov_disc_during_find(struct p2p_data *p2p)
{
	wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG,
		"P2P: Provision Discovery Request timeout");
	p2p->cfg->send_action_done(p2p->cfg->cb_ctx);
	p2p_continue_find(p2p);
}


static void p2p_timeout_prov_disc_req(struct p2p_data *p2p)
{
	p2p->pending_action_state = P2P_NO_PENDING_ACTION;

	/*
	 * For user initiated PD requests that we have not gotten any responses
	 * for while in IDLE state, we retry them a couple of times before
	 * giving up.
	 */
	if (!p2p->user_initiated_pd)
		return;

	wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG,
		"P2P: User initiated Provision Discovery Request timeout");

	if (p2p->pd_retries) {
		p2p->pd_retries--;
		p2p_retry_pd(p2p);
	} else {
		if (p2p->cfg->prov_disc_fail)
			p2p->cfg->prov_disc_fail(p2p->cfg->cb_ctx,
						 p2p->pending_pd_devaddr,
						 P2P_PROV_DISC_TIMEOUT);
		p2p_reset_pending_pd(p2p);
	}
}


static void p2p_timeout_invite(struct p2p_data *p2p)
{
	p2p->cfg->send_action_done(p2p->cfg->cb_ctx);
	p2p_set_state(p2p, P2P_INVITE_LISTEN);
	if (p2p->inv_role == P2P_INVITE_ROLE_ACTIVE_GO) {
		/*
		 * Better remain on operating channel instead of listen channel
		 * when running a group.
		 */
		wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG, "P2P: Inviting in "
			"active GO role - wait on operating channel");
		p2p_set_timeout(p2p, 0, 100000);
		return;
	}
	p2p_listen_in_find(p2p);
}


static void p2p_timeout_invite_listen(struct p2p_data *p2p)
{
	if (p2p->invite_peer && p2p->invite_peer->invitation_reqs < 100) {
		p2p_set_state(p2p, P2P_INVITE);
		p2p_invite_send(p2p, p2p->invite_peer,
				p2p->invite_go_dev_addr);
	} else {
		if (p2p->invite_peer) {
			wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG,
				"P2P: Invitation Request retry limit reached");
			if (p2p->cfg->invitation_result)
				p2p->cfg->invitation_result(
					p2p->cfg->cb_ctx, -1, NULL);
		}
		p2p_set_state(p2p, P2P_IDLE);
	}
}


static void p2p_state_timeout(void *eloop_ctx, void *timeout_ctx)
{
	struct p2p_data *p2p = eloop_ctx;

	wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG, "P2P: Timeout (state=%s)",
		p2p_state_txt(p2p->state));

	p2p->in_listen = 0;

	switch (p2p->state) {
	case P2P_IDLE:
		/* Check if we timed out waiting for PD req */
		if (p2p->pending_action_state == P2P_PENDING_PD)
			p2p_timeout_prov_disc_req(p2p);
		break;
	case P2P_SEARCH:
		/* Check if we timed out waiting for PD req */
		if (p2p->pending_action_state == P2P_PENDING_PD)
			p2p_timeout_prov_disc_req(p2p);
		if (p2p->search_delay && !p2p->in_search_delay) {
			wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG, "P2P: Delay "
				"search operation by %u ms",
				p2p->search_delay);
			p2p->in_search_delay = 1;
			p2p_set_timeout(p2p, p2p->search_delay / 1000,
					(p2p->search_delay % 1000) * 1000);
			break;
		}
		p2p->in_search_delay = 0;
		p2p_search(p2p);
		break;
	case P2P_CONNECT:
		p2p_timeout_connect(p2p);
		break;
	case P2P_CONNECT_LISTEN:
		p2p_timeout_connect_listen(p2p);
		break;
	case P2P_GO_NEG:
		break;
	case P2P_LISTEN_ONLY:
		/* Check if we timed out waiting for PD req */
		if (p2p->pending_action_state == P2P_PENDING_PD)
			p2p_timeout_prov_disc_req(p2p);

		if (p2p->ext_listen_only) {
			wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG,
				"P2P: Extended Listen Timing - Listen State "
				"completed");
			p2p->ext_listen_only = 0;
			p2p_set_state(p2p, P2P_IDLE);
		}
		break;
	case P2P_WAIT_PEER_CONNECT:
		p2p_timeout_wait_peer_connect(p2p);
		break;
	case P2P_WAIT_PEER_IDLE:
		p2p_timeout_wait_peer_idle(p2p);
		break;
	case P2P_SD_DURING_FIND:
		p2p_timeout_sd_during_find(p2p);
		break;
	case P2P_PROVISIONING:
		break;
	case P2P_PD_DURING_FIND:
		p2p_timeout_prov_disc_during_find(p2p);
		break;
	case P2P_INVITE:
		p2p_timeout_invite(p2p);
		break;
	case P2P_INVITE_LISTEN:
		p2p_timeout_invite_listen(p2p);
		break;
	case P2P_SEARCH_WHEN_READY:
		break;
	case P2P_CONTINUE_SEARCH_WHEN_READY:
		break;
	}
}


int p2p_reject(struct p2p_data *p2p, const u8 *peer_addr)
{
	struct p2p_device *dev;

	dev = p2p_get_device(p2p, peer_addr);
	wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG, "P2P: Local request to reject "
		"connection attempts by peer " MACSTR, MAC2STR(peer_addr));
	if (dev == NULL) {
		wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG, "P2P: Peer " MACSTR
			" unknown", MAC2STR(peer_addr));
		return -1;
	}
	dev->status = P2P_SC_FAIL_REJECTED_BY_USER;
	dev->flags |= P2P_DEV_USER_REJECTED;
	return 0;
}


const char * p2p_wps_method_text(enum p2p_wps_method method)
{
	switch (method) {
	case WPS_NOT_READY:
		return "not-ready";
	case WPS_PIN_DISPLAY:
		return "Display";
	case WPS_PIN_KEYPAD:
		return "Keypad";
	case WPS_PBC:
		return "PBC";
	}

	return "??";
}


static const char * p2p_go_state_text(enum p2p_go_state go_state)
{
	switch (go_state) {
	case UNKNOWN_GO:
		return "unknown";
	case LOCAL_GO:
		return "local";
	case  REMOTE_GO:
		return "remote";
	}

	return "??";
}


const struct p2p_peer_info * p2p_get_peer_info(struct p2p_data *p2p,
					       const u8 *addr, int next)
{
	struct p2p_device *dev;

	if (addr)
		dev = p2p_get_device(p2p, addr);
	else
		dev = dl_list_first(&p2p->devices, struct p2p_device, list);

	if (dev && next) {
		dev = dl_list_first(&dev->list, struct p2p_device, list);
		if (&dev->list == &p2p->devices)
			dev = NULL;
	}

	if (dev == NULL)
		return NULL;

	return &dev->info;
}


int p2p_get_peer_info_txt(const struct p2p_peer_info *info,
			  char *buf, size_t buflen)
{
	struct p2p_device *dev;
	int res;
	char *pos, *end;
	struct os_time now;

	if (info == NULL)
		return -1;

	dev = (struct p2p_device *) (((u8 *) info) -
				     offsetof(struct p2p_device, info));

	pos = buf;
	end = buf + buflen;

	os_get_time(&now);
	res = os_snprintf(pos, end - pos,
			  "age=%d\n"
			  "listen_freq=%d\n"
			  "wps_method=%s\n"
			  "interface_addr=" MACSTR "\n"
			  "member_in_go_dev=" MACSTR "\n"
			  "member_in_go_iface=" MACSTR "\n"
			  "go_neg_req_sent=%d\n"
			  "go_state=%s\n"
			  "dialog_token=%u\n"
			  "intended_addr=" MACSTR "\n"
			  "country=%c%c\n"
			  "oper_freq=%d\n"
			  "req_config_methods=0x%x\n"
			  "flags=%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s\n"
			  "status=%d\n"
			  "wait_count=%u\n"
			  "invitation_reqs=%u\n",
			  (int) (now.sec - dev->last_seen.sec),
			  dev->listen_freq,
			  p2p_wps_method_text(dev->wps_method),
			  MAC2STR(dev->interface_addr),
			  MAC2STR(dev->member_in_go_dev),
			  MAC2STR(dev->member_in_go_iface),
			  dev->go_neg_req_sent,
			  p2p_go_state_text(dev->go_state),
			  dev->dialog_token,
			  MAC2STR(dev->intended_addr),
			  dev->country[0] ? dev->country[0] : '_',
			  dev->country[1] ? dev->country[1] : '_',
			  dev->oper_freq,
			  dev->req_config_methods,
			  dev->flags & P2P_DEV_PROBE_REQ_ONLY ?
			  "[PROBE_REQ_ONLY]" : "",
			  dev->flags & P2P_DEV_REPORTED ? "[REPORTED]" : "",
			  dev->flags & P2P_DEV_NOT_YET_READY ?
			  "[NOT_YET_READY]" : "",
			  dev->flags & P2P_DEV_SD_INFO ? "[SD_INFO]" : "",
			  dev->flags & P2P_DEV_SD_SCHEDULE ? "[SD_SCHEDULE]" :
			  "",
			  dev->flags & P2P_DEV_PD_PEER_DISPLAY ?
			  "[PD_PEER_DISPLAY]" : "",
			  dev->flags & P2P_DEV_PD_PEER_KEYPAD ?
			  "[PD_PEER_KEYPAD]" : "",
			  dev->flags & P2P_DEV_USER_REJECTED ?
			  "[USER_REJECTED]" : "",
			  dev->flags & P2P_DEV_PEER_WAITING_RESPONSE ?
			  "[PEER_WAITING_RESPONSE]" : "",
			  dev->flags & P2P_DEV_PREFER_PERSISTENT_GROUP ?
			  "[PREFER_PERSISTENT_GROUP]" : "",
			  dev->flags & P2P_DEV_WAIT_GO_NEG_RESPONSE ?
			  "[WAIT_GO_NEG_RESPONSE]" : "",
			  dev->flags & P2P_DEV_WAIT_GO_NEG_CONFIRM ?
			  "[WAIT_GO_NEG_CONFIRM]" : "",
			  dev->flags & P2P_DEV_GROUP_CLIENT_ONLY ?
			  "[GROUP_CLIENT_ONLY]" : "",
			  dev->flags & P2P_DEV_FORCE_FREQ ?
			  "[FORCE_FREQ]" : "",
			  dev->flags & P2P_DEV_PD_FOR_JOIN ?
			  "[PD_FOR_JOIN]" : "",
			  dev->status,
			  dev->wait_count,
			  dev->invitation_reqs);
	if (res < 0 || res >= end - pos)
		return pos - buf;
	pos += res;

	if (dev->ext_listen_period) {
		res = os_snprintf(pos, end - pos,
				  "ext_listen_period=%u\n"
				  "ext_listen_interval=%u\n",
				  dev->ext_listen_period,
				  dev->ext_listen_interval);
		if (res < 0 || res >= end - pos)
			return pos - buf;
		pos += res;
	}

	if (dev->oper_ssid_len) {
		res = os_snprintf(pos, end - pos,
				  "oper_ssid=%s\n",
				  wpa_ssid_txt(dev->oper_ssid,
					       dev->oper_ssid_len));
		if (res < 0 || res >= end - pos)
			return pos - buf;
		pos += res;
	}

#ifdef CONFIG_WIFI_DISPLAY
	if (dev->info.wfd_subelems) {
		res = os_snprintf(pos, end - pos, "wfd_subelems=");
		if (res < 0 || res >= end - pos)
			return pos - buf;
		pos += res;

		pos += wpa_snprintf_hex(pos, end - pos,
					wpabuf_head(dev->info.wfd_subelems),
					wpabuf_len(dev->info.wfd_subelems));

		res = os_snprintf(pos, end - pos, "\n");
		if (res < 0 || res >= end - pos)
			return pos - buf;
		pos += res;
	}
#endif /* CONFIG_WIFI_DISPLAY */

	return pos - buf;
}


int p2p_peer_known(struct p2p_data *p2p, const u8 *addr)
{
	return p2p_get_device(p2p, addr) != NULL;
}


void p2p_set_client_discoverability(struct p2p_data *p2p, int enabled)
{
	if (enabled) {
		wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG, "P2P: Client "
			"discoverability enabled");
		p2p->dev_capab |= P2P_DEV_CAPAB_CLIENT_DISCOVERABILITY;
	} else {
		wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG, "P2P: Client "
			"discoverability disabled");
		p2p->dev_capab &= ~P2P_DEV_CAPAB_CLIENT_DISCOVERABILITY;
	}
}


static struct wpabuf * p2p_build_presence_req(u32 duration1, u32 interval1,
					      u32 duration2, u32 interval2)
{
	struct wpabuf *req;
	struct p2p_noa_desc desc1, desc2, *ptr1 = NULL, *ptr2 = NULL;
	u8 *len;

	req = wpabuf_alloc(100);
	if (req == NULL)
		return NULL;

	if (duration1 || interval1) {
		os_memset(&desc1, 0, sizeof(desc1));
		desc1.count_type = 1;
		desc1.duration = duration1;
		desc1.interval = interval1;
		ptr1 = &desc1;

		if (duration2 || interval2) {
			os_memset(&desc2, 0, sizeof(desc2));
			desc2.count_type = 2;
			desc2.duration = duration2;
			desc2.interval = interval2;
			ptr2 = &desc2;
		}
	}

	p2p_buf_add_action_hdr(req, P2P_PRESENCE_REQ, 1);
	len = p2p_buf_add_ie_hdr(req);
	p2p_buf_add_noa(req, 0, 0, 0, ptr1, ptr2);
	p2p_buf_update_ie_hdr(req, len);

	return req;
}


int p2p_presence_req(struct p2p_data *p2p, const u8 *go_interface_addr,
		     const u8 *own_interface_addr, unsigned int freq,
		     u32 duration1, u32 interval1, u32 duration2,
		     u32 interval2)
{
	struct wpabuf *req;

	wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG, "P2P: Send Presence Request to "
		"GO " MACSTR " (own interface " MACSTR ") freq=%u dur1=%u "
		"int1=%u dur2=%u int2=%u",
		MAC2STR(go_interface_addr), MAC2STR(own_interface_addr),
		freq, duration1, interval1, duration2, interval2);

	req = p2p_build_presence_req(duration1, interval1, duration2,
				     interval2);
	if (req == NULL)
		return -1;

	p2p->pending_action_state = P2P_NO_PENDING_ACTION;
	if (p2p_send_action(p2p, freq, go_interface_addr, own_interface_addr,
			    go_interface_addr,
			    wpabuf_head(req), wpabuf_len(req), 200) < 0) {
		wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG,
			"P2P: Failed to send Action frame");
	}
	wpabuf_free(req);

	return 0;
}


static struct wpabuf * p2p_build_presence_resp(u8 status, const u8 *noa,
					       size_t noa_len, u8 dialog_token)
{
	struct wpabuf *resp;
	u8 *len;

	resp = wpabuf_alloc(100 + noa_len);
	if (resp == NULL)
		return NULL;

	p2p_buf_add_action_hdr(resp, P2P_PRESENCE_RESP, dialog_token);
	len = p2p_buf_add_ie_hdr(resp);
	p2p_buf_add_status(resp, status);
	if (noa) {
		wpabuf_put_u8(resp, P2P_ATTR_NOTICE_OF_ABSENCE);
		wpabuf_put_le16(resp, noa_len);
		wpabuf_put_data(resp, noa, noa_len);
	} else
		p2p_buf_add_noa(resp, 0, 0, 0, NULL, NULL);
	p2p_buf_update_ie_hdr(resp, len);

	return resp;
}


static void p2p_process_presence_req(struct p2p_data *p2p, const u8 *da,
				     const u8 *sa, const u8 *data, size_t len,
				     int rx_freq)
{
	struct p2p_message msg;
	u8 status;
	struct wpabuf *resp;
	size_t g;
	struct p2p_group *group = NULL;
	int parsed = 0;
	u8 noa[50];
	int noa_len;

	wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG,
		"P2P: Received P2P Action - P2P Presence Request");

	for (g = 0; g < p2p->num_groups; g++) {
		if (os_memcmp(da, p2p_group_get_interface_addr(p2p->groups[g]),
			      ETH_ALEN) == 0) {
			group = p2p->groups[g];
			break;
		}
	}
	if (group == NULL) {
		wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG,
			"P2P: Ignore P2P Presence Request for unknown group "
			MACSTR, MAC2STR(da));
		return;
	}

	if (p2p_parse(data, len, &msg) < 0) {
		wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG,
			"P2P: Failed to parse P2P Presence Request");
		status = P2P_SC_FAIL_INVALID_PARAMS;
		goto fail;
	}
	parsed = 1;

	if (msg.noa == NULL) {
		wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG,
			"P2P: No NoA attribute in P2P Presence Request");
		status = P2P_SC_FAIL_INVALID_PARAMS;
		goto fail;
	}

	status = p2p_group_presence_req(group, sa, msg.noa, msg.noa_len);

fail:
	if (p2p->cfg->get_noa)
		noa_len = p2p->cfg->get_noa(p2p->cfg->cb_ctx, da, noa,
					    sizeof(noa));
	else
		noa_len = -1;
	resp = p2p_build_presence_resp(status, noa_len > 0 ? noa : NULL,
				       noa_len > 0 ? noa_len : 0,
				       msg.dialog_token);
	if (parsed)
		p2p_parse_free(&msg);
	if (resp == NULL)
		return;

	p2p->pending_action_state = P2P_NO_PENDING_ACTION;
	if (p2p_send_action(p2p, rx_freq, sa, da, da,
			    wpabuf_head(resp), wpabuf_len(resp), 200) < 0) {
		wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG,
			"P2P: Failed to send Action frame");
	}
	wpabuf_free(resp);
}


static void p2p_process_presence_resp(struct p2p_data *p2p, const u8 *da,
				      const u8 *sa, const u8 *data, size_t len)
{
	struct p2p_message msg;

	wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG,
		"P2P: Received P2P Action - P2P Presence Response");

	if (p2p_parse(data, len, &msg) < 0) {
		wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG,
			"P2P: Failed to parse P2P Presence Response");
		return;
	}

	if (msg.status == NULL || msg.noa == NULL) {
		wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG,
			"P2P: No Status or NoA attribute in P2P Presence "
			"Response");
		p2p_parse_free(&msg);
		return;
	}

	if (*msg.status) {
		wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG,
			"P2P: P2P Presence Request was rejected: status %u",
			*msg.status);
		p2p_parse_free(&msg);
		return;
	}

	wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG,
		"P2P: P2P Presence Request was accepted");
	wpa_hexdump(MSG_DEBUG, "P2P: P2P Presence Response - NoA",
		    msg.noa, msg.noa_len);
	/* TODO: process NoA */
	p2p_parse_free(&msg);
}


static void p2p_ext_listen_timeout(void *eloop_ctx, void *timeout_ctx)
{
	struct p2p_data *p2p = eloop_ctx;

	if (p2p->ext_listen_interval) {
		/* Schedule next extended listen timeout */
		eloop_register_timeout(p2p->ext_listen_interval_sec,
				       p2p->ext_listen_interval_usec,
				       p2p_ext_listen_timeout, p2p, NULL);
	}

	if (p2p->state == P2P_LISTEN_ONLY && p2p->ext_listen_only) {
		/*
		 * This should not really happen, but it looks like the Listen
		 * command may fail is something else (e.g., a scan) was
		 * running at an inconvenient time. As a workaround, allow new
		 * Extended Listen operation to be started.
		 */
		wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG, "P2P: Previous "
			"Extended Listen operation had not been completed - "
			"try again");
		p2p->ext_listen_only = 0;
		p2p_set_state(p2p, P2P_IDLE);
	}

	if (p2p->state != P2P_IDLE) {
		wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG, "P2P: Skip Extended "
			"Listen timeout in active state (%s)",
			p2p_state_txt(p2p->state));
		return;
	}

	wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG, "P2P: Extended Listen timeout");
	p2p->ext_listen_only = 1;
	if (p2p_listen(p2p, p2p->ext_listen_period) < 0) {
		wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG, "P2P: Failed to start "
			"Listen state for Extended Listen Timing");
		p2p->ext_listen_only = 0;
	}
}


int p2p_ext_listen(struct p2p_data *p2p, unsigned int period,
		   unsigned int interval)
{
	if (period > 65535 || interval > 65535 || period > interval ||
	    (period == 0 && interval > 0) || (period > 0 && interval == 0)) {
		wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG,
			"P2P: Invalid Extended Listen Timing request: "
			"period=%u interval=%u", period, interval);
		return -1;
	}

	eloop_cancel_timeout(p2p_ext_listen_timeout, p2p, NULL);

	if (interval == 0) {
		wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG,
			"P2P: Disabling Extended Listen Timing");
		p2p->ext_listen_period = 0;
		p2p->ext_listen_interval = 0;
		return 0;
	}

	wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG,
		"P2P: Enabling Extended Listen Timing: period %u msec, "
		"interval %u msec", period, interval);
	p2p->ext_listen_period = period;
	p2p->ext_listen_interval = interval;
	p2p->ext_listen_interval_sec = interval / 1000;
	p2p->ext_listen_interval_usec = (interval % 1000) * 1000;

	eloop_register_timeout(p2p->ext_listen_interval_sec,
			       p2p->ext_listen_interval_usec,
			       p2p_ext_listen_timeout, p2p, NULL);

	return 0;
}


void p2p_deauth_notif(struct p2p_data *p2p, const u8 *bssid, u16 reason_code,
		      const u8 *ie, size_t ie_len)
{
	struct p2p_message msg;

	if (bssid == NULL || ie == NULL)
		return;

	os_memset(&msg, 0, sizeof(msg));
	if (p2p_parse_ies(ie, ie_len, &msg))
		return;
	if (msg.minor_reason_code == NULL)
		return;

	wpa_msg(p2p->cfg->msg_ctx, MSG_INFO,
		"P2P: Deauthentication notification BSSID " MACSTR
		" reason_code=%u minor_reason_code=%u",
		MAC2STR(bssid), reason_code, *msg.minor_reason_code);

	p2p_parse_free(&msg);
}


void p2p_disassoc_notif(struct p2p_data *p2p, const u8 *bssid, u16 reason_code,
			const u8 *ie, size_t ie_len)
{
	struct p2p_message msg;

	if (bssid == NULL || ie == NULL)
		return;

	os_memset(&msg, 0, sizeof(msg));
	if (p2p_parse_ies(ie, ie_len, &msg))
		return;
	if (msg.minor_reason_code == NULL)
		return;

	wpa_msg(p2p->cfg->msg_ctx, MSG_INFO,
		"P2P: Disassociation notification BSSID " MACSTR
		" reason_code=%u minor_reason_code=%u",
		MAC2STR(bssid), reason_code, *msg.minor_reason_code);

	p2p_parse_free(&msg);
}


void p2p_set_managed_oper(struct p2p_data *p2p, int enabled)
{
	if (enabled) {
		wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG, "P2P: Managed P2P "
			"Device operations enabled");
		p2p->dev_capab |= P2P_DEV_CAPAB_INFRA_MANAGED;
	} else {
		wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG, "P2P: Managed P2P "
			"Device operations disabled");
		p2p->dev_capab &= ~P2P_DEV_CAPAB_INFRA_MANAGED;
	}
}


int p2p_set_listen_channel(struct p2p_data *p2p, u8 reg_class, u8 channel)
{
	if (p2p_channel_to_freq(p2p->cfg->country, reg_class, channel) < 0)
		return -1;

	wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG, "P2P: Set Listen channel: "
		"reg_class %u channel %u", reg_class, channel);
	p2p->cfg->reg_class = reg_class;
	p2p->cfg->channel = channel;

	return 0;
}


int p2p_set_ssid_postfix(struct p2p_data *p2p, const u8 *postfix, size_t len)
{
	wpa_hexdump_ascii(MSG_DEBUG, "P2P: New SSID postfix", postfix, len);
	if (postfix == NULL) {
		p2p->cfg->ssid_postfix_len = 0;
		return 0;
	}
	if (len > sizeof(p2p->cfg->ssid_postfix))
		return -1;
	os_memcpy(p2p->cfg->ssid_postfix, postfix, len);
	p2p->cfg->ssid_postfix_len = len;
	return 0;
}


int p2p_set_oper_channel(struct p2p_data *p2p, u8 op_reg_class, u8 op_channel,
			 int cfg_op_channel)
{
	if (p2p_channel_to_freq(p2p->cfg->country, op_reg_class, op_channel)
	    < 0)
		return -1;

	wpa_msg(p2p->cfg->msg_ctx, MSG_INFO, "P2P: Set Operating channel: "
		"reg_class %u channel %u", op_reg_class, op_channel);
	p2p->cfg->op_reg_class = op_reg_class;
	p2p->cfg->op_channel = op_channel;
	p2p->cfg->cfg_op_channel = cfg_op_channel;
	return 0;
}


int p2p_set_pref_chan(struct p2p_data *p2p, unsigned int num_pref_chan,
		      const struct p2p_channel *pref_chan)
{
	struct p2p_channel *n;

	if (pref_chan) {
		n = os_malloc(num_pref_chan * sizeof(struct p2p_channel));
		if (n == NULL)
			return -1;
		os_memcpy(n, pref_chan,
			  num_pref_chan * sizeof(struct p2p_channel));
	} else
		n = NULL;

	os_free(p2p->cfg->pref_chan);
	p2p->cfg->pref_chan = n;
	p2p->cfg->num_pref_chan = num_pref_chan;

	return 0;
}


int p2p_get_interface_addr(struct p2p_data *p2p, const u8 *dev_addr,
			   u8 *iface_addr)
{
	struct p2p_device *dev = p2p_get_device(p2p, dev_addr);
	if (dev == NULL || is_zero_ether_addr(dev->interface_addr))
		return -1;
	os_memcpy(iface_addr, dev->interface_addr, ETH_ALEN);
	return 0;
}


int p2p_get_dev_addr(struct p2p_data *p2p, const u8 *iface_addr,
			   u8 *dev_addr)
{
	struct p2p_device *dev = p2p_get_device_interface(p2p, iface_addr);
	if (dev == NULL)
		return -1;
	os_memcpy(dev_addr, dev->info.p2p_device_addr, ETH_ALEN);
	return 0;
}


void p2p_set_peer_filter(struct p2p_data *p2p, const u8 *addr)
{
	os_memcpy(p2p->peer_filter, addr, ETH_ALEN);
	if (is_zero_ether_addr(p2p->peer_filter))
		wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG, "P2P: Disable peer "
			"filter");
	else
		wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG, "P2P: Enable peer "
			"filter for " MACSTR, MAC2STR(p2p->peer_filter));
}


void p2p_set_cross_connect(struct p2p_data *p2p, int enabled)
{
	wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG, "P2P: Cross connection %s",
		enabled ? "enabled" : "disabled");
	if (p2p->cross_connect == enabled)
		return;
	p2p->cross_connect = enabled;
	/* TODO: may need to tear down any action group where we are GO(?) */
}


int p2p_get_oper_freq(struct p2p_data *p2p, const u8 *iface_addr)
{
	struct p2p_device *dev = p2p_get_device_interface(p2p, iface_addr);
	if (dev == NULL)
		return -1;
	if (dev->oper_freq <= 0)
		return -1;
	return dev->oper_freq;
}


void p2p_set_intra_bss_dist(struct p2p_data *p2p, int enabled)
{
	wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG, "P2P: Intra BSS distribution %s",
		enabled ? "enabled" : "disabled");
	p2p->cfg->p2p_intra_bss = enabled;
}


void p2p_update_channel_list(struct p2p_data *p2p, struct p2p_channels *chan)
{
	wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG, "P2P: Update channel list");
	os_memcpy(&p2p->cfg->channels, chan, sizeof(struct p2p_channels));
}


int p2p_send_action(struct p2p_data *p2p, unsigned int freq, const u8 *dst,
		    const u8 *src, const u8 *bssid, const u8 *buf,
		    size_t len, unsigned int wait_time)
{
	if (p2p->p2p_scan_running) {
		wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG, "P2P: Delay Action "
			"frame TX until p2p_scan completes");
		if (p2p->after_scan_tx) {
			wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG, "P2P: Dropped "
				"previous pending Action frame TX");
			os_free(p2p->after_scan_tx);
		}
		p2p->after_scan_tx = os_malloc(sizeof(*p2p->after_scan_tx) +
					       len);
		if (p2p->after_scan_tx == NULL)
			return -1;
		p2p->after_scan_tx->freq = freq;
		os_memcpy(p2p->after_scan_tx->dst, dst, ETH_ALEN);
		os_memcpy(p2p->after_scan_tx->src, src, ETH_ALEN);
		os_memcpy(p2p->after_scan_tx->bssid, bssid, ETH_ALEN);
		p2p->after_scan_tx->len = len;
		p2p->after_scan_tx->wait_time = wait_time;
		os_memcpy(p2p->after_scan_tx + 1, buf, len);
		return 0;
	}

	return p2p->cfg->send_action(p2p->cfg->cb_ctx, freq, dst, src, bssid,
				     buf, len, wait_time);
}


void p2p_set_best_channels(struct p2p_data *p2p, int freq_24, int freq_5,
			   int freq_overall)
{
	wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG, "P2P: Best channel: 2.4 GHz: %d,"
		"  5 GHz: %d,  overall: %d", freq_24, freq_5, freq_overall);
	p2p->best_freq_24 = freq_24;
	p2p->best_freq_5 = freq_5;
	p2p->best_freq_overall = freq_overall;
}


const u8 * p2p_get_go_neg_peer(struct p2p_data *p2p)
{
	if (p2p == NULL || p2p->go_neg_peer == NULL)
		return NULL;
	return p2p->go_neg_peer->info.p2p_device_addr;
}


const struct p2p_peer_info *
p2p_get_peer_found(struct p2p_data *p2p, const u8 *addr, int next)
{
	struct p2p_device *dev;

	if (addr) {
		dev = p2p_get_device(p2p, addr);
		if (!dev)
			return NULL;

		if (!next) {
			if (dev->flags & P2P_DEV_PROBE_REQ_ONLY)
				return NULL;

			return &dev->info;
		} else {
			do {
				dev = dl_list_first(&dev->list,
						    struct p2p_device,
						    list);
				if (&dev->list == &p2p->devices)
					return NULL;
			} while (dev->flags & P2P_DEV_PROBE_REQ_ONLY);
		}
	} else {
		dev = dl_list_first(&p2p->devices, struct p2p_device, list);
		if (!dev)
			return NULL;
		while (dev->flags & P2P_DEV_PROBE_REQ_ONLY) {
			dev = dl_list_first(&dev->list,
					    struct p2p_device,
					    list);
			if (&dev->list == &p2p->devices)
				return NULL;
		}
	}

	return &dev->info;
}

#ifdef ANDROID_P2P
int p2p_search_in_progress(struct p2p_data *p2p)
{
	if (p2p == NULL)
		return 0;

	return p2p->state == P2P_SEARCH;
}
#endif

int p2p_in_progress(struct p2p_data *p2p)
{
	if (p2p == NULL)
		return 0;
	if (p2p->state == P2P_SEARCH || p2p->state == P2P_SEARCH_WHEN_READY ||
	    p2p->state == P2P_CONTINUE_SEARCH_WHEN_READY)
		return 2;
	return p2p->state != P2P_IDLE && p2p->state != P2P_PROVISIONING;
}


void p2p_set_config_timeout(struct p2p_data *p2p, u8 go_timeout,
			    u8 client_timeout)
{
	if (p2p) {
		p2p->go_timeout = go_timeout;
		p2p->client_timeout = client_timeout;
	}
}


void p2p_increase_search_delay(struct p2p_data *p2p, unsigned int delay)
{
	if (p2p && p2p->search_delay < delay)
		p2p->search_delay = delay;
}


#ifdef CONFIG_WIFI_DISPLAY

static void p2p_update_wfd_ie_groups(struct p2p_data *p2p)
{
	size_t g;
	struct p2p_group *group;

	for (g = 0; g < p2p->num_groups; g++) {
		group = p2p->groups[g];
		p2p_group_update_ies(group);
	}
}


int p2p_set_wfd_ie_beacon(struct p2p_data *p2p, struct wpabuf *ie)
{
	wpabuf_free(p2p->wfd_ie_beacon);
	p2p->wfd_ie_beacon = ie;
	p2p_update_wfd_ie_groups(p2p);
	return 0;
}


int p2p_set_wfd_ie_probe_req(struct p2p_data *p2p, struct wpabuf *ie)
{
	wpabuf_free(p2p->wfd_ie_probe_req);
	p2p->wfd_ie_probe_req = ie;
	return 0;
}


int p2p_set_wfd_ie_probe_resp(struct p2p_data *p2p, struct wpabuf *ie)
{
	wpabuf_free(p2p->wfd_ie_probe_resp);
	p2p->wfd_ie_probe_resp = ie;
	p2p_update_wfd_ie_groups(p2p);
	return 0;
}


int p2p_set_wfd_ie_assoc_req(struct p2p_data *p2p, struct wpabuf *ie)
{
	wpabuf_free(p2p->wfd_ie_assoc_req);
	p2p->wfd_ie_assoc_req = ie;
	return 0;
}


int p2p_set_wfd_ie_invitation(struct p2p_data *p2p, struct wpabuf *ie)
{
	wpabuf_free(p2p->wfd_ie_invitation);
	p2p->wfd_ie_invitation = ie;
	return 0;
}


int p2p_set_wfd_ie_prov_disc_req(struct p2p_data *p2p, struct wpabuf *ie)
{
	wpabuf_free(p2p->wfd_ie_prov_disc_req);
	p2p->wfd_ie_prov_disc_req = ie;
	return 0;
}


int p2p_set_wfd_ie_prov_disc_resp(struct p2p_data *p2p, struct wpabuf *ie)
{
	wpabuf_free(p2p->wfd_ie_prov_disc_resp);
	p2p->wfd_ie_prov_disc_resp = ie;
	return 0;
}


int p2p_set_wfd_ie_go_neg(struct p2p_data *p2p, struct wpabuf *ie)
{
	wpabuf_free(p2p->wfd_ie_go_neg);
	p2p->wfd_ie_go_neg = ie;
	return 0;
}


int p2p_set_wfd_dev_info(struct p2p_data *p2p, const struct wpabuf *elem)
{
	wpabuf_free(p2p->wfd_dev_info);
	if (elem) {
		p2p->wfd_dev_info = wpabuf_dup(elem);
		if (p2p->wfd_dev_info == NULL)
			return -1;
	} else
		p2p->wfd_dev_info = NULL;

	return 0;
}


int p2p_set_wfd_assoc_bssid(struct p2p_data *p2p, const struct wpabuf *elem)
{
	wpabuf_free(p2p->wfd_assoc_bssid);
	if (elem) {
		p2p->wfd_assoc_bssid = wpabuf_dup(elem);
		if (p2p->wfd_assoc_bssid == NULL)
			return -1;
	} else
		p2p->wfd_assoc_bssid = NULL;

	return 0;
}


int p2p_set_wfd_coupled_sink_info(struct p2p_data *p2p,
				  const struct wpabuf *elem)
{
	wpabuf_free(p2p->wfd_coupled_sink_info);
	if (elem) {
		p2p->wfd_coupled_sink_info = wpabuf_dup(elem);
		if (p2p->wfd_coupled_sink_info == NULL)
			return -1;
	} else
		p2p->wfd_coupled_sink_info = NULL;

	return 0;
}

#endif /* CONFIG_WIFI_DISPLAY */
