/*
 * wpa_supplicant - P2P
 * Copyright (c) 2009-2010, Atheros Communications
 * Copyright (c) 2010-2014, Jouni Malinen <j@w1.fi>
 *
 * 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_common.h"
#include "common/ieee802_11_defs.h"
#include "common/wpa_ctrl.h"
#include "wps/wps_i.h"
#include "p2p/p2p.h"
#include "ap/hostapd.h"
#include "ap/ap_config.h"
#include "ap/sta_info.h"
#include "ap/ap_drv_ops.h"
#include "ap/wps_hostapd.h"
#include "ap/p2p_hostapd.h"
#include "ap/dfs.h"
#include "eapol_supp/eapol_supp_sm.h"
#include "rsn_supp/wpa.h"
#include "wpa_supplicant_i.h"
#include "driver_i.h"
#include "ap.h"
#include "config_ssid.h"
#include "config.h"
#include "notify.h"
#include "scan.h"
#include "bss.h"
#include "offchannel.h"
#include "wps_supplicant.h"
#include "p2p_supplicant.h"
#include "wifi_display.h"


/*
 * How many times to try to scan to find the GO before giving up on join
 * request.
 */
#define P2P_MAX_JOIN_SCAN_ATTEMPTS 10

#define P2P_AUTO_PD_SCAN_ATTEMPTS 5

/**
 * Defines time interval in seconds when a GO needs to evacuate a frequency that
 * it is currently using, but is no longer valid for P2P use cases.
 */
#define P2P_GO_FREQ_CHANGE_TIME 5

/**
 * Defines CSA parameters which are used when GO evacuates the no longer valid
 * channel (and if the driver supports channel switch).
 */
#define P2P_GO_CSA_COUNT 7
#define P2P_GO_CSA_BLOCK_TX 0

#ifndef P2P_MAX_CLIENT_IDLE
/*
 * How many seconds to try to reconnect to the GO when connection in P2P client
 * role has been lost.
 */
#define P2P_MAX_CLIENT_IDLE 10
#endif /* P2P_MAX_CLIENT_IDLE */

#ifndef P2P_MAX_INITIAL_CONN_WAIT
/*
 * How many seconds to wait for initial 4-way handshake to get completed after
 * WPS provisioning step or after the re-invocation of a persistent group on a
 * P2P Client.
 */
#define P2P_MAX_INITIAL_CONN_WAIT 10
#endif /* P2P_MAX_INITIAL_CONN_WAIT */

#ifndef P2P_MAX_INITIAL_CONN_WAIT_GO
/*
 * How many seconds to wait for initial 4-way handshake to get completed after
 * WPS provisioning step on the GO. This controls the extra time the P2P
 * operation is considered to be in progress (e.g., to delay other scans) after
 * WPS provisioning has been completed on the GO during group formation.
 */
#define P2P_MAX_INITIAL_CONN_WAIT_GO 10
#endif /* P2P_MAX_INITIAL_CONN_WAIT_GO */

#ifndef P2P_MAX_INITIAL_CONN_WAIT_GO_REINVOKE
/*
 * How many seconds to wait for initial 4-way handshake to get completed after
 * re-invocation of a persistent group on the GO when the client is expected
 * to connect automatically (no user interaction).
 */
#define P2P_MAX_INITIAL_CONN_WAIT_GO_REINVOKE 15
#endif /* P2P_MAX_INITIAL_CONN_WAIT_GO_REINVOKE */

#define P2P_MGMT_DEVICE_PREFIX		"p2p-dev-"

/*
 * How many seconds to wait to re-attempt to move GOs, in case previous attempt
 * was not possible.
 */
#define P2P_RECONSIDER_GO_MOVE_DELAY 30

/* Check if frequency is 2GHz */
#define	IS_2GHZ(n)	(n >= 2412 && n <= 2484)

enum p2p_group_removal_reason {
	P2P_GROUP_REMOVAL_UNKNOWN,
	P2P_GROUP_REMOVAL_SILENT,
	P2P_GROUP_REMOVAL_FORMATION_FAILED,
	P2P_GROUP_REMOVAL_REQUESTED,
	P2P_GROUP_REMOVAL_IDLE_TIMEOUT,
	P2P_GROUP_REMOVAL_UNAVAILABLE,
	P2P_GROUP_REMOVAL_GO_ENDING_SESSION,
	P2P_GROUP_REMOVAL_PSK_FAILURE,
	P2P_GROUP_REMOVAL_FREQ_CONFLICT,
	P2P_GROUP_REMOVAL_GO_LEAVE_CHANNEL
};


static void wpas_p2p_long_listen_timeout(void *eloop_ctx, void *timeout_ctx);
static struct wpa_supplicant *
wpas_p2p_get_group_iface(struct wpa_supplicant *wpa_s, int addr_allocated,
			 int go);
static int wpas_p2p_join_start(struct wpa_supplicant *wpa_s, int freq,
			       const u8 *ssid, size_t ssid_len);
static int wpas_p2p_setup_freqs(struct wpa_supplicant *wpa_s, int freq,
				int *force_freq, int *pref_freq, int go,
				unsigned int *pref_freq_list,
				unsigned int *num_pref_freq);
static void wpas_p2p_join_scan_req(struct wpa_supplicant *wpa_s, int freq,
				   const u8 *ssid, size_t ssid_len);
static void wpas_p2p_join_scan(void *eloop_ctx, void *timeout_ctx);
static int wpas_p2p_join(struct wpa_supplicant *wpa_s, const u8 *iface_addr,
			 const u8 *dev_addr, enum p2p_wps_method wps_method,
			 int auto_join, int freq,
			 const u8 *ssid, size_t ssid_len);
static int wpas_p2p_create_iface(struct wpa_supplicant *wpa_s);
static void wpas_p2p_cross_connect_setup(struct wpa_supplicant *wpa_s);
static void wpas_p2p_group_idle_timeout(void *eloop_ctx, void *timeout_ctx);
static void wpas_p2p_set_group_idle_timeout(struct wpa_supplicant *wpa_s);
static void wpas_p2p_group_formation_timeout(void *eloop_ctx,
					     void *timeout_ctx);
static void wpas_p2p_group_freq_conflict(void *eloop_ctx, void *timeout_ctx);
static int wpas_p2p_fallback_to_go_neg(struct wpa_supplicant *wpa_s,
				       int group_added);
static void wpas_p2p_stop_find_oper(struct wpa_supplicant *wpa_s);
static void wpas_stop_listen(void *ctx);
static void wpas_p2p_psk_failure_removal(void *eloop_ctx, void *timeout_ctx);
static void wpas_p2p_group_deinit(struct wpa_supplicant *wpa_s);
static int wpas_p2p_add_group_interface(struct wpa_supplicant *wpa_s,
					enum wpa_driver_if_type type);
static void wpas_p2p_group_formation_failed(struct wpa_supplicant *wpa_s,
					    int already_deleted);
static void wpas_p2p_optimize_listen_channel(struct wpa_supplicant *wpa_s,
					     struct wpa_used_freq_data *freqs,
					     unsigned int num);
static void wpas_p2p_move_go(void *eloop_ctx, void *timeout_ctx);
static int wpas_p2p_go_is_peer_freq(struct wpa_supplicant *wpa_s, int freq);
static void
wpas_p2p_consider_moving_gos(struct wpa_supplicant *wpa_s,
			     struct wpa_used_freq_data *freqs, unsigned int num,
			     enum wpas_p2p_channel_update_trig trig);
static void wpas_p2p_reconsider_moving_go(void *eloop_ctx, void *timeout_ctx);


static int wpas_get_6ghz_he_chwidth_capab(struct hostapd_hw_modes *mode)
{
	int he_capab = 0;

	if (mode)
		he_capab = mode->he_capab[WPAS_MODE_INFRA].phy_cap[
			HE_PHYCAP_CHANNEL_WIDTH_SET_IDX];
	return he_capab;
}


/*
 * Get the number of concurrent channels that the HW can operate, but that are
 * currently not in use by any of the wpa_supplicant interfaces.
 */
static int wpas_p2p_num_unused_channels(struct wpa_supplicant *wpa_s)
{
	int *freqs;
	int num, unused;

	freqs = os_calloc(wpa_s->num_multichan_concurrent, sizeof(int));
	if (!freqs)
		return -1;

	num = get_shared_radio_freqs(wpa_s, freqs,
				     wpa_s->num_multichan_concurrent);
	os_free(freqs);

	unused = wpa_s->num_multichan_concurrent - num;
	wpa_dbg(wpa_s, MSG_DEBUG, "P2P: num_unused_channels: %d", unused);
	return unused;
}


/*
 * Get the frequencies that are currently in use by one or more of the virtual
 * interfaces, and that are also valid for P2P operation.
 */
static unsigned int
wpas_p2p_valid_oper_freqs(struct wpa_supplicant *wpa_s,
			  struct wpa_used_freq_data *p2p_freqs,
			  unsigned int len)
{
	struct wpa_used_freq_data *freqs;
	unsigned int num, i, j;

	freqs = os_calloc(wpa_s->num_multichan_concurrent,
			  sizeof(struct wpa_used_freq_data));
	if (!freqs)
		return 0;

	num = get_shared_radio_freqs_data(wpa_s, freqs,
					  wpa_s->num_multichan_concurrent);

	os_memset(p2p_freqs, 0, sizeof(struct wpa_used_freq_data) * len);

	for (i = 0, j = 0; i < num && j < len; i++) {
		if (p2p_supported_freq(wpa_s->global->p2p, freqs[i].freq))
			p2p_freqs[j++] = freqs[i];
	}

	os_free(freqs);

	dump_freq_data(wpa_s, "valid for P2P", p2p_freqs, j);

	return j;
}


static void wpas_p2p_set_own_freq_preference(struct wpa_supplicant *wpa_s,
					     int freq)
{
	if (wpa_s->global->p2p_disabled || wpa_s->global->p2p == NULL)
		return;

	/* Use the wpa_s used to control the P2P Device operation */
	wpa_s = wpa_s->global->p2p_init_wpa_s;

	if (wpa_s->conf->p2p_ignore_shared_freq &&
	    freq > 0 && wpa_s->num_multichan_concurrent > 1 &&
	    wpas_p2p_num_unused_channels(wpa_s) > 0) {
		wpa_printf(MSG_DEBUG, "P2P: Ignore own channel preference %d MHz due to p2p_ignore_shared_freq=1 configuration",
			   freq);
		freq = 0;
	}
	p2p_set_own_freq_preference(wpa_s->global->p2p, freq);
}


static void wpas_p2p_scan_res_handled(struct wpa_supplicant *wpa_s)
{
	unsigned int delay = wpas_p2p_search_delay(wpa_s);

	/* In case of concurrent P2P and external scans, delay P2P search. */
	if (external_scan_running(wpa_s->radio)) {
		delay = wpa_s->conf->p2p_search_delay;
		wpa_printf(MSG_DEBUG,
			   "P2P: Delay next P2P search by %d ms to let externally triggered scan complete",
			   delay);
	}

	p2p_scan_res_handled(wpa_s->global->p2p, delay);
}


static void wpas_p2p_scan_res_handler(struct wpa_supplicant *wpa_s,
				      struct wpa_scan_results *scan_res)
{
	size_t i;

	if (wpa_s->p2p_scan_work) {
		struct wpa_radio_work *work = wpa_s->p2p_scan_work;
		wpa_s->p2p_scan_work = NULL;
		radio_work_done(work);
	}

	if (wpa_s->global->p2p_disabled || wpa_s->global->p2p == NULL)
		return;

	wpa_printf(MSG_DEBUG, "P2P: Scan results received (%d BSS)",
		   (int) scan_res->num);

	for (i = 0; i < scan_res->num; i++) {
		struct wpa_scan_res *bss = scan_res->res[i];
		struct os_reltime time_tmp_age, entry_ts;
		const u8 *ies;
		size_t ies_len;

		time_tmp_age.sec = bss->age / 1000;
		time_tmp_age.usec = (bss->age % 1000) * 1000;
		os_reltime_sub(&scan_res->fetch_time, &time_tmp_age, &entry_ts);

		ies = (const u8 *) (bss + 1);
		ies_len = bss->ie_len;
		if (bss->beacon_ie_len > 0 &&
		    !wpa_scan_get_vendor_ie(bss, P2P_IE_VENDOR_TYPE) &&
		    wpa_scan_get_vendor_ie_beacon(bss, P2P_IE_VENDOR_TYPE)) {
			wpa_printf(MSG_DEBUG, "P2P: Use P2P IE(s) from Beacon frame since no P2P IE(s) in Probe Response frames received for "
				   MACSTR, MAC2STR(bss->bssid));
			ies = ies + ies_len;
			ies_len = bss->beacon_ie_len;
		}


		if (p2p_scan_res_handler(wpa_s->global->p2p, bss->bssid,
					 bss->freq, &entry_ts, bss->level,
					 ies, ies_len) > 0)
			break;
	}

	wpas_p2p_scan_res_handled(wpa_s);
}


static void wpas_p2p_scan_res_fail_handler(struct wpa_supplicant *wpa_s)
{
	if (wpa_s->p2p_scan_work) {
		struct wpa_radio_work *work = wpa_s->p2p_scan_work;

		wpa_s->p2p_scan_work = NULL;
		radio_work_done(work);
	}

	if (wpa_s->global->p2p_disabled || !wpa_s->global->p2p)
		return;

	wpa_dbg(wpa_s, MSG_DEBUG,
		"P2P: Failed to get scan results - try to continue");
	wpas_p2p_scan_res_handled(wpa_s);
}


static void wpas_p2p_trigger_scan_cb(struct wpa_radio_work *work, int deinit)
{
	struct wpa_supplicant *wpa_s = work->wpa_s;
	struct wpa_driver_scan_params *params = work->ctx;
	int ret;

	if (deinit) {
		if (!work->started) {
			wpa_scan_free_params(params);
			return;
		}

		wpa_s->p2p_scan_work = NULL;
		return;
	}

	if (wpa_s->clear_driver_scan_cache) {
		wpa_printf(MSG_DEBUG,
			   "Request driver to clear scan cache due to local BSS flush");
		params->only_new_results = 1;
	}

	if (!params->p2p_include_6ghz && !params->freqs) {
		wpa_printf(MSG_DEBUG,
			   "P2P: Exclude 6 GHz channels - update the scan frequency list");
		wpa_add_scan_freqs_list(wpa_s, HOSTAPD_MODE_IEEE80211G, params,
					0);
		wpa_add_scan_freqs_list(wpa_s, HOSTAPD_MODE_IEEE80211A, params,
					0);
	}
	ret = wpa_drv_scan(wpa_s, params);
	if (ret == 0)
		wpa_s->curr_scan_cookie = params->scan_cookie;
	wpa_scan_free_params(params);
	work->ctx = NULL;
	if (ret) {
		radio_work_done(work);
		p2p_notify_scan_trigger_status(wpa_s->global->p2p, ret);
		return;
	}

	p2p_notify_scan_trigger_status(wpa_s->global->p2p, ret);
	os_get_reltime(&wpa_s->scan_trigger_time);
	wpa_s->scan_res_handler = wpas_p2p_scan_res_handler;
	wpa_s->scan_res_fail_handler = wpas_p2p_scan_res_fail_handler;
	wpa_s->own_scan_requested = 1;
	wpa_s->clear_driver_scan_cache = 0;
	wpa_s->p2p_scan_work = work;
}


static int wpas_p2p_search_social_channel(struct wpa_supplicant *wpa_s,
					  int freq)
{
	if (wpa_s->global->p2p_24ghz_social_channels &&
	    (freq == 2412 || freq == 2437 || freq == 2462)) {
		/*
		 * Search all social channels regardless of whether these have
		 * been disabled for P2P operating channel use to avoid missing
		 * peers.
		 */
		return 1;
	}
	return p2p_supported_freq(wpa_s->global->p2p, freq);
}


static int wpas_p2p_scan(void *ctx, enum p2p_scan_type type, int freq,
			 unsigned int num_req_dev_types,
			 const u8 *req_dev_types, const u8 *dev_id, u16 pw_id,
			 bool include_6ghz)
{
	struct wpa_supplicant *wpa_s = ctx;
	struct wpa_driver_scan_params *params = NULL;
	struct wpabuf *wps_ie, *ies;
	unsigned int num_channels = 0;
	int social_channels_freq[] = { 2412, 2437, 2462, 60480 };
	size_t ielen;
	u8 *n, i;
	unsigned int bands;

	if (wpa_s->global->p2p_disabled || wpa_s->global->p2p == NULL)
		return -1;

	if (wpa_s->p2p_scan_work) {
		wpa_dbg(wpa_s, MSG_INFO, "P2P: Reject scan trigger since one is already pending");
		return -1;
	}

	params = os_zalloc(sizeof(*params));
	if (params == NULL)
		return -1;

	/* P2P Wildcard SSID */
	params->num_ssids = 1;
	n = os_malloc(P2P_WILDCARD_SSID_LEN);
	if (n == NULL)
		goto fail;
	os_memcpy(n, P2P_WILDCARD_SSID, P2P_WILDCARD_SSID_LEN);
	params->ssids[0].ssid = n;
	params->ssids[0].ssid_len = P2P_WILDCARD_SSID_LEN;

	wpa_s->wps->dev.p2p = 1;
	wps_ie = wps_build_probe_req_ie(pw_id, &wpa_s->wps->dev,
					wpa_s->wps->uuid, WPS_REQ_ENROLLEE,
					num_req_dev_types, req_dev_types);
	if (wps_ie == NULL)
		goto fail;
	if (!wpa_s->conf->p2p_6ghz_disable)
		params->p2p_include_6ghz = include_6ghz;
	switch (type) {
	case P2P_SCAN_SOCIAL:
		params->freqs = os_calloc(ARRAY_SIZE(social_channels_freq) + 1,
					  sizeof(int));
		if (params->freqs == NULL)
			goto fail;
		for (i = 0; i < ARRAY_SIZE(social_channels_freq); i++) {
			if (wpas_p2p_search_social_channel(
				    wpa_s, social_channels_freq[i]))
				params->freqs[num_channels++] =
					social_channels_freq[i];
		}
		params->freqs[num_channels++] = 0;
		break;
	case P2P_SCAN_FULL:
		break;
	case P2P_SCAN_SPECIFIC:
		params->freqs = os_calloc(2, sizeof(int));
		if (params->freqs == NULL)
			goto fail;
		params->freqs[0] = freq;
		params->freqs[1] = 0;
		break;
	case P2P_SCAN_SOCIAL_PLUS_ONE:
		params->freqs = os_calloc(ARRAY_SIZE(social_channels_freq) + 2,
					  sizeof(int));
		if (params->freqs == NULL)
			goto fail;
		for (i = 0; i < ARRAY_SIZE(social_channels_freq); i++) {
			if (wpas_p2p_search_social_channel(
				    wpa_s, social_channels_freq[i]))
				params->freqs[num_channels++] =
					social_channels_freq[i];
		}
		if (p2p_supported_freq(wpa_s->global->p2p, freq))
			params->freqs[num_channels++] = freq;
		params->freqs[num_channels++] = 0;
		break;
	}

	ielen = p2p_scan_ie_buf_len(wpa_s->global->p2p);
	ies = wpabuf_alloc(wpabuf_len(wps_ie) + ielen);
	if (ies == NULL) {
		wpabuf_free(wps_ie);
		goto fail;
	}
	wpabuf_put_buf(ies, wps_ie);
	wpabuf_free(wps_ie);

	bands = wpas_get_bands(wpa_s, params->freqs);
	p2p_scan_ie(wpa_s->global->p2p, ies, dev_id, bands);

	params->p2p_probe = 1;
	n = os_malloc(wpabuf_len(ies));
	if (n == NULL) {
		wpabuf_free(ies);
		goto fail;
	}
	os_memcpy(n, wpabuf_head(ies), wpabuf_len(ies));
	params->extra_ies = n;
	params->extra_ies_len = wpabuf_len(ies);
	wpabuf_free(ies);

	radio_remove_works(wpa_s, "p2p-scan", 0);
	if (radio_add_work(wpa_s, 0, "p2p-scan", 0, wpas_p2p_trigger_scan_cb,
			   params) < 0)
		goto fail;
	return 0;

fail:
	wpa_scan_free_params(params);
	return -1;
}


static enum wpa_driver_if_type wpas_p2p_if_type(int p2p_group_interface)
{
	switch (p2p_group_interface) {
	case P2P_GROUP_INTERFACE_PENDING:
		return WPA_IF_P2P_GROUP;
	case P2P_GROUP_INTERFACE_GO:
		return WPA_IF_P2P_GO;
	case P2P_GROUP_INTERFACE_CLIENT:
		return WPA_IF_P2P_CLIENT;
	}

	return WPA_IF_P2P_GROUP;
}


static struct wpa_supplicant * wpas_get_p2p_group(struct wpa_supplicant *wpa_s,
						  const u8 *ssid,
						  size_t ssid_len, int *go)
{
	struct wpa_ssid *s;

	for (wpa_s = wpa_s->global->ifaces; wpa_s; wpa_s = wpa_s->next) {
		for (s = wpa_s->conf->ssid; s; s = s->next) {
			if (s->disabled != 0 || !s->p2p_group ||
			    s->ssid_len != ssid_len ||
			    os_memcmp(ssid, s->ssid, ssid_len) != 0)
				continue;
			if (s->mode == WPAS_MODE_P2P_GO &&
			    s != wpa_s->current_ssid)
				continue;
			if (go)
				*go = s->mode == WPAS_MODE_P2P_GO;
			return wpa_s;
		}
	}

	return NULL;
}


static void run_wpas_p2p_disconnect(void *eloop_ctx, void *timeout_ctx)
{
	struct wpa_supplicant *wpa_s = eloop_ctx;
	wpa_printf(MSG_DEBUG,
		   "P2P: Complete previously requested removal of %s",
		   wpa_s->ifname);
	wpas_p2p_disconnect(wpa_s);
}


static int wpas_p2p_disconnect_safely(struct wpa_supplicant *wpa_s,
				      struct wpa_supplicant *calling_wpa_s)
{
	if (calling_wpa_s == wpa_s && wpa_s &&
	    wpa_s->p2p_group_interface != NOT_P2P_GROUP_INTERFACE) {
		/*
		 * The calling wpa_s instance is going to be removed. Do that
		 * from an eloop callback to keep the instance available until
		 * the caller has returned. This may be needed, e.g., to provide
		 * control interface responses on the per-interface socket.
		 */
		if (eloop_register_timeout(0, 0, run_wpas_p2p_disconnect,
					   wpa_s, NULL) < 0)
			return -1;
		return 0;
	}

	return wpas_p2p_disconnect(wpa_s);
}


/* Determine total number of clients in active groups where we are the GO */
static unsigned int p2p_group_go_member_count(struct wpa_supplicant *wpa_s)
{
	unsigned int count = 0;
	struct wpa_ssid *s;

	for (wpa_s = wpa_s->global->ifaces; wpa_s; wpa_s = wpa_s->next) {
		for (s = wpa_s->conf->ssid; s; s = s->next) {
			wpa_printf(MSG_DEBUG,
				   "P2P: sup:%p ssid:%p disabled:%d p2p:%d mode:%d",
				   wpa_s, s, s->disabled, s->p2p_group,
				   s->mode);
			if (!s->disabled && s->p2p_group &&
			    s->mode == WPAS_MODE_P2P_GO) {
				count += p2p_get_group_num_members(
					wpa_s->p2p_group);
			}
		}
	}

	return count;
}


static unsigned int p2p_is_active_persistent_group(struct wpa_supplicant *wpa_s)
{
	return !wpa_s->p2p_mgmt && wpa_s->current_ssid &&
		!wpa_s->current_ssid->disabled &&
		wpa_s->current_ssid->p2p_group &&
		wpa_s->current_ssid->p2p_persistent_group;
}


static unsigned int p2p_is_active_persistent_go(struct wpa_supplicant *wpa_s)
{
	return p2p_is_active_persistent_group(wpa_s) &&
		wpa_s->current_ssid->mode == WPAS_MODE_P2P_GO;
}


/* Find an interface for a P2P group where we are the GO */
static struct wpa_supplicant *
wpas_p2p_get_go_group(struct wpa_supplicant *wpa_s)
{
	struct wpa_supplicant *save = NULL;

	if (!wpa_s)
		return NULL;

	for (wpa_s = wpa_s->global->ifaces; wpa_s; wpa_s = wpa_s->next) {
		if (!p2p_is_active_persistent_go(wpa_s))
			continue;

		/* Prefer a group with connected clients */
		if (p2p_get_group_num_members(wpa_s->p2p_group))
			return wpa_s;
		save = wpa_s;
	}

	/* No group with connected clients, so pick the one without (if any) */
	return save;
}


static unsigned int p2p_is_active_persistent_cli(struct wpa_supplicant *wpa_s)
{
	return p2p_is_active_persistent_group(wpa_s) &&
		wpa_s->current_ssid->mode == WPAS_MODE_INFRA;
}


/* Find an interface for a P2P group where we are the P2P Client */
static struct wpa_supplicant *
wpas_p2p_get_cli_group(struct wpa_supplicant *wpa_s)
{
	for (wpa_s = wpa_s->global->ifaces; wpa_s; wpa_s = wpa_s->next) {
		if (p2p_is_active_persistent_cli(wpa_s))
			return wpa_s;
	}

	return NULL;
}


/* Find a persistent group where we are the GO */
static struct wpa_ssid *
wpas_p2p_get_persistent_go(struct wpa_supplicant *wpa_s)
{
	struct wpa_ssid *s;

	for (s = wpa_s->conf->ssid; s; s = s->next) {
		if (s->disabled == 2 && s->mode == WPAS_MODE_P2P_GO)
			return s;
	}

	return NULL;
}


static u8 p2ps_group_capability(void *ctx, u8 incoming, u8 role,
				unsigned int *force_freq,
				unsigned int *pref_freq)
{
	struct wpa_supplicant *wpa_s = ctx;
	struct wpa_ssid *s;
	u8 conncap = P2PS_SETUP_NONE;
	unsigned int owned_members = 0;
	struct wpa_supplicant *go_wpa_s, *cli_wpa_s;
	struct wpa_ssid *persistent_go;
	int p2p_no_group_iface;
	unsigned int pref_freq_list[P2P_MAX_PREF_CHANNELS], size;

	wpa_printf(MSG_DEBUG, "P2P: Conncap - in:%d role:%d", incoming, role);

	if (force_freq)
		*force_freq = 0;
	if (pref_freq)
		*pref_freq = 0;

	size = P2P_MAX_PREF_CHANNELS;
	if (force_freq && pref_freq &&
	    !wpas_p2p_setup_freqs(wpa_s, 0, (int *) force_freq,
				  (int *) pref_freq, 0, pref_freq_list, &size))
		wpas_p2p_set_own_freq_preference(wpa_s,
						 *force_freq ? *force_freq :
						 *pref_freq);

	/*
	 * For non-concurrent capable devices:
	 * If persistent_go, then no new.
	 * If GO, then no client.
	 * If client, then no GO.
	 */
	go_wpa_s = wpas_p2p_get_go_group(wpa_s);
	if (go_wpa_s)
		owned_members = p2p_get_group_num_members(go_wpa_s->p2p_group);
	persistent_go = wpas_p2p_get_persistent_go(wpa_s);
	p2p_no_group_iface = !wpas_p2p_create_iface(wpa_s);
	cli_wpa_s = wpas_p2p_get_cli_group(wpa_s);

	wpa_printf(MSG_DEBUG,
		   "P2P: GO(iface)=%p members=%u CLI(iface)=%p persistent(ssid)=%p",
		   go_wpa_s, owned_members, cli_wpa_s, persistent_go);

	/* If not concurrent, restrict our choices */
	if (p2p_no_group_iface) {
		wpa_printf(MSG_DEBUG, "P2P: p2p_no_group_iface");

		if (cli_wpa_s)
			return P2PS_SETUP_NONE;

		if (go_wpa_s) {
			if (role == P2PS_SETUP_CLIENT ||
			    incoming == P2PS_SETUP_GROUP_OWNER ||
			    p2p_client_limit_reached(go_wpa_s->p2p_group))
				return P2PS_SETUP_NONE;

			return P2PS_SETUP_GROUP_OWNER;
		}

		if (persistent_go) {
			if (role == P2PS_SETUP_NONE || role == P2PS_SETUP_NEW) {
				if (!incoming)
					return P2PS_SETUP_GROUP_OWNER |
						P2PS_SETUP_CLIENT;
				if (incoming == P2PS_SETUP_NEW) {
					u8 r;

					if (os_get_random(&r, sizeof(r)) < 0 ||
					    (r & 1))
						return P2PS_SETUP_CLIENT;
					return P2PS_SETUP_GROUP_OWNER;
				}
			}
		}
	}

	/* If a required role has been specified, handle it here */
	if (role && role != P2PS_SETUP_NEW) {
		switch (incoming) {
		case P2PS_SETUP_GROUP_OWNER | P2PS_SETUP_NEW:
		case P2PS_SETUP_GROUP_OWNER | P2PS_SETUP_CLIENT:
			/*
			 * Peer has an active GO, so if the role allows it and
			 * we do not have any active roles, become client.
			 */
			if ((role & P2PS_SETUP_CLIENT) && !go_wpa_s &&
			    !cli_wpa_s)
				return P2PS_SETUP_CLIENT;

			/* fall through */

		case P2PS_SETUP_NONE:
		case P2PS_SETUP_NEW:
			conncap = role;
			goto grp_owner;

		case P2PS_SETUP_GROUP_OWNER:
			/*
			 * Must be a complimentary role - cannot be a client to
			 * more than one peer.
			 */
			if (incoming == role || cli_wpa_s)
				return P2PS_SETUP_NONE;

			return P2PS_SETUP_CLIENT;

		case P2PS_SETUP_CLIENT:
			/* Must be a complimentary role */
			if (incoming != role) {
				conncap = P2PS_SETUP_GROUP_OWNER;
				goto grp_owner;
			}
			/* fall through */

		default:
			return P2PS_SETUP_NONE;
		}
	}

	/*
	 * For now, we only will support ownership of one group, and being a
	 * client of one group. Therefore, if we have either an existing GO
	 * group, or an existing client group, we will not do a new GO
	 * negotiation, but rather try to re-use the existing groups.
	 */
	switch (incoming) {
	case P2PS_SETUP_NONE:
	case P2PS_SETUP_NEW:
		if (cli_wpa_s)
			conncap = P2PS_SETUP_GROUP_OWNER;
		else if (!owned_members)
			conncap = P2PS_SETUP_NEW;
		else if (incoming == P2PS_SETUP_NONE)
			conncap = P2PS_SETUP_GROUP_OWNER | P2PS_SETUP_CLIENT;
		else
			conncap = P2PS_SETUP_CLIENT;
		break;

	case P2PS_SETUP_CLIENT:
		conncap = P2PS_SETUP_GROUP_OWNER;
		break;

	case P2PS_SETUP_GROUP_OWNER:
		if (!cli_wpa_s)
			conncap = P2PS_SETUP_CLIENT;
		break;

	case P2PS_SETUP_GROUP_OWNER | P2PS_SETUP_NEW:
	case P2PS_SETUP_GROUP_OWNER | P2PS_SETUP_CLIENT:
		if (cli_wpa_s)
			conncap = P2PS_SETUP_GROUP_OWNER;
		else {
			u8 r;

			if (os_get_random(&r, sizeof(r)) < 0 ||
			    (r & 1))
				conncap = P2PS_SETUP_CLIENT;
			else
				conncap = P2PS_SETUP_GROUP_OWNER;
		}
		break;

	default:
		return P2PS_SETUP_NONE;
	}

grp_owner:
	if ((conncap & P2PS_SETUP_GROUP_OWNER) ||
	    (!incoming && (conncap & P2PS_SETUP_NEW))) {
		if (go_wpa_s && p2p_client_limit_reached(go_wpa_s->p2p_group))
			conncap &= ~P2PS_SETUP_GROUP_OWNER;

		s = wpas_p2p_get_persistent_go(wpa_s);
		if (!s && !go_wpa_s && p2p_no_group_iface) {
			p2p_set_intended_addr(wpa_s->global->p2p,
					      wpa_s->p2p_mgmt ?
					      wpa_s->parent->own_addr :
					      wpa_s->own_addr);
		} else if (!s && !go_wpa_s) {
			if (wpas_p2p_add_group_interface(wpa_s,
							 WPA_IF_P2P_GROUP) < 0) {
				wpa_printf(MSG_ERROR,
					   "P2P: Failed to allocate a new interface for the group");
				return P2PS_SETUP_NONE;
			}
			wpa_s->global->pending_group_iface_for_p2ps = 1;
			p2p_set_intended_addr(wpa_s->global->p2p,
					      wpa_s->pending_interface_addr);
		}
	}

	return conncap;
}


static int wpas_p2p_group_delete(struct wpa_supplicant *wpa_s,
				 enum p2p_group_removal_reason removal_reason)
{
	struct wpa_ssid *ssid;
	char *gtype;
	const char *reason;

	ssid = wpa_s->current_ssid;
	if (ssid == NULL) {
		/*
		 * The current SSID was not known, but there may still be a
		 * pending P2P group interface waiting for provisioning or a
		 * P2P group that is trying to reconnect.
		 */
		ssid = wpa_s->conf->ssid;
		while (ssid) {
			if (ssid->p2p_group && ssid->disabled != 2)
				break;
			ssid = ssid->next;
		}
		if (ssid == NULL &&
			wpa_s->p2p_group_interface == NOT_P2P_GROUP_INTERFACE)
		{
			wpa_printf(MSG_ERROR, "P2P: P2P group interface "
				   "not found");
			return -1;
		}
	}
	if (wpa_s->p2p_group_interface == P2P_GROUP_INTERFACE_GO)
		gtype = "GO";
	else if (wpa_s->p2p_group_interface == P2P_GROUP_INTERFACE_CLIENT ||
		 (ssid && ssid->mode == WPAS_MODE_INFRA)) {
		wpa_s->reassociate = 0;
		wpa_s->disconnected = 1;
		gtype = "client";
	} else
		gtype = "GO";

	if (removal_reason != P2P_GROUP_REMOVAL_SILENT && ssid)
		wpas_notify_p2p_group_removed(wpa_s, ssid, gtype);

	if (os_strcmp(gtype, "client") == 0) {
		wpa_supplicant_deauthenticate(wpa_s, WLAN_REASON_DEAUTH_LEAVING);
		if (eloop_is_timeout_registered(wpas_p2p_psk_failure_removal,
						wpa_s, NULL)) {
			wpa_printf(MSG_DEBUG,
				   "P2P: PSK failure removal was scheduled, so use PSK failure as reason for group removal");
			removal_reason = P2P_GROUP_REMOVAL_PSK_FAILURE;
			eloop_cancel_timeout(wpas_p2p_psk_failure_removal,
					     wpa_s, NULL);
		}
	}

	if (wpa_s->cross_connect_in_use) {
		wpa_s->cross_connect_in_use = 0;
		wpa_msg_global(wpa_s->p2pdev, MSG_INFO,
			       P2P_EVENT_CROSS_CONNECT_DISABLE "%s %s",
			       wpa_s->ifname, wpa_s->cross_connect_uplink);
	}
	switch (removal_reason) {
	case P2P_GROUP_REMOVAL_REQUESTED:
		reason = " reason=REQUESTED";
		break;
	case P2P_GROUP_REMOVAL_FORMATION_FAILED:
		reason = " reason=FORMATION_FAILED";
		break;
	case P2P_GROUP_REMOVAL_IDLE_TIMEOUT:
		reason = " reason=IDLE";
		break;
	case P2P_GROUP_REMOVAL_UNAVAILABLE:
		reason = " reason=UNAVAILABLE";
		break;
	case P2P_GROUP_REMOVAL_GO_ENDING_SESSION:
		reason = " reason=GO_ENDING_SESSION";
		break;
	case P2P_GROUP_REMOVAL_PSK_FAILURE:
		reason = " reason=PSK_FAILURE";
		break;
	case P2P_GROUP_REMOVAL_FREQ_CONFLICT:
		reason = " reason=FREQ_CONFLICT";
		break;
	default:
		reason = "";
		break;
	}
	if (removal_reason != P2P_GROUP_REMOVAL_SILENT) {
		wpa_msg_global(wpa_s->p2pdev, MSG_INFO,
			       P2P_EVENT_GROUP_REMOVED "%s %s%s",
			       wpa_s->ifname, gtype, reason);
	}

	if (eloop_cancel_timeout(wpas_p2p_group_freq_conflict, wpa_s, NULL) > 0)
		wpa_printf(MSG_DEBUG, "P2P: Cancelled P2P group freq_conflict timeout");
	if (eloop_cancel_timeout(wpas_p2p_group_idle_timeout, wpa_s, NULL) > 0)
		wpa_printf(MSG_DEBUG, "P2P: Cancelled P2P group idle timeout");
	if (eloop_cancel_timeout(wpas_p2p_group_formation_timeout,
				 wpa_s->p2pdev, NULL) > 0) {
		wpa_printf(MSG_DEBUG, "P2P: Cancelled P2P group formation "
			   "timeout");
		wpa_s->p2p_in_provisioning = 0;
		wpas_p2p_group_formation_failed(wpa_s, 1);
	}

	wpa_s->p2p_in_invitation = 0;
	eloop_cancel_timeout(wpas_p2p_move_go, wpa_s, NULL);
	eloop_cancel_timeout(wpas_p2p_reconsider_moving_go, wpa_s, NULL);

	/*
	 * Make sure wait for the first client does not remain active after the
	 * group has been removed.
	 */
	wpa_s->global->p2p_go_wait_client.sec = 0;

	if (wpa_s->p2p_group_interface != NOT_P2P_GROUP_INTERFACE) {
		struct wpa_global *global;
		char *ifname;
		enum wpa_driver_if_type type;
		wpa_printf(MSG_DEBUG, "P2P: Remove group interface %s",
			wpa_s->ifname);
		global = wpa_s->global;
		ifname = os_strdup(wpa_s->ifname);
		type = wpas_p2p_if_type(wpa_s->p2p_group_interface);
		eloop_cancel_timeout(run_wpas_p2p_disconnect, wpa_s, NULL);
		wpa_supplicant_remove_iface(wpa_s->global, wpa_s, 0);
		wpa_s = global->ifaces;
		if (wpa_s && ifname)
			wpa_drv_if_remove(wpa_s, type, ifname);
		os_free(ifname);
		return 1;
	}

	/*
	 * The primary interface was used for P2P group operations, so
	 * need to reset its p2pdev.
	 */
	wpa_s->p2pdev = wpa_s->parent;

	if (!wpa_s->p2p_go_group_formation_completed) {
		wpa_s->global->p2p_group_formation = NULL;
		wpa_s->p2p_in_provisioning = 0;
	}

	wpa_s->show_group_started = 0;
	os_free(wpa_s->go_params);
	wpa_s->go_params = NULL;

	os_free(wpa_s->p2p_group_common_freqs);
	wpa_s->p2p_group_common_freqs = NULL;
	wpa_s->p2p_group_common_freqs_num = 0;
	wpa_s->p2p_go_do_acs = 0;
	wpa_s->p2p_go_allow_dfs = 0;

	wpa_s->waiting_presence_resp = 0;

	wpa_printf(MSG_DEBUG, "P2P: Remove temporary group network");
	if (ssid && (ssid->p2p_group ||
		     ssid->mode == WPAS_MODE_P2P_GROUP_FORMATION ||
		     (ssid->key_mgmt & WPA_KEY_MGMT_WPS))) {
		int id = ssid->id;
		if (ssid == wpa_s->current_ssid) {
			wpa_sm_set_config(wpa_s->wpa, NULL);
			eapol_sm_notify_config(wpa_s->eapol, NULL, NULL);
			wpa_s->current_ssid = NULL;
		}
		/*
		 * Networks objects created during any P2P activities are not
		 * exposed out as they might/will confuse certain non-P2P aware
		 * applications since these network objects won't behave like
		 * regular ones.
		 *
		 * Likewise, we don't send out network removed signals for such
		 * network objects.
		 */
		wpa_config_remove_network(wpa_s->conf, id);
		wpa_supplicant_clear_status(wpa_s);
		wpa_supplicant_cancel_sched_scan(wpa_s);
	} else {
		wpa_printf(MSG_DEBUG, "P2P: Temporary group network not "
			   "found");
	}
	if (wpa_s->ap_iface)
		wpa_supplicant_ap_deinit(wpa_s);
	else
		wpa_drv_deinit_p2p_cli(wpa_s);

	os_memset(wpa_s->go_dev_addr, 0, ETH_ALEN);

	return 0;
}


static int wpas_p2p_persistent_group(struct wpa_supplicant *wpa_s,
				     u8 *go_dev_addr,
				     const u8 *ssid, size_t ssid_len)
{
	struct wpa_bss *bss;
	const u8 *bssid;
	struct wpabuf *p2p;
	u8 group_capab;
	const u8 *addr;

	if (wpa_s->go_params)
		bssid = wpa_s->go_params->peer_interface_addr;
	else
		bssid = wpa_s->bssid;

	bss = wpa_bss_get(wpa_s, bssid, ssid, ssid_len);
	if (bss == NULL && wpa_s->go_params &&
	    !is_zero_ether_addr(wpa_s->go_params->peer_device_addr))
		bss = wpa_bss_get_p2p_dev_addr(
			wpa_s, wpa_s->go_params->peer_device_addr);
	if (bss == NULL) {
		u8 iface_addr[ETH_ALEN];
		if (p2p_get_interface_addr(wpa_s->global->p2p, bssid,
					   iface_addr) == 0)
			bss = wpa_bss_get(wpa_s, iface_addr, ssid, ssid_len);
	}
	if (bss == NULL) {
		wpa_printf(MSG_DEBUG, "P2P: Could not figure out whether "
			   "group is persistent - BSS " MACSTR " not found",
			   MAC2STR(bssid));
		return 0;
	}

	p2p = wpa_bss_get_vendor_ie_multi(bss, P2P_IE_VENDOR_TYPE);
	if (p2p == NULL)
		p2p = wpa_bss_get_vendor_ie_multi_beacon(bss,
							 P2P_IE_VENDOR_TYPE);
	if (p2p == NULL) {
		wpa_printf(MSG_DEBUG, "P2P: Could not figure out whether "
			   "group is persistent - BSS " MACSTR
			   " did not include P2P IE", MAC2STR(bssid));
		wpa_hexdump(MSG_DEBUG, "P2P: Probe Response IEs",
			    wpa_bss_ie_ptr(bss), bss->ie_len);
		wpa_hexdump(MSG_DEBUG, "P2P: Beacon IEs",
			    wpa_bss_ie_ptr(bss) + bss->ie_len,
			    bss->beacon_ie_len);
		return 0;
	}

	group_capab = p2p_get_group_capab(p2p);
	addr = p2p_get_go_dev_addr(p2p);
	wpa_printf(MSG_DEBUG, "P2P: Checking whether group is persistent: "
		   "group_capab=0x%x", group_capab);
	if (addr) {
		os_memcpy(go_dev_addr, addr, ETH_ALEN);
		wpa_printf(MSG_DEBUG, "P2P: GO Device Address " MACSTR,
			   MAC2STR(addr));
	} else
		os_memset(go_dev_addr, 0, ETH_ALEN);
	wpabuf_free(p2p);

	wpa_printf(MSG_DEBUG, "P2P: BSS " MACSTR " group_capab=0x%x "
		   "go_dev_addr=" MACSTR,
		   MAC2STR(bssid), group_capab, MAC2STR(go_dev_addr));

	return !!(group_capab & P2P_GROUP_CAPAB_PERSISTENT_GROUP);
}


static int wpas_p2p_store_persistent_group(struct wpa_supplicant *wpa_s,
					   struct wpa_ssid *ssid,
					   const u8 *go_dev_addr)
{
	struct wpa_ssid *s;
	int changed = 0;

	wpa_printf(MSG_DEBUG, "P2P: Storing credentials for a persistent "
		   "group (GO Dev Addr " MACSTR ")", MAC2STR(go_dev_addr));
	for (s = wpa_s->conf->ssid; s; s = s->next) {
		if (s->disabled == 2 &&
		    os_memcmp(go_dev_addr, s->bssid, ETH_ALEN) == 0 &&
		    s->ssid_len == ssid->ssid_len &&
		    os_memcmp(ssid->ssid, s->ssid, ssid->ssid_len) == 0)
			break;
	}

	if (s) {
		wpa_printf(MSG_DEBUG, "P2P: Update existing persistent group "
			   "entry");
		if (ssid->passphrase && !s->passphrase)
			changed = 1;
		else if (ssid->passphrase && s->passphrase &&
			 os_strcmp(ssid->passphrase, s->passphrase) != 0)
			changed = 1;
	} else {
		wpa_printf(MSG_DEBUG, "P2P: Create a new persistent group "
			   "entry");
		changed = 1;
		s = wpa_config_add_network(wpa_s->conf);
		if (s == NULL)
			return -1;

		/*
		 * Instead of network_added we emit persistent_group_added
		 * notification. Also to keep the defense checks in
		 * persistent_group obj registration method, we set the
		 * relevant flags in s to designate it as a persistent group.
		 */
		s->p2p_group = 1;
		s->p2p_persistent_group = 1;
		wpas_notify_persistent_group_added(wpa_s, s);
		wpa_config_set_network_defaults(s);
	}

	s->p2p_group = 1;
	s->p2p_persistent_group = 1;
	s->disabled = 2;
	s->bssid_set = 1;
	os_memcpy(s->bssid, go_dev_addr, ETH_ALEN);
	s->mode = ssid->mode;
	s->auth_alg = WPA_AUTH_ALG_OPEN;
	s->key_mgmt = WPA_KEY_MGMT_PSK;
	s->proto = WPA_PROTO_RSN;
	s->pbss = ssid->pbss;
	s->pairwise_cipher = ssid->pbss ? WPA_CIPHER_GCMP : WPA_CIPHER_CCMP;
	s->export_keys = 1;
	if (ssid->passphrase) {
		os_free(s->passphrase);
		s->passphrase = os_strdup(ssid->passphrase);
	}
	if (ssid->psk_set) {
		s->psk_set = 1;
		os_memcpy(s->psk, ssid->psk, 32);
	}
	if (s->passphrase && !s->psk_set)
		wpa_config_update_psk(s);
	if (s->ssid == NULL || s->ssid_len < ssid->ssid_len) {
		os_free(s->ssid);
		s->ssid = os_malloc(ssid->ssid_len);
	}
	if (s->ssid) {
		s->ssid_len = ssid->ssid_len;
		os_memcpy(s->ssid, ssid->ssid, s->ssid_len);
	}
	if (ssid->mode == WPAS_MODE_P2P_GO && wpa_s->global->add_psk) {
		dl_list_add(&s->psk_list, &wpa_s->global->add_psk->list);
		wpa_s->global->add_psk = NULL;
		changed = 1;
	}

	if (changed && wpa_s->conf->update_config &&
	    wpa_config_write(wpa_s->confname, wpa_s->conf)) {
		wpa_printf(MSG_DEBUG, "P2P: Failed to update configuration");
	}

	return s->id;
}


static void wpas_p2p_add_persistent_group_client(struct wpa_supplicant *wpa_s,
						 const u8 *addr)
{
	struct wpa_ssid *ssid, *s;
	u8 *n;
	size_t i;
	int found = 0;
	struct wpa_supplicant *p2p_wpa_s = wpa_s->global->p2p_init_wpa_s;

	ssid = wpa_s->current_ssid;
	if (ssid == NULL || ssid->mode != WPAS_MODE_P2P_GO ||
	    !ssid->p2p_persistent_group)
		return;

	for (s = p2p_wpa_s->conf->ssid; s; s = s->next) {
		if (s->disabled != 2 || s->mode != WPAS_MODE_P2P_GO)
			continue;

		if (s->ssid_len == ssid->ssid_len &&
		    os_memcmp(s->ssid, ssid->ssid, s->ssid_len) == 0)
			break;
	}

	if (s == NULL)
		return;

	for (i = 0; s->p2p_client_list && i < s->num_p2p_clients; i++) {
		if (os_memcmp(s->p2p_client_list + i * 2 * ETH_ALEN, addr,
			      ETH_ALEN) != 0)
			continue;

		if (i == s->num_p2p_clients - 1)
			return; /* already the most recent entry */

		/* move the entry to mark it most recent */
		os_memmove(s->p2p_client_list + i * 2 * ETH_ALEN,
			   s->p2p_client_list + (i + 1) * 2 * ETH_ALEN,
			   (s->num_p2p_clients - i - 1) * 2 * ETH_ALEN);
		os_memcpy(s->p2p_client_list +
			  (s->num_p2p_clients - 1) * 2 * ETH_ALEN, addr,
			  ETH_ALEN);
		os_memset(s->p2p_client_list +
			  (s->num_p2p_clients - 1) * 2 * ETH_ALEN + ETH_ALEN,
			  0xff, ETH_ALEN);
		found = 1;
		break;
	}

	if (!found && s->num_p2p_clients < P2P_MAX_STORED_CLIENTS) {
		n = os_realloc_array(s->p2p_client_list,
				     s->num_p2p_clients + 1, 2 * ETH_ALEN);
		if (n == NULL)
			return;
		os_memcpy(n + s->num_p2p_clients * 2 * ETH_ALEN, addr,
			  ETH_ALEN);
		os_memset(n + s->num_p2p_clients * 2 * ETH_ALEN + ETH_ALEN,
			  0xff, ETH_ALEN);
		s->p2p_client_list = n;
		s->num_p2p_clients++;
	} else if (!found && s->p2p_client_list) {
		/* Not enough room for an additional entry - drop the oldest
		 * entry */
		os_memmove(s->p2p_client_list,
			   s->p2p_client_list + 2 * ETH_ALEN,
			   (s->num_p2p_clients - 1) * 2 * ETH_ALEN);
		os_memcpy(s->p2p_client_list +
			  (s->num_p2p_clients - 1) * 2 * ETH_ALEN,
			  addr, ETH_ALEN);
		os_memset(s->p2p_client_list +
			  (s->num_p2p_clients - 1) * 2 * ETH_ALEN + ETH_ALEN,
			  0xff, ETH_ALEN);
	}

	if (p2p_wpa_s->conf->update_config &&
	    wpa_config_write(p2p_wpa_s->confname, p2p_wpa_s->conf))
		wpa_printf(MSG_DEBUG, "P2P: Failed to update configuration");
}


static void wpas_p2p_group_started(struct wpa_supplicant *wpa_s,
				   int go, struct wpa_ssid *ssid, int freq,
				   const u8 *psk, const char *passphrase,
				   const u8 *go_dev_addr, int persistent,
				   const char *extra)
{
	const char *ssid_txt;
	char psk_txt[65];

	if (psk)
		wpa_snprintf_hex(psk_txt, sizeof(psk_txt), psk, 32);
	else
		psk_txt[0] = '\0';

	if (ssid)
		ssid_txt = wpa_ssid_txt(ssid->ssid, ssid->ssid_len);
	else
		ssid_txt = "";

	if (passphrase && passphrase[0] == '\0')
		passphrase = NULL;

	/*
	 * Include PSK/passphrase only in the control interface message and
	 * leave it out from the debug log entry.
	 */
	wpa_msg_global_ctrl(wpa_s->p2pdev, MSG_INFO,
			    P2P_EVENT_GROUP_STARTED
			    "%s %s ssid=\"%s\" freq=%d%s%s%s%s%s go_dev_addr="
			    MACSTR "%s%s",
			    wpa_s->ifname, go ? "GO" : "client", ssid_txt, freq,
			    psk ? " psk=" : "", psk_txt,
			    passphrase ? " passphrase=\"" : "",
			    passphrase ? passphrase : "",
			    passphrase ? "\"" : "",
			    MAC2STR(go_dev_addr),
			    persistent ? " [PERSISTENT]" : "", extra);
	wpa_printf(MSG_INFO, P2P_EVENT_GROUP_STARTED
		   "%s %s ssid=\"%s\" freq=%d go_dev_addr=" MACSTR "%s%s",
		   wpa_s->ifname, go ? "GO" : "client", ssid_txt, freq,
		   MAC2STR(go_dev_addr), persistent ? " [PERSISTENT]" : "",
		   extra);
}


static void wpas_group_formation_completed(struct wpa_supplicant *wpa_s,
					   int success, int already_deleted)
{
	struct wpa_ssid *ssid;
	int client;
	int persistent;
	u8 go_dev_addr[ETH_ALEN];

	/*
	 * This callback is likely called for the main interface. Update wpa_s
	 * to use the group interface if a new interface was created for the
	 * group.
	 */
	if (wpa_s->global->p2p_group_formation)
		wpa_s = wpa_s->global->p2p_group_formation;
	if (wpa_s->p2p_go_group_formation_completed) {
		wpa_s->global->p2p_group_formation = NULL;
		wpa_s->p2p_in_provisioning = 0;
	} else if (wpa_s->p2p_in_provisioning && !success) {
		wpa_msg(wpa_s, MSG_DEBUG,
			"P2P: Stop provisioning state due to failure");
		wpa_s->p2p_in_provisioning = 0;
	}
	wpa_s->p2p_in_invitation = 0;
	wpa_s->group_formation_reported = 1;

	if (!success) {
		wpa_msg_global(wpa_s->p2pdev, MSG_INFO,
			       P2P_EVENT_GROUP_FORMATION_FAILURE);
		wpas_notify_p2p_group_formation_failure(wpa_s, "");
		if (already_deleted)
			return;
		wpas_p2p_group_delete(wpa_s,
				      P2P_GROUP_REMOVAL_FORMATION_FAILED);
		return;
	}

	wpa_msg_global(wpa_s->p2pdev, MSG_INFO,
		       P2P_EVENT_GROUP_FORMATION_SUCCESS);

	ssid = wpa_s->current_ssid;
	if (ssid && ssid->mode == WPAS_MODE_P2P_GROUP_FORMATION) {
		ssid->mode = WPAS_MODE_P2P_GO;
		p2p_group_notif_formation_done(wpa_s->p2p_group);
		wpa_supplicant_ap_mac_addr_filter(wpa_s, NULL);
	}

	persistent = 0;
	if (ssid) {
		client = ssid->mode == WPAS_MODE_INFRA;
		if (ssid->mode == WPAS_MODE_P2P_GO) {
			persistent = ssid->p2p_persistent_group;
			os_memcpy(go_dev_addr, wpa_s->global->p2p_dev_addr,
				  ETH_ALEN);
		} else {
			os_memset(go_dev_addr, 0, ETH_ALEN);
			persistent = wpas_p2p_persistent_group(wpa_s,
							       go_dev_addr,
							       ssid->ssid,
							       ssid->ssid_len);
		}
	} else {
		client = wpa_s->p2p_group_interface ==
			P2P_GROUP_INTERFACE_CLIENT;
		os_memset(go_dev_addr, 0, ETH_ALEN);
	}

	wpa_s->show_group_started = 0;
	if (client) {
		/*
		 * Indicate event only after successfully completed 4-way
		 * handshake, i.e., when the interface is ready for data
		 * packets.
		 */
		wpa_s->show_group_started = 1;
	} else {
		wpas_p2p_group_started(wpa_s, 1, ssid,
				       ssid ? ssid->frequency : 0,
				       ssid && ssid->passphrase == NULL &&
				       ssid->psk_set ? ssid->psk : NULL,
				       ssid ? ssid->passphrase : NULL,
				       go_dev_addr, persistent, "");
		wpas_p2p_cross_connect_setup(wpa_s);
		wpas_p2p_set_group_idle_timeout(wpa_s);
	}

	if (persistent)
		wpas_p2p_store_persistent_group(wpa_s->p2pdev,
						ssid, go_dev_addr);
	else {
		os_free(wpa_s->global->add_psk);
		wpa_s->global->add_psk = NULL;
	}

	if (!client) {
		wpas_notify_p2p_group_started(wpa_s, ssid, persistent, 0, NULL);
		os_get_reltime(&wpa_s->global->p2p_go_wait_client);
	}
}


struct send_action_work {
	unsigned int freq;
	u8 dst[ETH_ALEN];
	u8 src[ETH_ALEN];
	u8 bssid[ETH_ALEN];
	size_t len;
	unsigned int wait_time;
	u8 buf[0];
};


static void wpas_p2p_free_send_action_work(struct wpa_supplicant *wpa_s)
{
	struct send_action_work *awork = wpa_s->p2p_send_action_work->ctx;

	wpa_printf(MSG_DEBUG,
		   "P2P: Free Action frame radio work @%p (freq=%u dst="
		   MACSTR " src=" MACSTR " bssid=" MACSTR " wait_time=%u)",
		   wpa_s->p2p_send_action_work, awork->freq,
		   MAC2STR(awork->dst), MAC2STR(awork->src),
		   MAC2STR(awork->bssid), awork->wait_time);
	wpa_hexdump(MSG_DEBUG, "P2P: Freeing pending Action frame",
		    awork->buf, awork->len);
	os_free(awork);
	wpa_s->p2p_send_action_work->ctx = NULL;
	radio_work_done(wpa_s->p2p_send_action_work);
	wpa_s->p2p_send_action_work = NULL;
}


static void wpas_p2p_send_action_work_timeout(void *eloop_ctx,
					      void *timeout_ctx)
{
	struct wpa_supplicant *wpa_s = eloop_ctx;

	if (!wpa_s->p2p_send_action_work)
		return;

	wpa_printf(MSG_DEBUG, "P2P: Send Action frame radio work timed out");
	wpas_p2p_free_send_action_work(wpa_s);
}


static void wpas_p2p_action_tx_clear(struct wpa_supplicant *wpa_s)
{
	if (wpa_s->p2p_send_action_work) {
		struct send_action_work *awork;

		awork = wpa_s->p2p_send_action_work->ctx;
		wpa_printf(MSG_DEBUG,
			   "P2P: Clear Action TX work @%p (wait_time=%u)",
			   wpa_s->p2p_send_action_work, awork->wait_time);
		if (awork->wait_time == 0) {
			wpas_p2p_free_send_action_work(wpa_s);
		} else {
			/*
			 * In theory, this should not be needed, but number of
			 * places in the P2P code is still using non-zero wait
			 * time for the last Action frame in the sequence and
			 * some of these do not call send_action_done().
			 */
			eloop_cancel_timeout(wpas_p2p_send_action_work_timeout,
					     wpa_s, NULL);
			eloop_register_timeout(
				0, awork->wait_time * 1000,
				wpas_p2p_send_action_work_timeout,
				wpa_s, NULL);
		}
	}
}


static void wpas_p2p_send_action_tx_status(struct wpa_supplicant *wpa_s,
					   unsigned int freq,
					   const u8 *dst, const u8 *src,
					   const u8 *bssid,
					   const u8 *data, size_t data_len,
					   enum offchannel_send_action_result
					   result)
{
	enum p2p_send_action_result res = P2P_SEND_ACTION_SUCCESS;

	wpas_p2p_action_tx_clear(wpa_s);

	if (wpa_s->global->p2p == NULL || wpa_s->global->p2p_disabled)
		return;

	switch (result) {
	case OFFCHANNEL_SEND_ACTION_SUCCESS:
		res = P2P_SEND_ACTION_SUCCESS;
		break;
	case OFFCHANNEL_SEND_ACTION_NO_ACK:
		res = P2P_SEND_ACTION_NO_ACK;
		break;
	case OFFCHANNEL_SEND_ACTION_FAILED:
		res = P2P_SEND_ACTION_FAILED;
		break;
	}

	p2p_send_action_cb(wpa_s->global->p2p, freq, dst, src, bssid, res);

	if (result != OFFCHANNEL_SEND_ACTION_SUCCESS &&
	    wpa_s->pending_pd_before_join &&
	    (os_memcmp(dst, wpa_s->pending_join_dev_addr, ETH_ALEN) == 0 ||
	     os_memcmp(dst, wpa_s->pending_join_iface_addr, ETH_ALEN) == 0) &&
	    wpa_s->p2p_fallback_to_go_neg) {
		wpa_s->pending_pd_before_join = 0;
		wpa_dbg(wpa_s, MSG_DEBUG, "P2P: No ACK for PD Req "
			"during p2p_connect-auto");
		wpa_msg_global(wpa_s->p2pdev, MSG_INFO,
			       P2P_EVENT_FALLBACK_TO_GO_NEG
			       "reason=no-ACK-to-PD-Req");
		wpas_p2p_fallback_to_go_neg(wpa_s, 0);
		return;
	}
}


static void wpas_send_action_cb(struct wpa_radio_work *work, int deinit)
{
	struct wpa_supplicant *wpa_s = work->wpa_s;
	struct send_action_work *awork = work->ctx;

	if (deinit) {
		if (work->started) {
			eloop_cancel_timeout(wpas_p2p_send_action_work_timeout,
					     wpa_s, NULL);
			wpa_s->p2p_send_action_work = NULL;
			offchannel_send_action_done(wpa_s);
		}
		os_free(awork);
		return;
	}

	if (offchannel_send_action(wpa_s, awork->freq, awork->dst, awork->src,
				   awork->bssid, awork->buf, awork->len,
				   awork->wait_time,
				   wpas_p2p_send_action_tx_status, 1) < 0) {
		os_free(awork);
		radio_work_done(work);
		return;
	}
	wpa_s->p2p_send_action_work = work;
}


static int wpas_send_action_work(struct wpa_supplicant *wpa_s,
				 unsigned int freq, const u8 *dst,
				 const u8 *src, const u8 *bssid, const u8 *buf,
				 size_t len, unsigned int wait_time)
{
	struct send_action_work *awork;

	if (radio_work_pending(wpa_s, "p2p-send-action")) {
		wpa_printf(MSG_DEBUG, "P2P: Cannot schedule new p2p-send-action work since one is already pending");
		return -1;
	}

	awork = os_zalloc(sizeof(*awork) + len);
	if (awork == NULL)
		return -1;

	awork->freq = freq;
	os_memcpy(awork->dst, dst, ETH_ALEN);
	os_memcpy(awork->src, src, ETH_ALEN);
	os_memcpy(awork->bssid, bssid, ETH_ALEN);
	awork->len = len;
	awork->wait_time = wait_time;
	os_memcpy(awork->buf, buf, len);

	if (radio_add_work(wpa_s, freq, "p2p-send-action", 1,
			   wpas_send_action_cb, awork) < 0) {
		os_free(awork);
		return -1;
	}

	return 0;
}


static int wpas_send_action(void *ctx, unsigned int freq, const u8 *dst,
			    const u8 *src, const u8 *bssid, const u8 *buf,
			    size_t len, unsigned int wait_time, int *scheduled)
{
	struct wpa_supplicant *wpa_s = ctx;
	int listen_freq = -1, send_freq = -1;

	if (scheduled)
		*scheduled = 0;
	if (wpa_s->p2p_listen_work)
		listen_freq = wpa_s->p2p_listen_work->freq;
	if (wpa_s->p2p_send_action_work)
		send_freq = wpa_s->p2p_send_action_work->freq;
	if (listen_freq != (int) freq && send_freq != (int) freq) {
		int res;

		wpa_printf(MSG_DEBUG, "P2P: Schedule new radio work for Action frame TX (listen_freq=%d send_freq=%d freq=%u)",
			   listen_freq, send_freq, freq);
		res = wpas_send_action_work(wpa_s, freq, dst, src, bssid, buf,
					    len, wait_time);
		if (res == 0 && scheduled)
			*scheduled = 1;
		return res;
	}

	wpa_printf(MSG_DEBUG, "P2P: Use ongoing radio work for Action frame TX");
	return offchannel_send_action(wpa_s, freq, dst, src, bssid, buf, len,
				      wait_time,
				      wpas_p2p_send_action_tx_status, 1);
}


static void wpas_send_action_done(void *ctx)
{
	struct wpa_supplicant *wpa_s = ctx;

	if (wpa_s->p2p_send_action_work) {
		eloop_cancel_timeout(wpas_p2p_send_action_work_timeout,
				     wpa_s, NULL);
		os_free(wpa_s->p2p_send_action_work->ctx);
		radio_work_done(wpa_s->p2p_send_action_work);
		wpa_s->p2p_send_action_work = NULL;
	}

	offchannel_send_action_done(wpa_s);
}


static int wpas_copy_go_neg_results(struct wpa_supplicant *wpa_s,
				    struct p2p_go_neg_results *params)
{
	if (wpa_s->go_params == NULL) {
		wpa_s->go_params = os_malloc(sizeof(*params));
		if (wpa_s->go_params == NULL)
			return -1;
	}
	os_memcpy(wpa_s->go_params, params, sizeof(*params));
	return 0;
}


static void wpas_start_wps_enrollee(struct wpa_supplicant *wpa_s,
				    struct p2p_go_neg_results *res)
{
	wpa_s->group_formation_reported = 0;
	wpa_printf(MSG_DEBUG, "P2P: Start WPS Enrollee for peer " MACSTR
		   " dev_addr " MACSTR " wps_method %d",
		   MAC2STR(res->peer_interface_addr),
		   MAC2STR(res->peer_device_addr), res->wps_method);
	wpa_hexdump_ascii(MSG_DEBUG, "P2P: Start WPS Enrollee for SSID",
			  res->ssid, res->ssid_len);
	wpa_supplicant_ap_deinit(wpa_s);
	wpas_copy_go_neg_results(wpa_s, res);
	if (res->wps_method == WPS_PBC) {
		wpas_wps_start_pbc(wpa_s, res->peer_interface_addr, 1, 0);
#ifdef CONFIG_WPS_NFC
	} else if (res->wps_method == WPS_NFC) {
		wpas_wps_start_nfc(wpa_s, res->peer_device_addr,
				   res->peer_interface_addr,
				   wpa_s->p2pdev->p2p_oob_dev_pw,
				   wpa_s->p2pdev->p2p_oob_dev_pw_id, 1,
				   wpa_s->p2pdev->p2p_oob_dev_pw_id ==
				   DEV_PW_NFC_CONNECTION_HANDOVER ?
				   wpa_s->p2pdev->p2p_peer_oob_pubkey_hash :
				   NULL,
				   NULL, 0, 0);
#endif /* CONFIG_WPS_NFC */
	} else {
		u16 dev_pw_id = DEV_PW_DEFAULT;
		if (wpa_s->p2p_wps_method == WPS_P2PS)
			dev_pw_id = DEV_PW_P2PS_DEFAULT;
		if (wpa_s->p2p_wps_method == WPS_PIN_KEYPAD)
			dev_pw_id = DEV_PW_REGISTRAR_SPECIFIED;
		wpas_wps_start_pin(wpa_s, res->peer_interface_addr,
				   wpa_s->p2p_pin, 1, dev_pw_id);
	}
}


static void wpas_p2p_add_psk_list(struct wpa_supplicant *wpa_s,
				  struct wpa_ssid *ssid)
{
	struct wpa_ssid *persistent;
	struct psk_list_entry *psk;
	struct hostapd_data *hapd;

	if (!wpa_s->ap_iface)
		return;

	persistent = wpas_p2p_get_persistent(wpa_s->p2pdev, NULL, ssid->ssid,
					     ssid->ssid_len);
	if (persistent == NULL)
		return;

	hapd = wpa_s->ap_iface->bss[0];

	dl_list_for_each(psk, &persistent->psk_list, struct psk_list_entry,
			 list) {
		struct hostapd_wpa_psk *hpsk;

		wpa_dbg(wpa_s, MSG_DEBUG, "P2P: Add persistent group PSK entry for "
			MACSTR " psk=%d",
			MAC2STR(psk->addr), psk->p2p);
		hpsk = os_zalloc(sizeof(*hpsk));
		if (hpsk == NULL)
			break;
		os_memcpy(hpsk->psk, psk->psk, PMK_LEN);
		if (psk->p2p)
			os_memcpy(hpsk->p2p_dev_addr, psk->addr, ETH_ALEN);
		else
			os_memcpy(hpsk->addr, psk->addr, ETH_ALEN);
		hpsk->next = hapd->conf->ssid.wpa_psk;
		hapd->conf->ssid.wpa_psk = hpsk;
	}
}


static void p2p_go_dump_common_freqs(struct wpa_supplicant *wpa_s)
{
	char buf[20 + P2P_MAX_CHANNELS * 6];
	char *pos, *end;
	unsigned int i;
	int res;

	pos = buf;
	end = pos + sizeof(buf);
	for (i = 0; i < wpa_s->p2p_group_common_freqs_num; i++) {
		res = os_snprintf(pos, end - pos, " %d",
				  wpa_s->p2p_group_common_freqs[i]);
		if (os_snprintf_error(end - pos, res))
			break;
		pos += res;
	}
	*pos = '\0';

	wpa_dbg(wpa_s, MSG_DEBUG, "P2P: Common group frequencies:%s", buf);
}


static void p2p_go_save_group_common_freqs(struct wpa_supplicant *wpa_s,
					   struct p2p_go_neg_results *params)
{
	unsigned int i, len = int_array_len(wpa_s->go_params->freq_list);

	wpa_s->p2p_group_common_freqs_num = 0;
	os_free(wpa_s->p2p_group_common_freqs);
	wpa_s->p2p_group_common_freqs = os_calloc(len, sizeof(int));
	if (!wpa_s->p2p_group_common_freqs)
		return;

	for (i = 0; i < len; i++) {
		if (!wpa_s->go_params->freq_list[i])
			break;
		wpa_s->p2p_group_common_freqs[i] =
			wpa_s->go_params->freq_list[i];
	}
	wpa_s->p2p_group_common_freqs_num = i;
}


static void p2p_config_write(struct wpa_supplicant *wpa_s)
{
#ifndef CONFIG_NO_CONFIG_WRITE
	if (wpa_s->p2pdev->conf->update_config &&
	    wpa_config_write(wpa_s->p2pdev->confname, wpa_s->p2pdev->conf))
		wpa_printf(MSG_DEBUG, "P2P: Failed to update configuration");
#endif /* CONFIG_NO_CONFIG_WRITE */
}


static void p2p_go_configured(void *ctx, void *data)
{
	struct wpa_supplicant *wpa_s = ctx;
	struct p2p_go_neg_results *params = data;
	struct wpa_ssid *ssid;

	wpa_s->ap_configured_cb = NULL;
	wpa_s->ap_configured_cb_ctx = NULL;
	wpa_s->ap_configured_cb_data = NULL;
	if (!wpa_s->go_params) {
		wpa_printf(MSG_ERROR,
			   "P2P: p2p_go_configured() called with wpa_s->go_params == NULL");
		return;
	}

	p2p_go_save_group_common_freqs(wpa_s, params);
	p2p_go_dump_common_freqs(wpa_s);

	ssid = wpa_s->current_ssid;
	if (ssid && ssid->mode == WPAS_MODE_P2P_GO) {
		wpa_printf(MSG_DEBUG, "P2P: Group setup without provisioning");
		if (wpa_s->global->p2p_group_formation == wpa_s)
			wpa_s->global->p2p_group_formation = NULL;
		wpas_p2p_group_started(wpa_s, 1, ssid, ssid->frequency,
				       params->passphrase[0] == '\0' ?
				       params->psk : NULL,
				       params->passphrase,
				       wpa_s->global->p2p_dev_addr,
				       params->persistent_group, "");
		wpa_s->group_formation_reported = 1;

		if (wpa_s->p2pdev->p2ps_method_config_any) {
			if (is_zero_ether_addr(wpa_s->p2pdev->p2ps_join_addr)) {
				wpa_dbg(wpa_s, MSG_DEBUG,
					"P2PS: Setting default PIN for ANY");
				wpa_supplicant_ap_wps_pin(wpa_s, NULL,
							  "12345670", NULL, 0,
							  0);
			} else {
				wpa_dbg(wpa_s, MSG_DEBUG,
					"P2PS: Setting default PIN for " MACSTR,
					MAC2STR(wpa_s->p2pdev->p2ps_join_addr));
				wpa_supplicant_ap_wps_pin(
					wpa_s, wpa_s->p2pdev->p2ps_join_addr,
					"12345670", NULL, 0, 0);
			}
			wpa_s->p2pdev->p2ps_method_config_any = 0;
		}

		os_get_reltime(&wpa_s->global->p2p_go_wait_client);
		if (params->persistent_group) {
			wpas_p2p_store_persistent_group(
				wpa_s->p2pdev, ssid,
				wpa_s->global->p2p_dev_addr);
			wpas_p2p_add_psk_list(wpa_s, ssid);
		}

		wpas_notify_p2p_group_started(wpa_s, ssid,
					      params->persistent_group, 0,
					      NULL);
		wpas_p2p_cross_connect_setup(wpa_s);
		wpas_p2p_set_group_idle_timeout(wpa_s);

		if (wpa_s->p2p_first_connection_timeout) {
			wpa_dbg(wpa_s, MSG_DEBUG,
				"P2P: Start group formation timeout of %d seconds until first data connection on GO",
				wpa_s->p2p_first_connection_timeout);
			wpa_s->p2p_go_group_formation_completed = 0;
			wpa_s->global->p2p_group_formation = wpa_s;
			eloop_cancel_timeout(wpas_p2p_group_formation_timeout,
					     wpa_s->p2pdev, NULL);
			eloop_register_timeout(
				wpa_s->p2p_first_connection_timeout, 0,
				wpas_p2p_group_formation_timeout,
				wpa_s->p2pdev, NULL);
		}

		return;
	}

	wpa_printf(MSG_DEBUG, "P2P: Setting up WPS for GO provisioning");
	if (wpa_supplicant_ap_mac_addr_filter(wpa_s,
					      params->peer_interface_addr)) {
		wpa_printf(MSG_DEBUG, "P2P: Failed to setup MAC address "
			   "filtering");
		return;
	}
	if (params->wps_method == WPS_PBC) {
		wpa_supplicant_ap_wps_pbc(wpa_s, params->peer_interface_addr,
					  params->peer_device_addr);
#ifdef CONFIG_WPS_NFC
	} else if (params->wps_method == WPS_NFC) {
		if (wpa_s->p2pdev->p2p_oob_dev_pw_id !=
		    DEV_PW_NFC_CONNECTION_HANDOVER &&
		    !wpa_s->p2pdev->p2p_oob_dev_pw) {
			wpa_printf(MSG_DEBUG, "P2P: No NFC Dev Pw known");
			return;
		}
		wpas_ap_wps_add_nfc_pw(
			wpa_s, wpa_s->p2pdev->p2p_oob_dev_pw_id,
			wpa_s->p2pdev->p2p_oob_dev_pw,
			wpa_s->p2pdev->p2p_peer_oob_pk_hash_known ?
			wpa_s->p2pdev->p2p_peer_oob_pubkey_hash : NULL);
#endif /* CONFIG_WPS_NFC */
	} else if (wpa_s->p2p_pin[0])
		wpa_supplicant_ap_wps_pin(wpa_s, params->peer_interface_addr,
					  wpa_s->p2p_pin, NULL, 0, 0);
	os_free(wpa_s->go_params);
	wpa_s->go_params = NULL;
}


/**
 * wpas_p2p_freq_to_edmg_channel - Convert frequency into EDMG channel
 * @freq: Frequency (MHz) to convert
 * @op_class: Buffer for returning operating class
 * @op_edmg_channel: Buffer for returning channel number
 * Returns: 0 on success, -1 on failure
 *
 * This can be used to find the highest channel bonding which includes the
 * specified frequency.
 */
static int wpas_p2p_freq_to_edmg_channel(struct wpa_supplicant *wpa_s,
					 unsigned int freq,
					 u8 *op_class, u8 *op_edmg_channel)
{
	struct hostapd_hw_modes *hwmode;
	struct ieee80211_edmg_config edmg;
	unsigned int i;
	enum chan_width chanwidth[] = {
		CHAN_WIDTH_8640,
		CHAN_WIDTH_6480,
		CHAN_WIDTH_4320,
	};

	if (!wpa_s->hw.modes)
		return -1;

	hwmode = get_mode(wpa_s->hw.modes, wpa_s->hw.num_modes,
			  HOSTAPD_MODE_IEEE80211AD, false);
	if (!hwmode) {
		wpa_printf(MSG_ERROR,
			   "Unsupported AP mode: HOSTAPD_MODE_IEEE80211AD");
		return -1;
	}

	/* Find the highest EDMG channel bandwidth to start the P2P GO */
	for (i = 0; i < ARRAY_SIZE(chanwidth); i++) {
		if (ieee80211_chaninfo_to_channel(freq, chanwidth[i], 0,
						  op_class,
						  op_edmg_channel) < 0)
			continue;

		hostapd_encode_edmg_chan(1, *op_edmg_channel, 0, &edmg);
		if (edmg.channels &&
		    ieee802_edmg_is_allowed(hwmode->edmg, edmg)) {
			wpa_printf(MSG_DEBUG,
				   "Freq %u to EDMG channel %u at opclass %u",
				   freq, *op_edmg_channel, *op_class);
			return 0;
		}
	}

	return -1;
}


int wpas_p2p_try_edmg_channel(struct wpa_supplicant *wpa_s,
			      struct p2p_go_neg_results *params)
{
	u8 op_channel, op_class;
	int freq;

	/* Try social channel as primary channel frequency */
	freq = (!params->freq) ? 58320 + 1 * 2160 : params->freq;

	if (wpas_p2p_freq_to_edmg_channel(wpa_s, freq, &op_class,
					  &op_channel) == 0) {
		wpa_printf(MSG_DEBUG,
			   "Freq %d will be used to set an EDMG connection (channel=%u opclass=%u)",
			   freq, op_channel, op_class);
		params->freq = freq;
		return 0;
	}

	return -1;
}


static void wpas_start_wps_go(struct wpa_supplicant *wpa_s,
			      struct p2p_go_neg_results *params,
			      int group_formation)
{
	struct wpa_ssid *ssid;

	wpa_dbg(wpa_s, MSG_DEBUG, "P2P: Starting GO");
	if (wpas_copy_go_neg_results(wpa_s, params) < 0) {
		wpa_dbg(wpa_s, MSG_DEBUG, "P2P: Could not copy GO Negotiation "
			"results");
		return;
	}

	ssid = wpa_config_add_network(wpa_s->conf);
	if (ssid == NULL) {
		wpa_dbg(wpa_s, MSG_DEBUG, "P2P: Could not add network for GO");
		return;
	}

	wpa_s->show_group_started = 0;
	wpa_s->p2p_go_group_formation_completed = 0;
	wpa_s->group_formation_reported = 0;
	os_memset(wpa_s->go_dev_addr, 0, ETH_ALEN);

	wpa_config_set_network_defaults(ssid);
	ssid->temporary = 1;
	ssid->p2p_group = 1;
	ssid->p2p_persistent_group = !!params->persistent_group;
	ssid->mode = group_formation ? WPAS_MODE_P2P_GROUP_FORMATION :
		WPAS_MODE_P2P_GO;
	ssid->frequency = params->freq;
	ssid->ht40 = params->ht40;
	ssid->vht = params->vht;
	ssid->max_oper_chwidth = params->max_oper_chwidth;
	ssid->vht_center_freq2 = params->vht_center_freq2;
	ssid->he = params->he;
	if (params->edmg) {
		u8 op_channel, op_class;

		if (!wpas_p2p_freq_to_edmg_channel(wpa_s, params->freq,
						   &op_class, &op_channel)) {
			ssid->edmg_channel = op_channel;
			ssid->enable_edmg = params->edmg;
		} else {
			wpa_dbg(wpa_s, MSG_DEBUG,
				"P2P: Could not match EDMG channel, freq %d, for GO",
				params->freq);
		}
	}

	ssid->ssid = os_zalloc(params->ssid_len + 1);
	if (ssid->ssid) {
		os_memcpy(ssid->ssid, params->ssid, params->ssid_len);
		ssid->ssid_len = params->ssid_len;
	}
	ssid->auth_alg = WPA_AUTH_ALG_OPEN;
	ssid->key_mgmt = WPA_KEY_MGMT_PSK;
	if (is_6ghz_freq(ssid->frequency) &&
	    is_p2p_6ghz_capable(wpa_s->global->p2p)) {
		ssid->auth_alg |= WPA_AUTH_ALG_SAE;
		ssid->key_mgmt = WPA_KEY_MGMT_SAE;
		ssid->ieee80211w = MGMT_FRAME_PROTECTION_REQUIRED;
		ssid->sae_pwe = 1;
		wpa_dbg(wpa_s, MSG_DEBUG, "P2P: Use SAE auth_alg and key_mgmt");
	} else {
		p2p_set_6ghz_dev_capab(wpa_s->global->p2p, false);
	}
	ssid->proto = WPA_PROTO_RSN;
	ssid->pairwise_cipher = WPA_CIPHER_CCMP;
	ssid->group_cipher = WPA_CIPHER_CCMP;
	if (params->freq > 56160) {
		/*
		 * Enable GCMP instead of CCMP as pairwise_cipher and
		 * group_cipher in 60 GHz.
		 */
		ssid->pairwise_cipher = WPA_CIPHER_GCMP;
		ssid->group_cipher = WPA_CIPHER_GCMP;
		/* P2P GO in 60 GHz is always a PCP (PBSS) */
		ssid->pbss = 1;
	}
	if (os_strlen(params->passphrase) > 0) {
		ssid->passphrase = os_strdup(params->passphrase);
		if (ssid->passphrase == NULL) {
			wpa_msg_global(wpa_s, MSG_ERROR,
				       "P2P: Failed to copy passphrase for GO");
			wpa_config_remove_network(wpa_s->conf, ssid->id);
			return;
		}
	} else
		ssid->passphrase = NULL;
	ssid->psk_set = params->psk_set;
	if (ssid->psk_set)
		os_memcpy(ssid->psk, params->psk, sizeof(ssid->psk));
	else if (ssid->passphrase)
		wpa_config_update_psk(ssid);
	ssid->ap_max_inactivity = wpa_s->p2pdev->conf->p2p_go_max_inactivity;

	wpa_s->ap_configured_cb = p2p_go_configured;
	wpa_s->ap_configured_cb_ctx = wpa_s;
	wpa_s->ap_configured_cb_data = wpa_s->go_params;
	wpa_s->scan_req = NORMAL_SCAN_REQ;
	wpa_s->connect_without_scan = ssid;
	wpa_s->reassociate = 1;
	wpa_s->disconnected = 0;
	wpa_dbg(wpa_s, MSG_DEBUG, "P2P: Request scan (that will be skipped) to "
		"start GO)");
	wpa_supplicant_req_scan(wpa_s, 0, 0);
}


static void wpas_p2p_clone_config(struct wpa_supplicant *dst,
				  const struct wpa_supplicant *src)
{
	struct wpa_config *d;
	const struct wpa_config *s;

	d = dst->conf;
	s = src->conf;

#define C(n)                            \
do {                                    \
	if (s->n && !d->n)              \
		d->n = os_strdup(s->n); \
} while (0)

	C(device_name);
	C(manufacturer);
	C(model_name);
	C(model_number);
	C(serial_number);
	C(config_methods);
#undef C

	os_memcpy(d->device_type, s->device_type, WPS_DEV_TYPE_LEN);
	os_memcpy(d->sec_device_type, s->sec_device_type,
		  sizeof(d->sec_device_type));
	d->num_sec_device_types = s->num_sec_device_types;

	d->p2p_group_idle = s->p2p_group_idle;
	d->p2p_go_freq_change_policy = s->p2p_go_freq_change_policy;
	d->p2p_intra_bss = s->p2p_intra_bss;
	d->persistent_reconnect = s->persistent_reconnect;
	d->max_num_sta = s->max_num_sta;
	d->pbc_in_m1 = s->pbc_in_m1;
	d->ignore_old_scan_res = s->ignore_old_scan_res;
	d->beacon_int = s->beacon_int;
	d->dtim_period = s->dtim_period;
	d->p2p_go_ctwindow = s->p2p_go_ctwindow;
	d->disassoc_low_ack = s->disassoc_low_ack;
	d->disable_scan_offload = s->disable_scan_offload;
	d->passive_scan = s->passive_scan;
	d->pmf = s->pmf;
	d->p2p_6ghz_disable = s->p2p_6ghz_disable;

	if (s->wps_nfc_dh_privkey && s->wps_nfc_dh_pubkey &&
	    !d->wps_nfc_pw_from_config) {
		wpabuf_free(d->wps_nfc_dh_privkey);
		wpabuf_free(d->wps_nfc_dh_pubkey);
		d->wps_nfc_dh_privkey = wpabuf_dup(s->wps_nfc_dh_privkey);
		d->wps_nfc_dh_pubkey = wpabuf_dup(s->wps_nfc_dh_pubkey);
	}
	d->p2p_cli_probe = s->p2p_cli_probe;
	d->go_interworking = s->go_interworking;
	d->go_access_network_type = s->go_access_network_type;
	d->go_internet = s->go_internet;
	d->go_venue_group = s->go_venue_group;
	d->go_venue_type = s->go_venue_type;
	d->p2p_add_cli_chan = s->p2p_add_cli_chan;
}


static void wpas_p2p_get_group_ifname(struct wpa_supplicant *wpa_s,
				      char *ifname, size_t len)
{
	char *ifname_ptr = wpa_s->ifname;

	if (os_strncmp(wpa_s->ifname, P2P_MGMT_DEVICE_PREFIX,
		       os_strlen(P2P_MGMT_DEVICE_PREFIX)) == 0) {
		ifname_ptr = os_strrchr(wpa_s->ifname, '-') + 1;
	}

	os_snprintf(ifname, len, "p2p-%s-%d", ifname_ptr, wpa_s->p2p_group_idx);
	if (os_strlen(ifname) >= IFNAMSIZ &&
	    os_strlen(wpa_s->ifname) < IFNAMSIZ) {
		int res;

		/* Try to avoid going over the IFNAMSIZ length limit */
		res = os_snprintf(ifname, len, "p2p-%d", wpa_s->p2p_group_idx);
		if (os_snprintf_error(len, res) && len)
			ifname[len - 1] = '\0';
	}
}


static int wpas_p2p_add_group_interface(struct wpa_supplicant *wpa_s,
					enum wpa_driver_if_type type)
{
	char ifname[120], force_ifname[120];

	if (wpa_s->pending_interface_name[0]) {
		wpa_printf(MSG_DEBUG, "P2P: Pending virtual interface exists "
			   "- skip creation of a new one");
		if (is_zero_ether_addr(wpa_s->pending_interface_addr)) {
			wpa_printf(MSG_DEBUG, "P2P: Pending virtual address "
				   "unknown?! ifname='%s'",
				   wpa_s->pending_interface_name);
			return -1;
		}
		return 0;
	}

	wpas_p2p_get_group_ifname(wpa_s, ifname, sizeof(ifname));
	force_ifname[0] = '\0';

	wpa_printf(MSG_DEBUG, "P2P: Create a new interface %s for the group",
		   ifname);
	wpa_s->p2p_group_idx++;

	wpa_s->pending_interface_type = type;
	if (wpa_drv_if_add(wpa_s, type, ifname, NULL, NULL, force_ifname,
			   wpa_s->pending_interface_addr, NULL) < 0) {
		wpa_printf(MSG_ERROR, "P2P: Failed to create new group "
			   "interface");
		return -1;
	}

	if (wpa_s->conf->p2p_interface_random_mac_addr) {
		random_mac_addr(wpa_s->pending_interface_addr);
		wpa_printf(MSG_DEBUG, "P2P: Generate random MAC address " MACSTR
			   " for the group",
			   MAC2STR(wpa_s->pending_interface_addr));
	}

	if (force_ifname[0]) {
		wpa_printf(MSG_DEBUG, "P2P: Driver forced interface name %s",
			   force_ifname);
		os_strlcpy(wpa_s->pending_interface_name, force_ifname,
			   sizeof(wpa_s->pending_interface_name));
	} else
		os_strlcpy(wpa_s->pending_interface_name, ifname,
			   sizeof(wpa_s->pending_interface_name));
	wpa_printf(MSG_DEBUG, "P2P: Created pending virtual interface %s addr "
		   MACSTR, wpa_s->pending_interface_name,
		   MAC2STR(wpa_s->pending_interface_addr));

	return 0;
}


static void wpas_p2p_remove_pending_group_interface(
	struct wpa_supplicant *wpa_s)
{
	if (!wpa_s->pending_interface_name[0] ||
	    is_zero_ether_addr(wpa_s->pending_interface_addr))
		return; /* No pending virtual interface */

	wpa_printf(MSG_DEBUG, "P2P: Removing pending group interface %s",
		   wpa_s->pending_interface_name);
	wpa_drv_if_remove(wpa_s, wpa_s->pending_interface_type,
			  wpa_s->pending_interface_name);
	os_memset(wpa_s->pending_interface_addr, 0, ETH_ALEN);
	wpa_s->pending_interface_name[0] = '\0';
	wpa_s->global->pending_group_iface_for_p2ps = 0;
}


static struct wpa_supplicant *
wpas_p2p_init_group_interface(struct wpa_supplicant *wpa_s, int go)
{
	struct wpa_interface iface;
	struct wpa_supplicant *group_wpa_s;

	if (!wpa_s->pending_interface_name[0]) {
		wpa_printf(MSG_ERROR, "P2P: No pending group interface");
		if (!wpas_p2p_create_iface(wpa_s))
			return NULL;
		/*
		 * Something has forced us to remove the pending interface; try
		 * to create a new one and hope for the best that we will get
		 * the same local address.
		 */
		if (wpas_p2p_add_group_interface(wpa_s, go ? WPA_IF_P2P_GO :
						 WPA_IF_P2P_CLIENT) < 0)
			return NULL;
	}

	os_memset(&iface, 0, sizeof(iface));
	iface.ifname = wpa_s->pending_interface_name;
	iface.driver = wpa_s->driver->name;
	if (wpa_s->conf->ctrl_interface == NULL &&
	    wpa_s->parent != wpa_s &&
	    wpa_s->p2p_mgmt &&
	    (wpa_s->drv_flags & WPA_DRIVER_FLAGS_DEDICATED_P2P_DEVICE))
		iface.ctrl_interface = wpa_s->parent->conf->ctrl_interface;
	else
		iface.ctrl_interface = wpa_s->conf->ctrl_interface;
	iface.driver_param = wpa_s->conf->driver_param;
	group_wpa_s = wpa_supplicant_add_iface(wpa_s->global, &iface, wpa_s);
	if (group_wpa_s == NULL) {
		wpa_printf(MSG_ERROR, "P2P: Failed to create new "
			   "wpa_supplicant interface");
		return NULL;
	}
	wpa_s->pending_interface_name[0] = '\0';
	group_wpa_s->p2p_group_interface = go ? P2P_GROUP_INTERFACE_GO :
		P2P_GROUP_INTERFACE_CLIENT;
	wpa_s->global->p2p_group_formation = group_wpa_s;
	wpa_s->global->pending_group_iface_for_p2ps = 0;

	wpas_p2p_clone_config(group_wpa_s, wpa_s);

	if (wpa_s->conf->p2p_interface_random_mac_addr) {
		if (wpa_drv_set_mac_addr(group_wpa_s,
					 wpa_s->pending_interface_addr) < 0) {
			wpa_msg(group_wpa_s, MSG_INFO,
				"Failed to set random MAC address");
			wpa_supplicant_remove_iface(wpa_s->global, group_wpa_s,
						    0);
			return NULL;
		}

		if (wpa_supplicant_update_mac_addr(group_wpa_s) < 0) {
			wpa_msg(group_wpa_s, MSG_INFO,
				"Could not update MAC address information");
			wpa_supplicant_remove_iface(wpa_s->global, group_wpa_s,
						    0);
			return NULL;
		}

		wpa_printf(MSG_DEBUG, "P2P: Using random MAC address " MACSTR
			   " for the group",
			   MAC2STR(wpa_s->pending_interface_addr));
	}

	return group_wpa_s;
}


static void wpas_p2p_group_formation_timeout(void *eloop_ctx,
					     void *timeout_ctx)
{
	struct wpa_supplicant *wpa_s = eloop_ctx;
	wpa_printf(MSG_DEBUG, "P2P: Group Formation timed out");
	wpas_p2p_group_formation_failed(wpa_s, 0);
}


static void wpas_p2p_group_formation_failed(struct wpa_supplicant *wpa_s,
					    int already_deleted)
{
	eloop_cancel_timeout(wpas_p2p_group_formation_timeout,
			     wpa_s->p2pdev, NULL);
	if (wpa_s->global->p2p)
		p2p_group_formation_failed(wpa_s->global->p2p);
	wpas_group_formation_completed(wpa_s, 0, already_deleted);
}


static void wpas_p2p_grpform_fail_after_wps(struct wpa_supplicant *wpa_s)
{
	wpa_printf(MSG_DEBUG, "P2P: Reject group formation due to WPS provisioning failure");
	eloop_cancel_timeout(wpas_p2p_group_formation_timeout,
			     wpa_s->p2pdev, NULL);
	eloop_register_timeout(0, 0, wpas_p2p_group_formation_timeout,
			       wpa_s->p2pdev, NULL);
	wpa_s->global->p2p_fail_on_wps_complete = 0;
}


void wpas_p2p_ap_setup_failed(struct wpa_supplicant *wpa_s)
{
	if (wpa_s->global->p2p_group_formation != wpa_s)
		return;
	/* Speed up group formation timeout since this cannot succeed */
	eloop_cancel_timeout(wpas_p2p_group_formation_timeout,
			     wpa_s->p2pdev, NULL);
	eloop_register_timeout(0, 0, wpas_p2p_group_formation_timeout,
			       wpa_s->p2pdev, NULL);
}


static void wpas_go_neg_completed(void *ctx, struct p2p_go_neg_results *res)
{
	struct wpa_supplicant *wpa_s = ctx;
	struct wpa_supplicant *group_wpa_s;

	if (wpa_s->off_channel_freq || wpa_s->roc_waiting_drv_freq) {
		wpa_drv_cancel_remain_on_channel(wpa_s);
		wpa_s->off_channel_freq = 0;
		wpa_s->roc_waiting_drv_freq = 0;
	}

	if (res->status) {
		wpa_msg_global(wpa_s, MSG_INFO,
			       P2P_EVENT_GO_NEG_FAILURE "status=%d",
			       res->status);
		wpas_notify_p2p_go_neg_completed(wpa_s, res);
		wpas_p2p_remove_pending_group_interface(wpa_s);
		return;
	}

	if (!res->role_go) {
		/* Inform driver of the operating channel of GO. */
		wpa_drv_set_prob_oper_freq(wpa_s, res->freq);
	}

	if (wpa_s->p2p_go_ht40)
		res->ht40 = 1;
	if (wpa_s->p2p_go_vht)
		res->vht = 1;
	if (wpa_s->p2p_go_he)
		res->he = 1;
	if (wpa_s->p2p_go_edmg)
		res->edmg = 1;
	res->max_oper_chwidth = wpa_s->p2p_go_max_oper_chwidth;
	res->vht_center_freq2 = wpa_s->p2p_go_vht_center_freq2;

	wpa_msg_global(wpa_s, MSG_INFO, P2P_EVENT_GO_NEG_SUCCESS "role=%s "
		       "freq=%d ht40=%d peer_dev=" MACSTR " peer_iface=" MACSTR
		       " wps_method=%s",
		       res->role_go ? "GO" : "client", res->freq, res->ht40,
		       MAC2STR(res->peer_device_addr),
		       MAC2STR(res->peer_interface_addr),
		       p2p_wps_method_text(res->wps_method));
	wpas_notify_p2p_go_neg_completed(wpa_s, res);

	if (res->role_go && wpa_s->p2p_persistent_id >= 0) {
		struct wpa_ssid *ssid;
		ssid = wpa_config_get_network(wpa_s->conf,
					      wpa_s->p2p_persistent_id);
		if (ssid && ssid->disabled == 2 &&
		    ssid->mode == WPAS_MODE_P2P_GO && ssid->passphrase) {
			size_t len = os_strlen(ssid->passphrase);
			wpa_printf(MSG_DEBUG, "P2P: Override passphrase based "
				   "on requested persistent group");
			os_memcpy(res->passphrase, ssid->passphrase, len);
			res->passphrase[len] = '\0';
		}
	}

	if (wpa_s->create_p2p_iface) {
		group_wpa_s =
			wpas_p2p_init_group_interface(wpa_s, res->role_go);
		if (group_wpa_s == NULL) {
			wpas_p2p_remove_pending_group_interface(wpa_s);
			eloop_cancel_timeout(wpas_p2p_long_listen_timeout,
					     wpa_s, NULL);
			wpas_p2p_group_formation_failed(wpa_s, 1);
			return;
		}
		os_memset(wpa_s->pending_interface_addr, 0, ETH_ALEN);
		wpa_s->pending_interface_name[0] = '\0';
	} else {
		group_wpa_s = wpa_s->parent;
		wpa_s->global->p2p_group_formation = group_wpa_s;
		if (group_wpa_s != wpa_s)
			wpas_p2p_clone_config(group_wpa_s, wpa_s);
	}

	group_wpa_s->p2p_in_provisioning = 1;
	group_wpa_s->p2pdev = wpa_s;
	if (group_wpa_s != wpa_s) {
		os_memcpy(group_wpa_s->p2p_pin, wpa_s->p2p_pin,
			  sizeof(group_wpa_s->p2p_pin));
		group_wpa_s->p2p_wps_method = wpa_s->p2p_wps_method;
	}
	if (res->role_go) {
		wpas_start_wps_go(group_wpa_s, res, 1);
	} else {
		os_get_reltime(&group_wpa_s->scan_min_time);
		wpas_start_wps_enrollee(group_wpa_s, res);
	}

	wpa_s->global->p2p_long_listen = 0;
	eloop_cancel_timeout(wpas_p2p_long_listen_timeout, wpa_s, NULL);

	eloop_cancel_timeout(wpas_p2p_group_formation_timeout, wpa_s, NULL);
	eloop_register_timeout(15 + res->peer_config_timeout / 100,
			       (res->peer_config_timeout % 100) * 10000,
			       wpas_p2p_group_formation_timeout, wpa_s, NULL);
}


static void wpas_go_neg_req_rx(void *ctx, const u8 *src, u16 dev_passwd_id,
			       u8 go_intent)
{
	struct wpa_supplicant *wpa_s = ctx;
	wpa_msg_global(wpa_s, MSG_INFO, P2P_EVENT_GO_NEG_REQUEST MACSTR
		       " dev_passwd_id=%u go_intent=%u", MAC2STR(src),
		       dev_passwd_id, go_intent);

	wpas_notify_p2p_go_neg_req(wpa_s, src, dev_passwd_id, go_intent);
}


static void wpas_dev_found(void *ctx, const u8 *addr,
			   const struct p2p_peer_info *info,
			   int new_device)
{
	u8 *wfd_dev_info = NULL;
	u8 wfd_dev_info_len = 0;
	u8 *wfd_r2_dev_info = NULL;
	u8 wfd_r2_dev_info_len = 0;
#ifndef CONFIG_NO_STDOUT_DEBUG
	struct wpa_supplicant *wpa_s = ctx;
	char devtype[WPS_DEV_TYPE_BUFSIZE];
	char *wfd_dev_info_hex = NULL;
	char *wfd_r2_dev_info_hex = NULL;

#ifdef CONFIG_WIFI_DISPLAY
	wfd_dev_info_hex = wifi_display_subelem_hex(info->wfd_subelems,
						    WFD_SUBELEM_DEVICE_INFO);
	if (wfd_dev_info_hex) {
		wfd_dev_info_len = strlen(wfd_dev_info_hex) / 2;
		wfd_dev_info = os_zalloc(wfd_dev_info_len);
		// Only used for notification, so not handling error.
		hexstr2bin(wfd_dev_info_hex, wfd_dev_info, wfd_dev_info_len);
	}

	wfd_r2_dev_info_hex = wifi_display_subelem_hex(info->wfd_subelems,
						    WFD_SUBELEM_R2_DEVICE_INFO);
	if (wfd_r2_dev_info_hex) {
		wfd_r2_dev_info_len = strlen(wfd_r2_dev_info_hex) / 2;
		wfd_r2_dev_info = os_zalloc(wfd_r2_dev_info_len);
		// Only used for notification, so not handling error.
		hexstr2bin(wfd_r2_dev_info_hex, wfd_r2_dev_info, wfd_r2_dev_info_len);
	}
#endif /* CONFIG_WIFI_DISPLAY */

	if (info->p2ps_instance) {
		char str[256];
		const u8 *buf = wpabuf_head(info->p2ps_instance);
		size_t len = wpabuf_len(info->p2ps_instance);

		while (len) {
			u32 id;
			u16 methods;
			u8 str_len;

			if (len < 4 + 2 + 1)
				break;
			id = WPA_GET_LE32(buf);
			buf += sizeof(u32);
			methods = WPA_GET_BE16(buf);
			buf += sizeof(u16);
			str_len = *buf++;
			if (str_len > len - 4 - 2 - 1)
				break;
			os_memcpy(str, buf, str_len);
			str[str_len] = '\0';
			buf += str_len;
			len -= str_len + sizeof(u32) + sizeof(u16) + sizeof(u8);

			wpa_msg_global(wpa_s, MSG_INFO,
				       P2P_EVENT_DEVICE_FOUND MACSTR
				       " p2p_dev_addr=" MACSTR
				       " pri_dev_type=%s name='%s'"
				       " config_methods=0x%x"
				       " dev_capab=0x%x"
				       " group_capab=0x%x"
				       " adv_id=%x asp_svc=%s%s",
				       MAC2STR(addr),
				       MAC2STR(info->p2p_device_addr),
				       wps_dev_type_bin2str(
					       info->pri_dev_type,
					       devtype, sizeof(devtype)),
				       info->device_name, methods,
				       info->dev_capab, info->group_capab,
				       id, str,
				       info->vendor_elems ?
				       " vendor_elems=1" : "");
		}
		goto done;
	}

	wpa_msg_global(wpa_s, MSG_INFO, P2P_EVENT_DEVICE_FOUND MACSTR
		       " p2p_dev_addr=" MACSTR
		       " pri_dev_type=%s name='%s' config_methods=0x%x "
		       "dev_capab=0x%x group_capab=0x%x%s%s%s%s%s new=%d",
		       MAC2STR(addr), MAC2STR(info->p2p_device_addr),
		       wps_dev_type_bin2str(info->pri_dev_type, devtype,
					    sizeof(devtype)),
		       info->device_name, info->config_methods,
		       info->dev_capab, info->group_capab,
		       wfd_dev_info_hex ? " wfd_dev_info=0x" : "",
		       wfd_dev_info_hex ? wfd_dev_info_hex : "",
		       wfd_r2_dev_info_hex ? " wfd_r2_dev_info=0x" : "",
		       wfd_r2_dev_info_hex ? wfd_r2_dev_info_hex : "",
		       info->vendor_elems ? " vendor_elems=1" : "",
		       new_device);

done:
	os_free(wfd_dev_info_hex);
	os_free(wfd_r2_dev_info_hex);
#endif /* CONFIG_NO_STDOUT_DEBUG */

	wpas_notify_p2p_device_found(ctx, addr, info, wfd_dev_info,
				     wfd_dev_info_len, wfd_r2_dev_info,
				     wfd_r2_dev_info_len, new_device);
	os_free(wfd_dev_info);
}


static void wpas_dev_lost(void *ctx, const u8 *dev_addr)
{
	struct wpa_supplicant *wpa_s = ctx;

	wpa_msg_global(wpa_s, MSG_INFO, P2P_EVENT_DEVICE_LOST
		       "p2p_dev_addr=" MACSTR, MAC2STR(dev_addr));

	wpas_notify_p2p_device_lost(wpa_s, dev_addr);
}


static void wpas_find_stopped(void *ctx)
{
	struct wpa_supplicant *wpa_s = ctx;

	if (wpa_s->p2p_scan_work && wpas_abort_ongoing_scan(wpa_s) < 0)
		wpa_printf(MSG_DEBUG, "P2P: Abort ongoing scan failed");

	wpa_msg_global(wpa_s, MSG_INFO, P2P_EVENT_FIND_STOPPED);
	wpas_notify_p2p_find_stopped(wpa_s);
}


struct wpas_p2p_listen_work {
	unsigned int freq;
	unsigned int duration;
	struct wpabuf *probe_resp_ie;
};


static void wpas_p2p_listen_work_free(struct wpas_p2p_listen_work *lwork)
{
	if (lwork == NULL)
		return;
	wpabuf_free(lwork->probe_resp_ie);
	os_free(lwork);
}


static void wpas_p2p_listen_work_done(struct wpa_supplicant *wpa_s)
{
	struct wpas_p2p_listen_work *lwork;

	if (!wpa_s->p2p_listen_work)
		return;

	lwork = wpa_s->p2p_listen_work->ctx;
	wpas_p2p_listen_work_free(lwork);
	radio_work_done(wpa_s->p2p_listen_work);
	wpa_s->p2p_listen_work = NULL;
}


static void wpas_start_listen_cb(struct wpa_radio_work *work, int deinit)
{
	struct wpa_supplicant *wpa_s = work->wpa_s;
	struct wpas_p2p_listen_work *lwork = work->ctx;
	unsigned int duration;

	if (deinit) {
		if (work->started) {
			wpa_s->p2p_listen_work = NULL;
			wpas_stop_listen(wpa_s);
		}
		wpas_p2p_listen_work_free(lwork);
		return;
	}

	wpa_s->p2p_listen_work = work;

	wpa_drv_set_ap_wps_ie(wpa_s, NULL, lwork->probe_resp_ie, NULL);

	if (wpa_drv_probe_req_report(wpa_s, 1) < 0) {
		wpa_printf(MSG_DEBUG, "P2P: Failed to request the driver to "
			   "report received Probe Request frames");
		wpas_p2p_listen_work_done(wpa_s);
		return;
	}

	wpa_s->pending_listen_freq = lwork->freq;
	wpa_s->pending_listen_duration = lwork->duration;

	duration = lwork->duration;
#ifdef CONFIG_TESTING_OPTIONS
	if (wpa_s->extra_roc_dur) {
		wpa_printf(MSG_DEBUG, "TESTING: Increase ROC duration %u -> %u",
			   duration, duration + wpa_s->extra_roc_dur);
		duration += wpa_s->extra_roc_dur;
	}
#endif /* CONFIG_TESTING_OPTIONS */

	if (wpa_drv_remain_on_channel(wpa_s, lwork->freq, duration) < 0) {
		wpa_printf(MSG_DEBUG, "P2P: Failed to request the driver "
			   "to remain on channel (%u MHz) for Listen "
			   "state", lwork->freq);
		wpas_p2p_listen_work_done(wpa_s);
		wpa_s->pending_listen_freq = 0;
		return;
	}
	wpa_s->off_channel_freq = 0;
	wpa_s->roc_waiting_drv_freq = lwork->freq;
}


static int wpas_start_listen(void *ctx, unsigned int freq,
			     unsigned int duration,
			     const struct wpabuf *probe_resp_ie)
{
	struct wpa_supplicant *wpa_s = ctx;
	struct wpas_p2p_listen_work *lwork;

	if (wpa_s->p2p_listen_work) {
		wpa_printf(MSG_DEBUG, "P2P: Reject start_listen since p2p_listen_work already exists");
		return -1;
	}

	lwork = os_zalloc(sizeof(*lwork));
	if (lwork == NULL)
		return -1;
	lwork->freq = freq;
	lwork->duration = duration;
	if (probe_resp_ie) {
		lwork->probe_resp_ie = wpabuf_dup(probe_resp_ie);
		if (lwork->probe_resp_ie == NULL) {
			wpas_p2p_listen_work_free(lwork);
			return -1;
		}
	}

	if (radio_add_work(wpa_s, freq, "p2p-listen", 0, wpas_start_listen_cb,
			   lwork) < 0) {
		wpas_p2p_listen_work_free(lwork);
		return -1;
	}

	return 0;
}


static void wpas_stop_listen(void *ctx)
{
	struct wpa_supplicant *wpa_s = ctx;
	if (wpa_s->off_channel_freq || wpa_s->roc_waiting_drv_freq) {
		wpa_drv_cancel_remain_on_channel(wpa_s);
		wpa_s->off_channel_freq = 0;
		wpa_s->roc_waiting_drv_freq = 0;
	}
	wpa_drv_set_ap_wps_ie(wpa_s, NULL, NULL, NULL);

	/*
	 * Don't cancel Probe Request RX reporting for a connected P2P Client
	 * handling Probe Request frames.
	 */
	if (!wpa_s->p2p_cli_probe)
		wpa_drv_probe_req_report(wpa_s, 0);

	wpas_p2p_listen_work_done(wpa_s);
}


static int wpas_send_probe_resp(void *ctx, const struct wpabuf *buf,
				unsigned int freq)
{
	struct wpa_supplicant *wpa_s = ctx;
	return wpa_drv_send_mlme(wpa_s, wpabuf_head(buf), wpabuf_len(buf), 1,
				 freq, 0);
}


static void wpas_prov_disc_local_display(struct wpa_supplicant *wpa_s,
					 const u8 *peer, const char *params,
					 unsigned int generated_pin)
{
	wpa_msg_global(wpa_s, MSG_INFO, P2P_EVENT_PROV_DISC_SHOW_PIN MACSTR
		       " %08d%s", MAC2STR(peer), generated_pin, params);
}


static void wpas_prov_disc_local_keypad(struct wpa_supplicant *wpa_s,
					const u8 *peer, const char *params)
{
	wpa_msg_global(wpa_s, MSG_INFO, P2P_EVENT_PROV_DISC_ENTER_PIN MACSTR
		       "%s", MAC2STR(peer), params);
}


static void wpas_prov_disc_req(void *ctx, const u8 *peer, u16 config_methods,
			       const u8 *dev_addr, const u8 *pri_dev_type,
			       const char *dev_name, u16 supp_config_methods,
			       u8 dev_capab, u8 group_capab, const u8 *group_id,
			       size_t group_id_len)
{
	struct wpa_supplicant *wpa_s = ctx;
	char devtype[WPS_DEV_TYPE_BUFSIZE];
	char params[300];
	u8 empty_dev_type[8];
	unsigned int generated_pin = 0;
	struct wpa_supplicant *group = NULL;
	int res;

	if (group_id) {
		for (group = wpa_s->global->ifaces; group; group = group->next)
		{
			struct wpa_ssid *s = group->current_ssid;
			if (s != NULL &&
			    s->mode == WPAS_MODE_P2P_GO &&
			    group_id_len - ETH_ALEN == s->ssid_len &&
			    os_memcmp(group_id + ETH_ALEN, s->ssid,
				      s->ssid_len) == 0)
				break;
		}
	}

	if (pri_dev_type == NULL) {
		os_memset(empty_dev_type, 0, sizeof(empty_dev_type));
		pri_dev_type = empty_dev_type;
	}
	res = os_snprintf(params, sizeof(params), " p2p_dev_addr=" MACSTR
			  " pri_dev_type=%s name='%s' config_methods=0x%x "
			  "dev_capab=0x%x group_capab=0x%x%s%s",
			  MAC2STR(dev_addr),
			  wps_dev_type_bin2str(pri_dev_type, devtype,
					       sizeof(devtype)),
			  dev_name, supp_config_methods, dev_capab, group_capab,
			  group ? " group=" : "",
			  group ? group->ifname : "");
	if (os_snprintf_error(sizeof(params), res))
		wpa_printf(MSG_DEBUG, "P2P: PD Request event truncated");
	params[sizeof(params) - 1] = '\0';

	if (config_methods & WPS_CONFIG_DISPLAY) {
		if (wps_generate_pin(&generated_pin) < 0) {
			wpa_printf(MSG_DEBUG, "P2P: Could not generate PIN");
			wpas_notify_p2p_provision_discovery(
				wpa_s, peer, 0 /* response */,
				P2P_PROV_DISC_INFO_UNAVAILABLE, 0, 0);
			return;
		}
		wpas_prov_disc_local_display(wpa_s, peer, params,
					     generated_pin);
	} else if (config_methods & WPS_CONFIG_KEYPAD)
		wpas_prov_disc_local_keypad(wpa_s, peer, params);
	else if (config_methods & WPS_CONFIG_PUSHBUTTON)
		wpa_msg_global(wpa_s, MSG_INFO, P2P_EVENT_PROV_DISC_PBC_REQ
			       MACSTR "%s", MAC2STR(peer), params);

	wpas_notify_p2p_provision_discovery(wpa_s, peer, 1 /* request */,
					    P2P_PROV_DISC_SUCCESS,
					    config_methods, generated_pin);
}


static void wpas_prov_disc_resp(void *ctx, const u8 *peer, u16 config_methods)
{
	struct wpa_supplicant *wpa_s = ctx;
	unsigned int generated_pin = 0;
	char params[20];

	if (wpa_s->pending_pd_before_join &&
	    (os_memcmp(peer, wpa_s->pending_join_dev_addr, ETH_ALEN) == 0 ||
	     os_memcmp(peer, wpa_s->pending_join_iface_addr, ETH_ALEN) == 0)) {
		wpa_s->pending_pd_before_join = 0;
		wpa_printf(MSG_DEBUG, "P2P: Starting pending "
			   "join-existing-group operation");
		wpas_p2p_join_start(wpa_s, 0, NULL, 0);
		return;
	}

	if (wpa_s->pending_pd_use == AUTO_PD_JOIN ||
	    wpa_s->pending_pd_use == AUTO_PD_GO_NEG) {
		int res;

		res = os_snprintf(params, sizeof(params), " peer_go=%d",
				  wpa_s->pending_pd_use == AUTO_PD_JOIN);
		if (os_snprintf_error(sizeof(params), res))
			params[sizeof(params) - 1] = '\0';
	} else
		params[0] = '\0';

	if (config_methods & WPS_CONFIG_DISPLAY)
		wpas_prov_disc_local_keypad(wpa_s, peer, params);
	else if (config_methods & WPS_CONFIG_KEYPAD) {
		if (wps_generate_pin(&generated_pin) < 0) {
			wpa_printf(MSG_DEBUG, "P2P: Could not generate PIN");
			wpas_notify_p2p_provision_discovery(
				wpa_s, peer, 0 /* response */,
				P2P_PROV_DISC_INFO_UNAVAILABLE, 0, 0);
			return;
		}
		wpas_prov_disc_local_display(wpa_s, peer, params,
					     generated_pin);
	} else if (config_methods & WPS_CONFIG_PUSHBUTTON)
		wpa_msg_global(wpa_s, MSG_INFO, P2P_EVENT_PROV_DISC_PBC_RESP
			       MACSTR "%s", MAC2STR(peer), params);

	wpas_notify_p2p_provision_discovery(wpa_s, peer, 0 /* response */,
					    P2P_PROV_DISC_SUCCESS,
					    config_methods, generated_pin);
}


static void wpas_prov_disc_fail(void *ctx, const u8 *peer,
				enum p2p_prov_disc_status status,
				u32 adv_id, const u8 *adv_mac,
				const char *deferred_session_resp)
{
	struct wpa_supplicant *wpa_s = ctx;

	if (wpa_s->p2p_fallback_to_go_neg) {
		wpa_dbg(wpa_s, MSG_DEBUG, "P2P: PD for p2p_connect-auto "
			"failed - fall back to GO Negotiation");
		wpa_msg_global(wpa_s->p2pdev, MSG_INFO,
			       P2P_EVENT_FALLBACK_TO_GO_NEG
			       "reason=PD-failed");
		wpas_p2p_fallback_to_go_neg(wpa_s, 0);
		return;
	}

	if (status == P2P_PROV_DISC_TIMEOUT_JOIN) {
		wpa_s->pending_pd_before_join = 0;
		wpa_printf(MSG_DEBUG, "P2P: Starting pending "
			   "join-existing-group operation (no ACK for PD "
			   "Req attempts)");
		wpas_p2p_join_start(wpa_s, 0, NULL, 0);
		return;
	}

	if (adv_id && adv_mac && deferred_session_resp) {
		wpa_msg_global(wpa_s, MSG_INFO, P2P_EVENT_PROV_DISC_FAILURE
			       " p2p_dev_addr=" MACSTR " status=%d adv_id=%x"
			       " deferred_session_resp='%s'",
			       MAC2STR(peer), status, adv_id,
			       deferred_session_resp);
	} else if (adv_id && adv_mac) {
		wpa_msg_global(wpa_s, MSG_INFO, P2P_EVENT_PROV_DISC_FAILURE
			       " p2p_dev_addr=" MACSTR " status=%d adv_id=%x",
			       MAC2STR(peer), status, adv_id);
	} else {
		wpa_msg_global(wpa_s, MSG_INFO, P2P_EVENT_PROV_DISC_FAILURE
			       " p2p_dev_addr=" MACSTR " status=%d",
			       MAC2STR(peer), status);
	}

	wpas_notify_p2p_provision_discovery(wpa_s, peer, 0 /* response */,
					    status, 0, 0);
}


static int freq_included(struct wpa_supplicant *wpa_s,
			 const struct p2p_channels *channels,
			 unsigned int freq)
{
	if ((channels == NULL || p2p_channels_includes_freq(channels, freq)) &&
	    wpas_p2p_go_is_peer_freq(wpa_s, freq))
		return 1;
	return 0;
}


static void wpas_p2p_go_update_common_freqs(struct wpa_supplicant *wpa_s)
{
	unsigned int num = P2P_MAX_CHANNELS;
	int *common_freqs;
	int ret;

	p2p_go_dump_common_freqs(wpa_s);
	common_freqs = os_calloc(num, sizeof(int));
	if (!common_freqs)
		return;

	ret = p2p_group_get_common_freqs(wpa_s->p2p_group, common_freqs, &num);
	if (ret < 0) {
		wpa_dbg(wpa_s, MSG_DEBUG,
			"P2P: Failed to get group common freqs");
		os_free(common_freqs);
		return;
	}

	os_free(wpa_s->p2p_group_common_freqs);
	wpa_s->p2p_group_common_freqs = common_freqs;
	wpa_s->p2p_group_common_freqs_num = num;
	p2p_go_dump_common_freqs(wpa_s);
}


/*
 * Check if the given frequency is one of the possible operating frequencies
 * set after the completion of the GO Negotiation.
 */
static int wpas_p2p_go_is_peer_freq(struct wpa_supplicant *wpa_s, int freq)
{
	unsigned int i;

	p2p_go_dump_common_freqs(wpa_s);

	/* assume no restrictions */
	if (!wpa_s->p2p_group_common_freqs_num)
		return 1;

	for (i = 0; i < wpa_s->p2p_group_common_freqs_num; i++) {
		if (wpa_s->p2p_group_common_freqs[i] == freq)
			return 1;
	}
	return 0;
}


static int wpas_sta_check_ecsa(struct hostapd_data *hapd,
			       struct sta_info *sta, void *ctx)
{
	int *ecsa_support = ctx;

	*ecsa_support &= sta->ecsa_supported;

	return 0;
}


/* Check if all the peers support eCSA */
static int wpas_p2p_go_clients_support_ecsa(struct wpa_supplicant *wpa_s)
{
	int ecsa_support = 1;

	ap_for_each_sta(wpa_s->ap_iface->bss[0], wpas_sta_check_ecsa,
			&ecsa_support);

	return ecsa_support;
}


/**
 * Pick the best frequency to use from all the currently used frequencies.
 */
static int wpas_p2p_pick_best_used_freq(struct wpa_supplicant *wpa_s,
					struct wpa_used_freq_data *freqs,
					unsigned int num)
{
	unsigned int i, c;

	/* find a candidate freq that is supported by P2P */
	for (c = 0; c < num; c++)
		if (p2p_supported_freq(wpa_s->global->p2p, freqs[c].freq))
			break;

	if (c == num)
		return 0;

	/* once we have a candidate, try to find a 'better' one */
	for (i = c + 1; i < num; i++) {
		if (!p2p_supported_freq(wpa_s->global->p2p, freqs[i].freq))
			continue;

		/*
		 * 1. Infrastructure station interfaces have higher preference.
		 * 2. P2P Clients have higher preference.
		 * 3. All others.
		 */
		if (freqs[i].flags & WPA_FREQ_USED_BY_INFRA_STATION) {
			c = i;
			break;
		}

		if ((freqs[i].flags & WPA_FREQ_USED_BY_P2P_CLIENT))
			c = i;
	}
	return freqs[c].freq;
}


static u8 wpas_invitation_process(void *ctx, const u8 *sa, const u8 *bssid,
				  const u8 *go_dev_addr, const u8 *ssid,
				  size_t ssid_len, int *go, u8 *group_bssid,
				  int *force_freq, int persistent_group,
				  const struct p2p_channels *channels,
				  int dev_pw_id)
{
	struct wpa_supplicant *wpa_s = ctx;
	struct wpa_ssid *s;
	struct wpa_used_freq_data *freqs;
	struct wpa_supplicant *grp;
	int best_freq;

	if (!persistent_group) {
		wpa_printf(MSG_DEBUG, "P2P: Invitation from " MACSTR
			   " to join an active group (SSID: %s)",
			   MAC2STR(sa), wpa_ssid_txt(ssid, ssid_len));
		if (!is_zero_ether_addr(wpa_s->p2p_auth_invite) &&
		    (os_memcmp(go_dev_addr, wpa_s->p2p_auth_invite, ETH_ALEN)
		     == 0 ||
		     os_memcmp(sa, wpa_s->p2p_auth_invite, ETH_ALEN) == 0)) {
			wpa_printf(MSG_DEBUG, "P2P: Accept previously "
				   "authorized invitation");
			goto accept_inv;
		}

#ifdef CONFIG_WPS_NFC
		if (dev_pw_id >= 0 && wpa_s->p2p_nfc_tag_enabled &&
		    dev_pw_id == wpa_s->p2p_oob_dev_pw_id) {
			wpa_printf(MSG_DEBUG, "P2P: Accept invitation based on local enabled NFC Tag");
			wpa_s->p2p_wps_method = WPS_NFC;
			wpa_s->pending_join_wps_method = WPS_NFC;
			os_memcpy(wpa_s->pending_join_dev_addr,
				  go_dev_addr, ETH_ALEN);
			os_memcpy(wpa_s->pending_join_iface_addr,
				  bssid, ETH_ALEN);
			goto accept_inv;
		}
#endif /* CONFIG_WPS_NFC */

		/*
		 * Do not accept the invitation automatically; notify user and
		 * request approval.
		 */
		return P2P_SC_FAIL_INFO_CURRENTLY_UNAVAILABLE;
	}

	grp = wpas_get_p2p_group(wpa_s, ssid, ssid_len, go);
	if (grp) {
		wpa_printf(MSG_DEBUG, "P2P: Accept invitation to already "
			   "running persistent group");
		if (*go)
			os_memcpy(group_bssid, grp->own_addr, ETH_ALEN);
		goto accept_inv;
	}

	if (!is_zero_ether_addr(wpa_s->p2p_auth_invite) &&
	    os_memcmp(sa, wpa_s->p2p_auth_invite, ETH_ALEN) == 0) {
		wpa_printf(MSG_DEBUG, "P2P: Accept previously initiated "
			   "invitation to re-invoke a persistent group");
		os_memset(wpa_s->p2p_auth_invite, 0, ETH_ALEN);
	} else if (!wpa_s->conf->persistent_reconnect)
		return P2P_SC_FAIL_INFO_CURRENTLY_UNAVAILABLE;

	for (s = wpa_s->conf->ssid; s; s = s->next) {
		if (s->disabled == 2 &&
		    os_memcmp(s->bssid, go_dev_addr, ETH_ALEN) == 0 &&
		    s->ssid_len == ssid_len &&
		    os_memcmp(ssid, s->ssid, ssid_len) == 0)
			break;
	}

	if (!s) {
		wpa_printf(MSG_DEBUG, "P2P: Invitation from " MACSTR
			   " requested reinvocation of an unknown group",
			   MAC2STR(sa));
		return P2P_SC_FAIL_UNKNOWN_GROUP;
	}

	if (s->mode == WPAS_MODE_P2P_GO && !wpas_p2p_create_iface(wpa_s)) {
		*go = 1;
		if (wpa_s->wpa_state >= WPA_AUTHENTICATING) {
			wpa_printf(MSG_DEBUG, "P2P: The only available "
				   "interface is already in use - reject "
				   "invitation");
			return P2P_SC_FAIL_UNABLE_TO_ACCOMMODATE;
		}
		if (wpa_s->p2p_mgmt)
			os_memcpy(group_bssid, wpa_s->parent->own_addr,
				  ETH_ALEN);
		else
			os_memcpy(group_bssid, wpa_s->own_addr, ETH_ALEN);
	} else if (s->mode == WPAS_MODE_P2P_GO) {
		*go = 1;
		if (wpas_p2p_add_group_interface(wpa_s, WPA_IF_P2P_GO) < 0)
		{
			wpa_printf(MSG_ERROR, "P2P: Failed to allocate a new "
				   "interface address for the group");
			return P2P_SC_FAIL_UNABLE_TO_ACCOMMODATE;
		}
		os_memcpy(group_bssid, wpa_s->pending_interface_addr,
			  ETH_ALEN);
	}

accept_inv:
	wpas_p2p_set_own_freq_preference(wpa_s, 0);

	best_freq = 0;
	freqs = os_calloc(wpa_s->num_multichan_concurrent,
			  sizeof(struct wpa_used_freq_data));
	if (freqs) {
		int num_channels = wpa_s->num_multichan_concurrent;
		int num = wpas_p2p_valid_oper_freqs(wpa_s, freqs, num_channels);
		best_freq = wpas_p2p_pick_best_used_freq(wpa_s, freqs, num);
		os_free(freqs);
	}

	/* Get one of the frequencies currently in use */
	if (best_freq > 0) {
		wpa_printf(MSG_DEBUG, "P2P: Trying to prefer a channel already used by one of the interfaces");
		wpas_p2p_set_own_freq_preference(wpa_s, best_freq);

		if (wpa_s->num_multichan_concurrent < 2 ||
		    wpas_p2p_num_unused_channels(wpa_s) < 1) {
			wpa_printf(MSG_DEBUG, "P2P: No extra channels available - trying to force channel to match a channel already used by one of the interfaces");
			*force_freq = best_freq;
		}
	}

	if (*force_freq > 0 && wpa_s->num_multichan_concurrent > 1 &&
	    wpas_p2p_num_unused_channels(wpa_s) > 0) {
		if (*go == 0) {
			/* We are the client */
			wpa_printf(MSG_DEBUG, "P2P: Peer was found to be "
				   "running a GO but we are capable of MCC, "
				   "figure out the best channel to use");
			*force_freq = 0;
		} else if (!freq_included(wpa_s, channels, *force_freq)) {
			/* We are the GO, and *force_freq is not in the
			 * intersection */
			wpa_printf(MSG_DEBUG, "P2P: Forced GO freq %d MHz not "
				   "in intersection but we are capable of MCC, "
				   "figure out the best channel to use",
				   *force_freq);
			*force_freq = 0;
		}
	}

	return P2P_SC_SUCCESS;
}


static void wpas_invitation_received(void *ctx, const u8 *sa, const u8 *bssid,
				     const u8 *ssid, size_t ssid_len,
				     const u8 *go_dev_addr, u8 status,
				     int op_freq)
{
	struct wpa_supplicant *wpa_s = ctx;
	struct wpa_ssid *s;

	for (s = wpa_s->conf->ssid; s; s = s->next) {
		if (s->disabled == 2 &&
		    s->ssid_len == ssid_len &&
		    os_memcmp(ssid, s->ssid, ssid_len) == 0)
			break;
	}

	if (status == P2P_SC_SUCCESS) {
		wpa_printf(MSG_DEBUG, "P2P: Invitation from peer " MACSTR
			   " was accepted; op_freq=%d MHz, SSID=%s",
			   MAC2STR(sa), op_freq, wpa_ssid_txt(ssid, ssid_len));
		if (s) {
			int go = s->mode == WPAS_MODE_P2P_GO;
			if (go) {
				wpa_msg_global(wpa_s, MSG_INFO,
					       P2P_EVENT_INVITATION_ACCEPTED
					       "sa=" MACSTR
					       " persistent=%d freq=%d",
					       MAC2STR(sa), s->id, op_freq);
			} else {
				wpa_msg_global(wpa_s, MSG_INFO,
					       P2P_EVENT_INVITATION_ACCEPTED
					       "sa=" MACSTR
					       " persistent=%d",
					       MAC2STR(sa), s->id);
			}
			wpas_p2p_group_add_persistent(
				wpa_s, s, go, 0, op_freq, 0,
				wpa_s->conf->p2p_go_ht40,
				wpa_s->conf->p2p_go_vht,
				0,
				wpa_s->conf->p2p_go_he,
				wpa_s->conf->p2p_go_edmg, NULL,
				go ? P2P_MAX_INITIAL_CONN_WAIT_GO_REINVOKE : 0,
				1, is_p2p_allow_6ghz(wpa_s->global->p2p));
		} else if (bssid) {
			wpa_s->user_initiated_pd = 0;
			wpa_msg_global(wpa_s, MSG_INFO,
				       P2P_EVENT_INVITATION_ACCEPTED
				       "sa=" MACSTR " go_dev_addr=" MACSTR
				       " bssid=" MACSTR " unknown-network",
				       MAC2STR(sa), MAC2STR(go_dev_addr),
				       MAC2STR(bssid));
			wpas_p2p_join(wpa_s, bssid, go_dev_addr,
				      wpa_s->p2p_wps_method, 0, op_freq,
				      ssid, ssid_len);
		}
		return;
	}

	if (status != P2P_SC_FAIL_INFO_CURRENTLY_UNAVAILABLE) {
		wpa_printf(MSG_DEBUG, "P2P: Invitation from peer " MACSTR
			   " was rejected (status %u)", MAC2STR(sa), status);
		return;
	}

	if (!s) {
		if (bssid) {
			wpa_msg_global(wpa_s, MSG_INFO,
				       P2P_EVENT_INVITATION_RECEIVED
				       "sa=" MACSTR " go_dev_addr=" MACSTR
				       " bssid=" MACSTR " unknown-network",
				       MAC2STR(sa), MAC2STR(go_dev_addr),
				       MAC2STR(bssid));
		} else {
			wpa_msg_global(wpa_s, MSG_INFO,
				       P2P_EVENT_INVITATION_RECEIVED
				       "sa=" MACSTR " go_dev_addr=" MACSTR
				       " unknown-network",
				       MAC2STR(sa), MAC2STR(go_dev_addr));
		}
		wpas_notify_p2p_invitation_received(wpa_s, sa, go_dev_addr,
						    bssid, 0, op_freq);
		return;
	}

	if (s->mode == WPAS_MODE_P2P_GO && op_freq) {
		wpa_msg_global(wpa_s, MSG_INFO, P2P_EVENT_INVITATION_RECEIVED
			       "sa=" MACSTR " persistent=%d freq=%d",
			       MAC2STR(sa), s->id, op_freq);
	} else {
		wpa_msg_global(wpa_s, MSG_INFO, P2P_EVENT_INVITATION_RECEIVED
			       "sa=" MACSTR " persistent=%d",
			       MAC2STR(sa), s->id);
	}
	wpas_notify_p2p_invitation_received(wpa_s, sa, go_dev_addr, bssid,
					    s->id, op_freq);
}


static void wpas_remove_persistent_peer(struct wpa_supplicant *wpa_s,
					struct wpa_ssid *ssid,
					const u8 *peer, int inv)
{
	size_t i;
	struct wpa_supplicant *p2p_wpa_s = wpa_s->global->p2p_init_wpa_s;

	if (ssid == NULL)
		return;

	for (i = 0; ssid->p2p_client_list && i < ssid->num_p2p_clients; i++) {
		if (os_memcmp(ssid->p2p_client_list + i * 2 * ETH_ALEN, peer,
			      ETH_ALEN) == 0)
			break;
	}
	if (i >= ssid->num_p2p_clients || !ssid->p2p_client_list) {
		if (ssid->mode != WPAS_MODE_P2P_GO &&
		    os_memcmp(ssid->bssid, peer, ETH_ALEN) == 0) {
			wpa_printf(MSG_DEBUG, "P2P: Remove persistent group %d "
				   "due to invitation result", ssid->id);
			wpas_notify_network_removed(wpa_s, ssid);
			wpa_config_remove_network(wpa_s->conf, ssid->id);
			return;
		}
		return; /* Peer not found in client list */
	}

	wpa_printf(MSG_DEBUG, "P2P: Remove peer " MACSTR " from persistent "
		   "group %d client list%s",
		   MAC2STR(peer), ssid->id,
		   inv ? " due to invitation result" : "");
	os_memmove(ssid->p2p_client_list + i * 2 * ETH_ALEN,
		   ssid->p2p_client_list + (i + 1) * 2 * ETH_ALEN,
		   (ssid->num_p2p_clients - i - 1) * 2 * ETH_ALEN);
	ssid->num_p2p_clients--;
	if (p2p_wpa_s->conf->update_config &&
	    wpa_config_write(p2p_wpa_s->confname, p2p_wpa_s->conf))
		wpa_printf(MSG_DEBUG, "P2P: Failed to update configuration");
}


static void wpas_remove_persistent_client(struct wpa_supplicant *wpa_s,
					  const u8 *peer)
{
	struct wpa_ssid *ssid;

	wpa_s = wpa_s->global->p2p_invite_group;
	if (wpa_s == NULL)
		return; /* No known invitation group */
	ssid = wpa_s->current_ssid;
	if (ssid == NULL || ssid->mode != WPAS_MODE_P2P_GO ||
	    !ssid->p2p_persistent_group)
		return; /* Not operating as a GO in persistent group */
	ssid = wpas_p2p_get_persistent(wpa_s->p2pdev, peer,
				       ssid->ssid, ssid->ssid_len);
	wpas_remove_persistent_peer(wpa_s, ssid, peer, 1);
}


static void wpas_invitation_result(void *ctx, int status, const u8 *bssid,
				   const struct p2p_channels *channels,
				   const u8 *peer, int neg_freq,
				   int peer_oper_freq)
{
	struct wpa_supplicant *wpa_s = ctx;
	struct wpa_ssid *ssid;
	int freq;

	if (bssid) {
		wpa_msg_global(wpa_s, MSG_INFO, P2P_EVENT_INVITATION_RESULT
			       "status=%d " MACSTR,
			       status, MAC2STR(bssid));
	} else {
		wpa_msg_global(wpa_s, MSG_INFO, P2P_EVENT_INVITATION_RESULT
			       "status=%d ", status);
	}
	wpas_notify_p2p_invitation_result(wpa_s, status, bssid);

	wpa_printf(MSG_DEBUG, "P2P: Invitation result - status=%d peer=" MACSTR,
		   status, MAC2STR(peer));
	if (wpa_s->pending_invite_ssid_id == -1) {
		struct wpa_supplicant *group_if =
			wpa_s->global->p2p_invite_group;

		if (status == P2P_SC_FAIL_UNKNOWN_GROUP)
			wpas_remove_persistent_client(wpa_s, peer);

		/*
		 * Invitation to an active group. If this is successful and we
		 * are the GO, set the client wait to postpone some concurrent
		 * operations and to allow provisioning and connection to happen
		 * more quickly.
		 */
		if (status == P2P_SC_SUCCESS &&
		    group_if && group_if->current_ssid &&
		    group_if->current_ssid->mode == WPAS_MODE_P2P_GO) {
			os_get_reltime(&wpa_s->global->p2p_go_wait_client);
#ifdef CONFIG_TESTING_OPTIONS
			if (group_if->p2p_go_csa_on_inv) {
				wpa_printf(MSG_DEBUG,
					   "Testing: force P2P GO CSA after invitation");
				eloop_cancel_timeout(
					wpas_p2p_reconsider_moving_go,
					wpa_s, NULL);
				eloop_register_timeout(
					0, 50000,
					wpas_p2p_reconsider_moving_go,
					wpa_s, NULL);
			}
#endif /* CONFIG_TESTING_OPTIONS */
		}
		return;
	}

	if (status == P2P_SC_FAIL_INFO_CURRENTLY_UNAVAILABLE) {
		wpa_printf(MSG_DEBUG, "P2P: Waiting for peer to start another "
			   "invitation exchange to indicate readiness for "
			   "re-invocation");
	}

	if (status != P2P_SC_SUCCESS) {
		if (status == P2P_SC_FAIL_UNKNOWN_GROUP) {
			ssid = wpa_config_get_network(
				wpa_s->conf, wpa_s->pending_invite_ssid_id);
			wpas_remove_persistent_peer(wpa_s, ssid, peer, 1);
		}
		wpas_p2p_remove_pending_group_interface(wpa_s);
		return;
	}

	ssid = wpa_config_get_network(wpa_s->conf,
				      wpa_s->pending_invite_ssid_id);
	if (ssid == NULL) {
		wpa_printf(MSG_ERROR, "P2P: Could not find persistent group "
			   "data matching with invitation");
		return;
	}

	/*
	 * The peer could have missed our ctrl::ack frame for Invitation
	 * Response and continue retransmitting the frame. To reduce the
	 * likelihood of the peer not getting successful TX status for the
	 * Invitation Response frame, wait a short time here before starting
	 * the persistent group so that we will remain on the current channel to
	 * acknowledge any possible retransmission from the peer.
	 */
	wpa_dbg(wpa_s, MSG_DEBUG, "P2P: 50 ms wait on current channel before "
		"starting persistent group");
	os_sleep(0, 50000);

	if (neg_freq > 0 && ssid->mode == WPAS_MODE_P2P_GO &&
	    freq_included(wpa_s, channels, neg_freq))
		freq = neg_freq;
	else if (peer_oper_freq > 0 && ssid->mode != WPAS_MODE_P2P_GO &&
		 freq_included(wpa_s, channels, peer_oper_freq))
		freq = peer_oper_freq;
	else
		freq = 0;

	wpa_printf(MSG_DEBUG, "P2P: Persistent group invitation success - op_freq=%d MHz SSID=%s",
		   freq, wpa_ssid_txt(ssid->ssid, ssid->ssid_len));
	wpas_p2p_group_add_persistent(wpa_s, ssid,
				      ssid->mode == WPAS_MODE_P2P_GO,
				      wpa_s->p2p_persistent_go_freq,
				      freq,
				      wpa_s->p2p_go_vht_center_freq2,
				      wpa_s->p2p_go_ht40, wpa_s->p2p_go_vht,
				      wpa_s->p2p_go_max_oper_chwidth,
				      wpa_s->p2p_go_he,
				      wpa_s->p2p_go_edmg,
				      channels,
				      ssid->mode == WPAS_MODE_P2P_GO ?
				      P2P_MAX_INITIAL_CONN_WAIT_GO_REINVOKE :
				      0, 1,
				      is_p2p_allow_6ghz(wpa_s->global->p2p));
}


static int wpas_p2p_disallowed_freq(struct wpa_global *global,
				    unsigned int freq)
{
	if (freq_range_list_includes(&global->p2p_go_avoid_freq, freq))
		return 1;
	return freq_range_list_includes(&global->p2p_disallow_freq, freq);
}


static void wpas_p2p_add_chan(struct p2p_reg_class *reg, u8 chan)
{
	reg->channel[reg->channels] = chan;
	reg->channels++;
}


static int wpas_p2p_default_channels(struct wpa_supplicant *wpa_s,
				     struct p2p_channels *chan,
				     struct p2p_channels *cli_chan)
{
	int i, cla = 0;

	wpa_s->global->p2p_24ghz_social_channels = 1;

	os_memset(cli_chan, 0, sizeof(*cli_chan));

	wpa_printf(MSG_DEBUG, "P2P: Enable operating classes for 2.4 GHz "
		   "band");

	/* Operating class 81 - 2.4 GHz band channels 1..13 */
	chan->reg_class[cla].reg_class = 81;
	chan->reg_class[cla].channels = 0;
	for (i = 0; i < 11; i++) {
		if (!wpas_p2p_disallowed_freq(wpa_s->global, 2412 + i * 5))
			wpas_p2p_add_chan(&chan->reg_class[cla], i + 1);
	}
	if (chan->reg_class[cla].channels)
		cla++;

	wpa_printf(MSG_DEBUG, "P2P: Enable operating classes for lower 5 GHz "
		   "band");

	/* Operating class 115 - 5 GHz, channels 36-48 */
	chan->reg_class[cla].reg_class = 115;
	chan->reg_class[cla].channels = 0;
	if (!wpas_p2p_disallowed_freq(wpa_s->global, 5000 + 36 * 5))
		wpas_p2p_add_chan(&chan->reg_class[cla], 36);
	if (!wpas_p2p_disallowed_freq(wpa_s->global, 5000 + 40 * 5))
		wpas_p2p_add_chan(&chan->reg_class[cla], 40);
	if (!wpas_p2p_disallowed_freq(wpa_s->global, 5000 + 44 * 5))
		wpas_p2p_add_chan(&chan->reg_class[cla], 44);
	if (!wpas_p2p_disallowed_freq(wpa_s->global, 5000 + 48 * 5))
		wpas_p2p_add_chan(&chan->reg_class[cla], 48);
	if (chan->reg_class[cla].channels)
		cla++;

	wpa_printf(MSG_DEBUG, "P2P: Enable operating classes for higher 5 GHz "
		   "band");

	/* Operating class 124 - 5 GHz, channels 149,153,157,161 */
	chan->reg_class[cla].reg_class = 124;
	chan->reg_class[cla].channels = 0;
	if (!wpas_p2p_disallowed_freq(wpa_s->global, 5000 + 149 * 5))
		wpas_p2p_add_chan(&chan->reg_class[cla], 149);
	if (!wpas_p2p_disallowed_freq(wpa_s->global, 5000 + 153 * 5))
		wpas_p2p_add_chan(&chan->reg_class[cla], 153);
	if (!wpas_p2p_disallowed_freq(wpa_s->global, 5000 + 156 * 5))
		wpas_p2p_add_chan(&chan->reg_class[cla], 157);
	if (!wpas_p2p_disallowed_freq(wpa_s->global, 5000 + 161 * 5))
		wpas_p2p_add_chan(&chan->reg_class[cla], 161);
	if (chan->reg_class[cla].channels)
		cla++;

	chan->reg_classes = cla;
	return 0;
}


static enum chan_allowed has_channel(struct wpa_global *global,
				     struct hostapd_hw_modes *mode, u8 op_class,
				     u8 chan, int *flags)
{
	int i;
	unsigned int freq;

	freq = ieee80211_chan_to_freq(NULL, op_class, chan);
	if (wpas_p2p_disallowed_freq(global, freq))
		return NOT_ALLOWED;

	for (i = 0; i < mode->num_channels; i++) {
		if ((unsigned int) mode->channels[i].freq == freq) {
			if (flags)
				*flags = mode->channels[i].flag;
			if (mode->channels[i].flag & HOSTAPD_CHAN_DISABLED)
				return NOT_ALLOWED;
			if (mode->channels[i].flag & HOSTAPD_CHAN_NO_IR)
				return NO_IR;
			if (mode->channels[i].flag & HOSTAPD_CHAN_RADAR)
				return RADAR;
			return ALLOWED;
		}
	}

	return NOT_ALLOWED;
}


static int wpas_p2p_get_center_80mhz(struct wpa_supplicant *wpa_s,
				     struct hostapd_hw_modes *mode,
				     u8 channel, const u8 *center_channels,
				     size_t num_chan)
{
	size_t i;

	if (mode->mode != HOSTAPD_MODE_IEEE80211A)
		return 0;

	for (i = 0; i < num_chan; i++)
		/*
		 * In 80 MHz, the bandwidth "spans" 12 channels (e.g., 36-48),
		 * so the center channel is 6 channels away from the start/end.
		 */
		if (channel >= center_channels[i] - 6 &&
		    channel <= center_channels[i] + 6)
			return center_channels[i];

	return 0;
}


static const u8 center_channels_5ghz_80mhz[] = { 42, 58, 106, 122, 138,
						 155, 171 };
static const u8 center_channels_6ghz_80mhz[] = { 7, 23, 39, 55, 71, 87, 103,
						 119, 135, 151, 167, 183, 199,
						 215 };

static enum chan_allowed wpas_p2p_verify_80mhz(struct wpa_supplicant *wpa_s,
					       struct hostapd_hw_modes *mode,
					       u8 op_class, u8 channel, u8 bw)
{
	u8 center_chan;
	int i, flags;
	enum chan_allowed res, ret = ALLOWED;
	const u8 *chans;
	size_t num_chans;
	bool is_6ghz = is_6ghz_op_class(op_class);

	if (is_6ghz) {
		chans = center_channels_6ghz_80mhz;
		num_chans = ARRAY_SIZE(center_channels_6ghz_80mhz);
	} else {
		chans = center_channels_5ghz_80mhz;
		num_chans = ARRAY_SIZE(center_channels_5ghz_80mhz);
	}
	center_chan = wpas_p2p_get_center_80mhz(wpa_s, mode, channel,
						chans, num_chans);
	if (!center_chan)
		return NOT_ALLOWED;
	if (!wpa_s->p2p_go_allow_dfs &&
	    !is_6ghz && center_chan >= 58 && center_chan <= 138)
		return NOT_ALLOWED; /* Do not allow DFS channels for P2P */

	/* check all the channels are available */
	for (i = 0; i < 4; i++) {
		int adj_chan = center_chan - 6 + i * 4;

		res = has_channel(wpa_s->global, mode, op_class, adj_chan,
				  &flags);
		if (res == NOT_ALLOWED)
			return NOT_ALLOWED;
		if (res == RADAR)
			ret = RADAR;
		if (res == NO_IR)
			ret = NO_IR;
		if (!is_6ghz) {
			if (i == 0 && !(flags & HOSTAPD_CHAN_VHT_10_70))
				return NOT_ALLOWED;
			if (i == 1 && !(flags & HOSTAPD_CHAN_VHT_30_50))
				return NOT_ALLOWED;
			if (i == 2 && !(flags & HOSTAPD_CHAN_VHT_50_30))
				return NOT_ALLOWED;
			if (i == 3 && !(flags & HOSTAPD_CHAN_VHT_70_10))
				return NOT_ALLOWED;
		} else if (is_6ghz &&
			   (!(wpas_get_6ghz_he_chwidth_capab(mode) &
			      HE_PHYCAP_CHANNEL_WIDTH_SET_40MHZ_80MHZ_IN_5G))) {
			return NOT_ALLOWED;
		}
	}

	return ret;
}


static int wpas_p2p_get_center_160mhz(struct wpa_supplicant *wpa_s,
				     struct hostapd_hw_modes *mode,
				     u8 channel, const u8 *center_channels,
				     size_t num_chan)
{
	unsigned int i;

	if (mode->mode != HOSTAPD_MODE_IEEE80211A)
		return 0;

	for (i = 0; i < num_chan; i++)
		/*
		 * In 160 MHz, the bandwidth "spans" 28 channels (e.g., 36-64),
		 * so the center channel is 14 channels away from the start/end.
		 */
		if (channel >= center_channels[i] - 14 &&
		    channel <= center_channels[i] + 14)
			return center_channels[i];

	return 0;
}


static const u8 center_channels_5ghz_160mhz[] = { 50, 114, 163 };
static const u8 center_channels_6ghz_160mhz[] = { 15, 47, 79, 111, 143, 175,
						  207 };

static enum chan_allowed wpas_p2p_verify_160mhz(struct wpa_supplicant *wpa_s,
					       struct hostapd_hw_modes *mode,
					       u8 op_class, u8 channel, u8 bw)
{
	u8 center_chan;
	int i, flags;
	enum chan_allowed res, ret = ALLOWED;
	const u8 *chans;
	size_t num_chans;

	if (is_6ghz_op_class(op_class)) {
		chans = center_channels_6ghz_160mhz;
		num_chans = ARRAY_SIZE(center_channels_6ghz_160mhz);
	} else {
		chans = center_channels_5ghz_160mhz;
		num_chans = ARRAY_SIZE(center_channels_5ghz_160mhz);
	}
	center_chan = wpas_p2p_get_center_160mhz(wpa_s, mode, channel,
						 chans, num_chans);
	if (!center_chan)
		return NOT_ALLOWED;
	/* VHT 160 MHz uses DFS channels in most countries. */

	/* Check all the channels are available */
	for (i = 0; i < 8; i++) {
		int adj_chan = center_chan - 14 + i * 4;

		res = has_channel(wpa_s->global, mode, op_class, adj_chan,
				  &flags);
		if (res == NOT_ALLOWED)
			return NOT_ALLOWED;

		if (res == RADAR)
			ret = RADAR;
		if (res == NO_IR)
			ret = NO_IR;

		if (!is_6ghz_op_class(op_class)) {
			if (i == 0 && !(flags & HOSTAPD_CHAN_VHT_10_150))
				return NOT_ALLOWED;
			if (i == 1 && !(flags & HOSTAPD_CHAN_VHT_30_130))
				return NOT_ALLOWED;
			if (i == 2 && !(flags & HOSTAPD_CHAN_VHT_50_110))
				return NOT_ALLOWED;
			if (i == 3 && !(flags & HOSTAPD_CHAN_VHT_70_90))
				return NOT_ALLOWED;
			if (i == 4 && !(flags & HOSTAPD_CHAN_VHT_90_70))
				return NOT_ALLOWED;
			if (i == 5 && !(flags & HOSTAPD_CHAN_VHT_110_50))
				return NOT_ALLOWED;
			if (i == 6 && !(flags & HOSTAPD_CHAN_VHT_130_30))
				return NOT_ALLOWED;
			if (i == 7 && !(flags & HOSTAPD_CHAN_VHT_150_10))
				return NOT_ALLOWED;
		} else if (is_6ghz_op_class(op_class) &&
			   (!(wpas_get_6ghz_he_chwidth_capab(mode) &
			      HE_PHYCAP_CHANNEL_WIDTH_SET_160MHZ_IN_5G))) {
			return NOT_ALLOWED;
		}
	}

	return ret;
}


static enum chan_allowed wpas_p2p_verify_edmg(struct wpa_supplicant *wpa_s,
					      struct hostapd_hw_modes *mode,
					      u8 channel)
{
	struct ieee80211_edmg_config edmg;

	hostapd_encode_edmg_chan(1, channel, 0, &edmg);
	if (edmg.channels && ieee802_edmg_is_allowed(mode->edmg, edmg))
		return ALLOWED;

	return NOT_ALLOWED;
}


static enum chan_allowed wpas_p2p_verify_channel(struct wpa_supplicant *wpa_s,
						 struct hostapd_hw_modes *mode,
						 u8 op_class, u8 channel, u8 bw)
{
	int flag = 0;
	enum chan_allowed res, res2;

	res2 = res = has_channel(wpa_s->global, mode, op_class, channel, &flag);
	if (bw == BW40MINUS) {
		if (!(flag & HOSTAPD_CHAN_HT40MINUS))
			return NOT_ALLOWED;
		res2 = has_channel(wpa_s->global, mode, op_class, channel - 4,
				   NULL);
	} else if (bw == BW40PLUS) {
		if (!(flag & HOSTAPD_CHAN_HT40PLUS))
			return NOT_ALLOWED;
		res2 = has_channel(wpa_s->global, mode, op_class, channel + 4,
				   NULL);
	} else if (is_6ghz_op_class(op_class) && bw == BW40) {
		if (mode->mode != HOSTAPD_MODE_IEEE80211A)
			return NOT_ALLOWED;
		if (get_6ghz_sec_channel(channel) < 0)
			res2 = has_channel(wpa_s->global, mode, op_class,
					   channel - 4, NULL);
		else
			res2 = has_channel(wpa_s->global, mode, op_class,
					   channel + 4, NULL);
	} else if (bw == BW80) {
		res2 = wpas_p2p_verify_80mhz(wpa_s, mode, op_class, channel,
					     bw);
	} else if (bw == BW160) {
		res2 = wpas_p2p_verify_160mhz(wpa_s, mode, op_class, channel,
					      bw);
	} else if (bw == BW4320 || bw == BW6480 || bw == BW8640) {
		return wpas_p2p_verify_edmg(wpa_s, mode, channel);
	}

	if (res == NOT_ALLOWED || res2 == NOT_ALLOWED)
		return NOT_ALLOWED;
	if (res == NO_IR || res2 == NO_IR)
		return NO_IR;
	if (res == RADAR || res2 == RADAR)
		return RADAR;
	return res;
}


static int wpas_p2p_setup_channels(struct wpa_supplicant *wpa_s,
				   struct p2p_channels *chan,
				   struct p2p_channels *cli_chan,
				   bool p2p_disable_6ghz)
{
	struct hostapd_hw_modes *mode;
	int cla, op, cli_cla;

	if (wpa_s->hw.modes == NULL) {
		wpa_printf(MSG_DEBUG, "P2P: Driver did not support fetching "
			   "of all supported channels; assume dualband "
			   "support");
		return wpas_p2p_default_channels(wpa_s, chan, cli_chan);
	}

	cla = cli_cla = 0;

	for (op = 0; global_op_class[op].op_class; op++) {
		const struct oper_class_map *o = &global_op_class[op];
		unsigned int ch;
		struct p2p_reg_class *reg = NULL, *cli_reg = NULL;

		if (o->p2p == NO_P2P_SUPP ||
		    (is_6ghz_op_class(o->op_class) && p2p_disable_6ghz))
			continue;

		mode = get_mode(wpa_s->hw.modes, wpa_s->hw.num_modes, o->mode,
				is_6ghz_op_class(o->op_class));
		if (mode == NULL)
			continue;
		if (mode->mode == HOSTAPD_MODE_IEEE80211G)
			wpa_s->global->p2p_24ghz_social_channels = 1;
		for (ch = o->min_chan; ch <= o->max_chan; ch += o->inc) {
			enum chan_allowed res;

			/* Check for non-continuous jump in channel index
			 * incrementation */
			if ((o->op_class >= 128 && o->op_class <= 130) &&
			    ch < 149 && ch + o->inc > 149)
				ch = 149;

			res = wpas_p2p_verify_channel(wpa_s, mode, o->op_class,
						      ch, o->bw);
			if (res == ALLOWED) {
				if (reg == NULL) {
					if (cla == P2P_MAX_REG_CLASSES)
						continue;
					wpa_printf(MSG_DEBUG, "P2P: Add operating class %u",
						   o->op_class);
					reg = &chan->reg_class[cla];
					cla++;
					reg->reg_class = o->op_class;
				}
				if (reg->channels == P2P_MAX_REG_CLASS_CHANNELS)
					continue;
				reg->channel[reg->channels] = ch;
				reg->channels++;
			} else if (res == NO_IR &&
				   wpa_s->conf->p2p_add_cli_chan) {
				if (cli_reg == NULL) {
					if (cli_cla == P2P_MAX_REG_CLASSES)
						continue;
					wpa_printf(MSG_DEBUG, "P2P: Add operating class %u (client only)",
						   o->op_class);
					cli_reg = &cli_chan->reg_class[cli_cla];
					cli_cla++;
					cli_reg->reg_class = o->op_class;
				}
				if (cli_reg->channels ==
				    P2P_MAX_REG_CLASS_CHANNELS)
					continue;
				cli_reg->channel[cli_reg->channels] = ch;
				cli_reg->channels++;
			}
		}
		if (reg) {
			wpa_hexdump(MSG_DEBUG, "P2P: Channels",
				    reg->channel, reg->channels);
		}
		if (cli_reg) {
			wpa_hexdump(MSG_DEBUG, "P2P: Channels (client only)",
				    cli_reg->channel, cli_reg->channels);
		}
	}

	chan->reg_classes = cla;
	cli_chan->reg_classes = cli_cla;

	return 0;
}


int wpas_p2p_get_sec_channel_offset_40mhz(struct wpa_supplicant *wpa_s,
					  struct hostapd_hw_modes *mode,
					  u8 channel)
{
	int op;
	enum chan_allowed ret;

	for (op = 0; global_op_class[op].op_class; op++) {
		const struct oper_class_map *o = &global_op_class[op];
		u16 ch;
		int chan = channel;

		/* Allow DFS channels marked as NO_P2P_SUPP to be used with
		 * driver offloaded DFS. */
		if ((o->p2p == NO_P2P_SUPP &&
		     (!is_dfs_global_op_class(o->op_class) ||
		      !wpa_s->p2p_go_allow_dfs)) ||
		    (is_6ghz_op_class(o->op_class) &&
		     wpa_s->conf->p2p_6ghz_disable))
			continue;

		if (is_6ghz_op_class(o->op_class) && o->bw == BW40 &&
		    get_6ghz_sec_channel(channel) < 0)
			chan = channel - 4;

		for (ch = o->min_chan; ch <= o->max_chan; ch += o->inc) {
			if (o->mode != HOSTAPD_MODE_IEEE80211A ||
			    (o->bw != BW40PLUS && o->bw != BW40MINUS &&
			     o->bw != BW40) ||
			    ch != chan)
				continue;
			ret = wpas_p2p_verify_channel(wpa_s, mode, o->op_class,
						      ch, o->bw);
			if (ret == ALLOWED) {
				if (is_6ghz_op_class(o->op_class) &&
				    o->bw == BW40)
					return get_6ghz_sec_channel(channel);
				return (o->bw == BW40MINUS) ? -1 : 1;
			}
			if (ret == RADAR && wpa_s->p2p_go_allow_dfs) {
				/* Allow RADAR channels used for driver
				 * offloaded DFS */
				return (o->bw == BW40MINUS) ? -1 : 1;
			}
		}
	}
	return 0;
}


int wpas_p2p_get_vht80_center(struct wpa_supplicant *wpa_s,
			      struct hostapd_hw_modes *mode, u8 channel,
			      u8 op_class)
{
	const u8 *chans;
	size_t num_chans;
	enum chan_allowed ret;

	ret = wpas_p2p_verify_channel(wpa_s, mode, op_class, channel, BW80);
	if (!(ret == ALLOWED || (ret == RADAR && wpa_s->p2p_go_allow_dfs)))
		return 0;

	if (is_6ghz_op_class(op_class)) {
		chans = center_channels_6ghz_80mhz;
		num_chans = ARRAY_SIZE(center_channels_6ghz_80mhz);
	} else {
		chans = center_channels_5ghz_80mhz;
		num_chans = ARRAY_SIZE(center_channels_5ghz_80mhz);
	}
	return wpas_p2p_get_center_80mhz(wpa_s, mode, channel,
					 chans, num_chans);
}


int wpas_p2p_get_vht160_center(struct wpa_supplicant *wpa_s,
			       struct hostapd_hw_modes *mode, u8 channel,
			       u8 op_class)
{
	const u8 *chans;
	size_t num_chans;
	enum chan_allowed ret;

	ret = wpas_p2p_verify_channel(wpa_s, mode, op_class, channel, BW160);
	if (!(ret == ALLOWED || (ret == RADAR && wpa_s->p2p_go_allow_dfs)))
		return 0;
	if (is_6ghz_op_class(op_class)) {
		chans = center_channels_6ghz_160mhz;
		num_chans = ARRAY_SIZE(center_channels_6ghz_160mhz);
	} else {
		chans = center_channels_5ghz_160mhz;
		num_chans = ARRAY_SIZE(center_channels_5ghz_160mhz);
	}
	return wpas_p2p_get_center_160mhz(wpa_s, mode, channel,
					  chans, num_chans);
}


static int wpas_get_noa(void *ctx, const u8 *interface_addr, u8 *buf,
			size_t buf_len)
{
	struct wpa_supplicant *wpa_s = ctx;

	for (wpa_s = wpa_s->global->ifaces; wpa_s; wpa_s = wpa_s->next) {
		if (os_memcmp(wpa_s->own_addr, interface_addr, ETH_ALEN) == 0)
			break;
	}
	if (wpa_s == NULL)
		return -1;

	return wpa_drv_get_noa(wpa_s, buf, buf_len);
}


struct wpa_supplicant * wpas_get_p2p_go_iface(struct wpa_supplicant *wpa_s,
					      const u8 *ssid, size_t ssid_len)
{
	for (wpa_s = wpa_s->global->ifaces; wpa_s; wpa_s = wpa_s->next) {
		struct wpa_ssid *s = wpa_s->current_ssid;
		if (s == NULL)
			continue;
		if (s->mode != WPAS_MODE_P2P_GO &&
		    s->mode != WPAS_MODE_AP &&
		    s->mode != WPAS_MODE_P2P_GROUP_FORMATION)
			continue;
		if (s->ssid_len != ssid_len ||
		    os_memcmp(ssid, s->ssid, ssid_len) != 0)
			continue;
		return wpa_s;
	}

	return NULL;

}


struct wpa_supplicant * wpas_get_p2p_client_iface(struct wpa_supplicant *wpa_s,
						  const u8 *peer_dev_addr)
{
	for (wpa_s = wpa_s->global->ifaces; wpa_s; wpa_s = wpa_s->next) {
		struct wpa_ssid *ssid = wpa_s->current_ssid;
		if (ssid && (ssid->mode != WPAS_MODE_INFRA || !ssid->p2p_group))
			continue;
		if (os_memcmp(wpa_s->go_dev_addr, peer_dev_addr, ETH_ALEN) == 0)
			return wpa_s;
	}

	return NULL;
}


static int wpas_go_connected(void *ctx, const u8 *dev_addr)
{
	struct wpa_supplicant *wpa_s = ctx;

	return wpas_get_p2p_client_iface(wpa_s, dev_addr) != NULL;
}


static int wpas_is_concurrent_session_active(void *ctx)
{
	struct wpa_supplicant *wpa_s = ctx;
	struct wpa_supplicant *ifs;

	for (ifs = wpa_s->global->ifaces; ifs; ifs = ifs->next) {
		if (ifs == wpa_s)
			continue;
		if (ifs->wpa_state > WPA_ASSOCIATED)
			return 1;
	}
	return 0;
}


static void wpas_p2p_debug_print(void *ctx, int level, const char *msg)
{
	struct wpa_supplicant *wpa_s = ctx;
	wpa_msg_global(wpa_s, level, "P2P: %s", msg);
}


int wpas_p2p_add_p2pdev_interface(struct wpa_supplicant *wpa_s,
				  const char *conf_p2p_dev)
{
	struct wpa_interface iface;
	struct wpa_supplicant *p2pdev_wpa_s;
	char ifname[100];
	char force_name[100];
	int ret;
	const u8 *if_addr = NULL;

	ret = os_snprintf(ifname, sizeof(ifname), P2P_MGMT_DEVICE_PREFIX "%s",
			  wpa_s->ifname);
	if (os_snprintf_error(sizeof(ifname), ret))
		return -1;
	/* Cut length at the maximum size. Note that we don't need to ensure
	 * collision free names here as the created interface is not a netdev.
	 */
	ifname[IFNAMSIZ - 1] = '\0';
	force_name[0] = '\0';
	wpa_s->pending_interface_type = WPA_IF_P2P_DEVICE;

	if (wpa_s->conf->p2p_device_random_mac_addr == 2 &&
	    !is_zero_ether_addr(wpa_s->conf->p2p_device_persistent_mac_addr))
		if_addr = wpa_s->conf->p2p_device_persistent_mac_addr;

	ret = wpa_drv_if_add(wpa_s, WPA_IF_P2P_DEVICE, ifname, if_addr, NULL,
			     force_name, wpa_s->pending_interface_addr, NULL);
	if (ret < 0) {
		wpa_printf(MSG_DEBUG, "P2P: Failed to create P2P Device interface");
		return ret;
	}
	os_strlcpy(wpa_s->pending_interface_name, ifname,
		   sizeof(wpa_s->pending_interface_name));

	os_memset(&iface, 0, sizeof(iface));
	iface.p2p_mgmt = 1;
	iface.ifname = wpa_s->pending_interface_name;
	iface.driver = wpa_s->driver->name;
	iface.driver_param = wpa_s->conf->driver_param;

	/*
	 * If a P2P Device configuration file was given, use it as the interface
	 * configuration file (instead of using parent's configuration file.
	 */
	if (conf_p2p_dev) {
		iface.confname = conf_p2p_dev;
		iface.ctrl_interface = NULL;
	} else {
		iface.confname = wpa_s->confname;
		iface.ctrl_interface = wpa_s->conf->ctrl_interface;
	}

	p2pdev_wpa_s = wpa_supplicant_add_iface(wpa_s->global, &iface, wpa_s);
	if (!p2pdev_wpa_s) {
		wpa_printf(MSG_DEBUG, "P2P: Failed to add P2P Device interface");
		return -1;
	}

	p2pdev_wpa_s->p2pdev = p2pdev_wpa_s;
	wpa_s->pending_interface_name[0] = '\0';
	return 0;
}


static void wpas_presence_resp(void *ctx, const u8 *src, u8 status,
			       const u8 *noa, size_t noa_len)
{
	struct wpa_supplicant *wpa_s, *intf = ctx;
	char hex[100];

	for (wpa_s = intf->global->ifaces; wpa_s; wpa_s = wpa_s->next) {
		if (wpa_s->waiting_presence_resp)
			break;
	}
	if (!wpa_s) {
		wpa_dbg(wpa_s, MSG_DEBUG, "P2P: No group interface was waiting for presence response");
		return;
	}
	wpa_s->waiting_presence_resp = 0;

	wpa_snprintf_hex(hex, sizeof(hex), noa, noa_len);
	wpa_msg(wpa_s, MSG_INFO, P2P_EVENT_PRESENCE_RESPONSE "src=" MACSTR
		" status=%u noa=%s", MAC2STR(src), status, hex);
}


static int wpas_get_persistent_group(void *ctx, const u8 *addr, const u8 *ssid,
				     size_t ssid_len, u8 *go_dev_addr,
				     u8 *ret_ssid, size_t *ret_ssid_len,
				     u8 *intended_iface_addr)
{
	struct wpa_supplicant *wpa_s = ctx;
	struct wpa_ssid *s;

	s = wpas_p2p_get_persistent(wpa_s, addr, ssid, ssid_len);
	if (s) {
		os_memcpy(ret_ssid, s->ssid, s->ssid_len);
		*ret_ssid_len = s->ssid_len;
		os_memcpy(go_dev_addr, s->bssid, ETH_ALEN);

		if (s->mode != WPAS_MODE_P2P_GO) {
			os_memset(intended_iface_addr, 0, ETH_ALEN);
		} else if (wpas_p2p_create_iface(wpa_s)) {
			if (wpas_p2p_add_group_interface(wpa_s, WPA_IF_P2P_GO))
				return 0;

			os_memcpy(intended_iface_addr,
				  wpa_s->pending_interface_addr, ETH_ALEN);
		} else {
			os_memcpy(intended_iface_addr, wpa_s->own_addr,
				  ETH_ALEN);
		}
		return 1;
	}

	return 0;
}


static int wpas_get_go_info(void *ctx, u8 *intended_addr,
			    u8 *ssid, size_t *ssid_len, int *group_iface,
			    unsigned int *freq)
{
	struct wpa_supplicant *wpa_s = ctx;
	struct wpa_supplicant *go;
	struct wpa_ssid *s;

	/*
	 * group_iface will be set to 1 only if a dedicated interface for P2P
	 * role is required. First, we try to reuse an active GO. However,
	 * if it is not present, we will try to reactivate an existing
	 * persistent group and set group_iface to 1, so the caller will know
	 * that the pending interface should be used.
	 */
	*group_iface = 0;

	if (freq)
		*freq = 0;

	go = wpas_p2p_get_go_group(wpa_s);
	if (!go) {
		s = wpas_p2p_get_persistent_go(wpa_s);
		*group_iface = wpas_p2p_create_iface(wpa_s);
		if (s)
			os_memcpy(intended_addr, s->bssid, ETH_ALEN);
		else
			return 0;
	} else {
		s = go->current_ssid;
		os_memcpy(intended_addr, go->own_addr, ETH_ALEN);
		if (freq)
			*freq = go->assoc_freq;
	}

	os_memcpy(ssid, s->ssid, s->ssid_len);
	*ssid_len = s->ssid_len;

	return 1;
}


static int wpas_remove_stale_groups(void *ctx, const u8 *peer, const u8 *go,
				    const u8 *ssid, size_t ssid_len)
{
	struct wpa_supplicant *wpa_s = ctx;
	struct wpa_ssid *s;
	int save_config = 0;
	size_t i;

	/* Start with our first choice of Persistent Groups */
	while ((s = wpas_p2p_get_persistent(wpa_s, peer, NULL, 0))) {
		if (go && ssid && ssid_len &&
		    s->ssid_len == ssid_len &&
		    os_memcmp(go, s->bssid, ETH_ALEN) == 0 &&
		    os_memcmp(ssid, s->ssid, ssid_len) == 0)
			break;

		/* Remove stale persistent group */
		if (s->mode != WPAS_MODE_P2P_GO || s->num_p2p_clients <= 1) {
			wpa_dbg(wpa_s, MSG_DEBUG,
				"P2P: Remove stale persistent group id=%d",
				s->id);
			wpas_notify_persistent_group_removed(wpa_s, s);
			wpa_config_remove_network(wpa_s->conf, s->id);
			save_config = 1;
			continue;
		}

		for (i = 0; i < s->num_p2p_clients; i++) {
			if (os_memcmp(s->p2p_client_list + i * 2 * ETH_ALEN,
				      peer, ETH_ALEN) != 0)
				continue;

			os_memmove(s->p2p_client_list + i * 2 * ETH_ALEN,
				   s->p2p_client_list + (i + 1) * 2 * ETH_ALEN,
				   (s->num_p2p_clients - i - 1) * 2 * ETH_ALEN);
			break;
		}
		s->num_p2p_clients--;
		save_config = 1;
	}

	if (save_config)
		p2p_config_write(wpa_s);

	/* Return TRUE if valid SSID remains */
	return s != NULL;
}


static void wpas_p2ps_get_feat_cap_str(char *buf, size_t buf_len,
				       const u8 *feat_cap, size_t feat_cap_len)
{
	static const char pref[] = " feature_cap=";
	int ret;

	buf[0] = '\0';

	/*
	 * We expect a feature capability to contain at least one byte to be
	 * reported. The string buffer provided by the caller function is
	 * expected to be big enough to contain all bytes of the attribute for
	 * known specifications. This function truncates the reported bytes if
	 * the feature capability data exceeds the string buffer size.
	 */
	if (!feat_cap || !feat_cap_len || buf_len < sizeof(pref) + 2)
		return;

	os_memcpy(buf, pref, sizeof(pref));
	ret = wpa_snprintf_hex(&buf[sizeof(pref) - 1],
			       buf_len - sizeof(pref) + 1,
			       feat_cap, feat_cap_len);

	if (ret != (2 * (int) feat_cap_len))
		wpa_printf(MSG_WARNING, "P2PS feature_cap bytes truncated");
}


static void wpas_p2ps_prov_complete(void *ctx, u8 status, const u8 *dev,
				    const u8 *adv_mac, const u8 *ses_mac,
				    const u8 *grp_mac, u32 adv_id, u32 ses_id,
				    u8 conncap, int passwd_id,
				    const u8 *persist_ssid,
				    size_t persist_ssid_size, int response_done,
				    int prov_start, const char *session_info,
				    const u8 *feat_cap, size_t feat_cap_len,
				    unsigned int freq,
				    const u8 *group_ssid, size_t group_ssid_len)
{
	struct wpa_supplicant *wpa_s = ctx;
	u8 mac[ETH_ALEN];
	struct wpa_ssid *persistent_go, *stale, *s = NULL;
	int save_config = 0;
	struct wpa_supplicant *go_wpa_s;
	char feat_cap_str[256];

	if (!dev)
		return;

	os_memset(mac, 0, ETH_ALEN);
	if (!adv_mac)
		adv_mac = mac;
	if (!ses_mac)
		ses_mac = mac;
	if (!grp_mac)
		grp_mac = mac;

	wpas_p2ps_get_feat_cap_str(feat_cap_str, sizeof(feat_cap_str),
				   feat_cap, feat_cap_len);

	if (prov_start) {
		if (session_info == NULL) {
			wpa_msg_global(wpa_s, MSG_INFO,
				       P2P_EVENT_P2PS_PROVISION_START MACSTR
				       " adv_id=%x conncap=%x"
				       " adv_mac=" MACSTR
				       " session=%x mac=" MACSTR
				       " dev_passwd_id=%d%s",
				       MAC2STR(dev), adv_id, conncap,
				       MAC2STR(adv_mac),
				       ses_id, MAC2STR(ses_mac),
				       passwd_id, feat_cap_str);
		} else {
			wpa_msg_global(wpa_s, MSG_INFO,
				       P2P_EVENT_P2PS_PROVISION_START MACSTR
				       " adv_id=%x conncap=%x"
				       " adv_mac=" MACSTR
				       " session=%x mac=" MACSTR
				       " dev_passwd_id=%d info='%s'%s",
				       MAC2STR(dev), adv_id, conncap,
				       MAC2STR(adv_mac),
				       ses_id, MAC2STR(ses_mac),
				       passwd_id, session_info, feat_cap_str);
		}
		return;
	}

	go_wpa_s = wpas_p2p_get_go_group(wpa_s);
	persistent_go = wpas_p2p_get_persistent_go(wpa_s);

	if (status && status != P2P_SC_SUCCESS_DEFERRED) {
		if (go_wpa_s && !p2p_group_go_member_count(wpa_s))
			wpas_p2p_group_remove(wpa_s, go_wpa_s->ifname);

		if (persistent_go && !persistent_go->num_p2p_clients) {
			/* remove empty persistent GO */
			wpa_dbg(wpa_s, MSG_DEBUG,
				"P2P: Remove empty persistent group id=%d",
				persistent_go->id);
			wpas_notify_persistent_group_removed(wpa_s,
							     persistent_go);
			wpa_config_remove_network(wpa_s->conf,
						  persistent_go->id);
		}

		wpa_msg_global(wpa_s, MSG_INFO,
			       P2P_EVENT_P2PS_PROVISION_DONE MACSTR
			       " status=%d"
			       " adv_id=%x adv_mac=" MACSTR
			       " session=%x mac=" MACSTR "%s",
			       MAC2STR(dev), status,
			       adv_id, MAC2STR(adv_mac),
			       ses_id, MAC2STR(ses_mac), feat_cap_str);
		return;
	}

	/* Clean up stale persistent groups with this device */
	if (persist_ssid && persist_ssid_size)
		s = wpas_p2p_get_persistent(wpa_s, dev, persist_ssid,
					    persist_ssid_size);

	if (persist_ssid && s && s->mode != WPAS_MODE_P2P_GO &&
	    is_zero_ether_addr(grp_mac)) {
		wpa_dbg(wpa_s, MSG_ERROR,
			"P2P: Peer device is a GO in a persistent group, but it did not provide the intended MAC address");
		return;
	}

	for (;;) {
		stale = wpas_p2p_get_persistent(wpa_s, dev, NULL, 0);
		if (!stale)
			break;

		if (s && s->ssid_len == stale->ssid_len &&
		    os_memcmp(stale->bssid, s->bssid, ETH_ALEN) == 0 &&
		    os_memcmp(stale->ssid, s->ssid, s->ssid_len) == 0)
			break;

		/* Remove stale persistent group */
		if (stale->mode != WPAS_MODE_P2P_GO ||
		    stale->num_p2p_clients <= 1) {
			wpa_dbg(wpa_s, MSG_DEBUG,
				"P2P: Remove stale persistent group id=%d",
				stale->id);
			wpas_notify_persistent_group_removed(wpa_s, stale);
			wpa_config_remove_network(wpa_s->conf, stale->id);
		} else {
			size_t i;

			for (i = 0; i < stale->num_p2p_clients; i++) {
				if (os_memcmp(stale->p2p_client_list +
					      i * ETH_ALEN,
					      dev, ETH_ALEN) == 0) {
					os_memmove(stale->p2p_client_list +
						   i * ETH_ALEN,
						   stale->p2p_client_list +
						   (i + 1) * ETH_ALEN,
						   (stale->num_p2p_clients -
						    i - 1) * ETH_ALEN);
					break;
				}
			}
			stale->num_p2p_clients--;
		}
		save_config = 1;
	}

	if (save_config)
		p2p_config_write(wpa_s);

	if (s) {
		if (go_wpa_s && !p2p_group_go_member_count(wpa_s))
			wpas_p2p_group_remove(wpa_s, go_wpa_s->ifname);

		if (persistent_go && s != persistent_go &&
		    !persistent_go->num_p2p_clients) {
			/* remove empty persistent GO */
			wpa_dbg(wpa_s, MSG_DEBUG,
				"P2P: Remove empty persistent group id=%d",
				persistent_go->id);
			wpas_notify_persistent_group_removed(wpa_s,
							     persistent_go);
			wpa_config_remove_network(wpa_s->conf,
						  persistent_go->id);
			/* Save config */
		}

		wpa_msg_global(wpa_s, MSG_INFO,
			       P2P_EVENT_P2PS_PROVISION_DONE MACSTR
			       " status=%d"
			       " adv_id=%x adv_mac=" MACSTR
			       " session=%x mac=" MACSTR
			       " persist=%d%s",
			       MAC2STR(dev), status,
			       adv_id, MAC2STR(adv_mac),
			       ses_id, MAC2STR(ses_mac), s->id, feat_cap_str);
		return;
	}

	wpa_s->global->pending_p2ps_group = 0;
	wpa_s->global->pending_p2ps_group_freq = 0;

	if (conncap == P2PS_SETUP_GROUP_OWNER) {
		/*
		 * We need to copy the interface name. Simply saving a
		 * pointer isn't enough, since if we use pending_interface_name
		 * it will be overwritten when the group is added.
		 */
		char go_ifname[100];

		go_ifname[0] = '\0';
		if (!go_wpa_s) {
			if (!response_done) {
				wpa_s->global->pending_p2ps_group = 1;
				wpa_s->global->pending_p2ps_group_freq = freq;
			}

			if (!wpas_p2p_create_iface(wpa_s))
				os_memcpy(go_ifname, wpa_s->ifname,
					  sizeof(go_ifname));
			else if (wpa_s->pending_interface_name[0])
				os_memcpy(go_ifname,
					  wpa_s->pending_interface_name,
					  sizeof(go_ifname));

			if (!go_ifname[0]) {
				wpas_p2ps_prov_complete(
					wpa_s, P2P_SC_FAIL_UNKNOWN_GROUP,
					dev, adv_mac, ses_mac,
					grp_mac, adv_id, ses_id, 0, 0,
					NULL, 0, 0, 0, NULL, NULL, 0, 0,
					NULL, 0);
				return;
			}

			/* If PD Resp complete, start up the GO */
			if (response_done && persistent_go) {
				wpas_p2p_group_add_persistent(
					wpa_s, persistent_go,
					0, 0, freq, 0, 0, 0, 0, 0, 0, NULL,
					persistent_go->mode ==
					WPAS_MODE_P2P_GO ?
					P2P_MAX_INITIAL_CONN_WAIT_GO_REINVOKE :
					0, 0, false);
			} else if (response_done) {
				wpas_p2p_group_add(wpa_s, 1, freq,
						   0, 0, 0, 0, 0, 0, false);
			}

			if (passwd_id == DEV_PW_P2PS_DEFAULT) {
				os_memcpy(wpa_s->p2ps_join_addr, grp_mac,
					  ETH_ALEN);
				wpa_s->p2ps_method_config_any = 1;
			}
		} else if (passwd_id == DEV_PW_P2PS_DEFAULT) {
			os_memcpy(go_ifname, go_wpa_s->ifname,
				  sizeof(go_ifname));

			if (is_zero_ether_addr(grp_mac)) {
				wpa_dbg(go_wpa_s, MSG_DEBUG,
					"P2P: Setting PIN-1 for ANY");
				wpa_supplicant_ap_wps_pin(go_wpa_s, NULL,
							  "12345670", NULL, 0,
							  0);
			} else {
				wpa_dbg(go_wpa_s, MSG_DEBUG,
					"P2P: Setting PIN-1 for " MACSTR,
					MAC2STR(grp_mac));
				wpa_supplicant_ap_wps_pin(go_wpa_s, grp_mac,
							  "12345670", NULL, 0,
							  0);
			}

			os_memcpy(wpa_s->p2ps_join_addr, grp_mac, ETH_ALEN);
			wpa_s->p2ps_method_config_any = 1;
		}

		wpa_msg_global(wpa_s, MSG_INFO,
			       P2P_EVENT_P2PS_PROVISION_DONE MACSTR
			       " status=%d conncap=%x"
			       " adv_id=%x adv_mac=" MACSTR
			       " session=%x mac=" MACSTR
			       " dev_passwd_id=%d go=%s%s",
			       MAC2STR(dev), status, conncap,
			       adv_id, MAC2STR(adv_mac),
			       ses_id, MAC2STR(ses_mac),
			       passwd_id, go_ifname, feat_cap_str);
		return;
	}

	if (go_wpa_s && !p2p_group_go_member_count(wpa_s))
		wpas_p2p_group_remove(wpa_s, go_wpa_s->ifname);

	if (persistent_go && !persistent_go->num_p2p_clients) {
		/* remove empty persistent GO */
		wpa_dbg(wpa_s, MSG_DEBUG,
			"P2P: Remove empty persistent group id=%d",
			persistent_go->id);
		wpas_notify_persistent_group_removed(wpa_s, persistent_go);
		wpa_config_remove_network(wpa_s->conf, persistent_go->id);
	}

	if (conncap == P2PS_SETUP_CLIENT) {
		char ssid_hex[32 * 2 + 1];

		if (group_ssid)
			wpa_snprintf_hex(ssid_hex, sizeof(ssid_hex),
					 group_ssid, group_ssid_len);
		else
			ssid_hex[0] = '\0';
		wpa_msg_global(wpa_s, MSG_INFO,
			       P2P_EVENT_P2PS_PROVISION_DONE MACSTR
			       " status=%d conncap=%x"
			       " adv_id=%x adv_mac=" MACSTR
			       " session=%x mac=" MACSTR
			       " dev_passwd_id=%d join=" MACSTR "%s%s%s",
			       MAC2STR(dev), status, conncap,
			       adv_id, MAC2STR(adv_mac),
			       ses_id, MAC2STR(ses_mac),
			       passwd_id, MAC2STR(grp_mac), feat_cap_str,
			       group_ssid ? " group_ssid=" : "", ssid_hex);
	} else {
		wpa_msg_global(wpa_s, MSG_INFO,
			       P2P_EVENT_P2PS_PROVISION_DONE MACSTR
			       " status=%d conncap=%x"
			       " adv_id=%x adv_mac=" MACSTR
			       " session=%x mac=" MACSTR
			       " dev_passwd_id=%d%s",
			       MAC2STR(dev), status, conncap,
			       adv_id, MAC2STR(adv_mac),
			       ses_id, MAC2STR(ses_mac),
			       passwd_id, feat_cap_str);
	}
}


static int _wpas_p2p_in_progress(void *ctx)
{
	struct wpa_supplicant *wpa_s = ctx;
	return wpas_p2p_in_progress(wpa_s);
}


static int wpas_prov_disc_resp_cb(void *ctx)
{
	struct wpa_supplicant *wpa_s = ctx;
	struct wpa_ssid *persistent_go;
	unsigned int freq;

	if (!wpa_s->global->pending_p2ps_group)
		return 0;

	freq = wpa_s->global->pending_p2ps_group_freq;
	wpa_s->global->pending_p2ps_group_freq = 0;
	wpa_s->global->pending_p2ps_group = 0;

	if (wpas_p2p_get_go_group(wpa_s))
		return 0;
	persistent_go = wpas_p2p_get_persistent_go(wpa_s);

	if (persistent_go) {
		wpas_p2p_group_add_persistent(
			wpa_s, persistent_go, 0, 0, 0, 0, 0, 0, 0, 0, 0,
			NULL,
			persistent_go->mode == WPAS_MODE_P2P_GO ?
			P2P_MAX_INITIAL_CONN_WAIT_GO_REINVOKE : 0, 0,
			is_p2p_allow_6ghz(wpa_s->global->p2p));
	} else {
		wpas_p2p_group_add(wpa_s, 1, freq, 0, 0, 0, 0, 0, 0,
				   is_p2p_allow_6ghz(wpa_s->global->p2p));
	}

	return 1;
}


static int wpas_p2p_get_pref_freq_list(void *ctx, int go,
				       unsigned int *len,
				       unsigned int *freq_list)
{
	struct wpa_supplicant *wpa_s = ctx;

	return wpa_drv_get_pref_freq_list(wpa_s, go ? WPA_IF_P2P_GO :
					  WPA_IF_P2P_CLIENT, len, freq_list);
}

int wpas_p2p_mac_setup(struct wpa_supplicant *wpa_s)
{
	u8 addr[ETH_ALEN] = {0};

	if (wpa_s->conf->p2p_device_random_mac_addr == 0)
		return 0;

	if (wpa_s->conf->p2p_device_random_mac_addr == 2) {
		if (is_zero_ether_addr(
			    wpa_s->conf->p2p_device_persistent_mac_addr) &&
		    !is_zero_ether_addr(wpa_s->own_addr)) {
			os_memcpy(wpa_s->conf->p2p_device_persistent_mac_addr,
				  wpa_s->own_addr, ETH_ALEN);
		}
		return 0;
	}

	if (!wpa_s->conf->ssid) {
		if (random_mac_addr(addr) < 0) {
			wpa_msg(wpa_s, MSG_INFO,
				"Failed to generate random MAC address");
			return -EINVAL;
		}

		/* Store generated MAC address. */
		os_memcpy(wpa_s->conf->p2p_device_persistent_mac_addr, addr,
			  ETH_ALEN);
	} else {
		/* If there are existing saved groups, restore last MAC address.
		 * if there is no last used MAC address, the last one is
		 * factory MAC. */
		if (is_zero_ether_addr(
			    wpa_s->conf->p2p_device_persistent_mac_addr))
			return 0;
		os_memcpy(addr, wpa_s->conf->p2p_device_persistent_mac_addr,
			  ETH_ALEN);
		wpa_msg(wpa_s, MSG_DEBUG, "Restore last used MAC address.");
	}

	if (wpa_drv_set_mac_addr(wpa_s, addr) < 0) {
		wpa_msg(wpa_s, MSG_INFO,
			"Failed to set random MAC address");
		return -EINVAL;
	}

	if (wpa_supplicant_update_mac_addr(wpa_s) < 0) {
		wpa_msg(wpa_s, MSG_INFO,
			"Could not update MAC address information");
		return -EINVAL;
	}

	wpa_msg(wpa_s, MSG_DEBUG, "Using random MAC address " MACSTR,
		MAC2STR(addr));

	return 0;
}

/**
 * wpas_p2p_init - Initialize P2P module for %wpa_supplicant
 * @global: Pointer to global data from wpa_supplicant_init()
 * @wpa_s: Pointer to wpa_supplicant data from wpa_supplicant_add_iface()
 * Returns: 0 on success, -1 on failure
 */
int wpas_p2p_init(struct wpa_global *global, struct wpa_supplicant *wpa_s)
{
	struct p2p_config p2p;
	int i;

	if (wpa_s->conf->p2p_disabled)
		return 0;

	if (!(wpa_s->drv_flags & WPA_DRIVER_FLAGS_P2P_CAPABLE))
		return 0;

	if (global->p2p)
		return 0;

	if (wpas_p2p_mac_setup(wpa_s) < 0) {
		wpa_msg(wpa_s, MSG_ERROR,
			"Failed to initialize P2P random MAC address.");
		return -1;
	}

	os_memset(&p2p, 0, sizeof(p2p));
	p2p.cb_ctx = wpa_s;
	p2p.debug_print = wpas_p2p_debug_print;
	p2p.p2p_scan = wpas_p2p_scan;
	p2p.send_action = wpas_send_action;
	p2p.send_action_done = wpas_send_action_done;
	p2p.go_neg_completed = wpas_go_neg_completed;
	p2p.go_neg_req_rx = wpas_go_neg_req_rx;
	p2p.dev_found = wpas_dev_found;
	p2p.dev_lost = wpas_dev_lost;
	p2p.find_stopped = wpas_find_stopped;
	p2p.start_listen = wpas_start_listen;
	p2p.stop_listen = wpas_stop_listen;
	p2p.send_probe_resp = wpas_send_probe_resp;
	p2p.sd_request = wpas_sd_request;
	p2p.sd_response = wpas_sd_response;
	p2p.prov_disc_req = wpas_prov_disc_req;
	p2p.prov_disc_resp = wpas_prov_disc_resp;
	p2p.prov_disc_fail = wpas_prov_disc_fail;
	p2p.invitation_process = wpas_invitation_process;
	p2p.invitation_received = wpas_invitation_received;
	p2p.invitation_result = wpas_invitation_result;
	p2p.get_noa = wpas_get_noa;
	p2p.go_connected = wpas_go_connected;
	p2p.presence_resp = wpas_presence_resp;
	p2p.is_concurrent_session_active = wpas_is_concurrent_session_active;
	p2p.is_p2p_in_progress = _wpas_p2p_in_progress;
	p2p.get_persistent_group = wpas_get_persistent_group;
	p2p.get_go_info = wpas_get_go_info;
	p2p.remove_stale_groups = wpas_remove_stale_groups;
	p2p.p2ps_prov_complete = wpas_p2ps_prov_complete;
	p2p.prov_disc_resp_cb = wpas_prov_disc_resp_cb;
	p2p.p2ps_group_capability = p2ps_group_capability;
	p2p.get_pref_freq_list = wpas_p2p_get_pref_freq_list;
	p2p.p2p_6ghz_disable = wpa_s->conf->p2p_6ghz_disable;

	os_memcpy(wpa_s->global->p2p_dev_addr, wpa_s->own_addr, ETH_ALEN);
	os_memcpy(p2p.dev_addr, wpa_s->global->p2p_dev_addr, ETH_ALEN);
	p2p.dev_name = wpa_s->conf->device_name;
	p2p.manufacturer = wpa_s->conf->manufacturer;
	p2p.model_name = wpa_s->conf->model_name;
	p2p.model_number = wpa_s->conf->model_number;
	p2p.serial_number = wpa_s->conf->serial_number;
	if (wpa_s->wps) {
		os_memcpy(p2p.uuid, wpa_s->wps->uuid, 16);
		p2p.config_methods = wpa_s->wps->config_methods;
	}

	if (wpas_p2p_setup_channels(wpa_s, &p2p.channels, &p2p.cli_channels,
				    p2p.p2p_6ghz_disable)) {
		wpa_printf(MSG_ERROR,
			   "P2P: Failed to configure supported channel list");
		return -1;
	}

	if (wpa_s->conf->p2p_listen_reg_class &&
	    wpa_s->conf->p2p_listen_channel) {
		p2p.reg_class = wpa_s->conf->p2p_listen_reg_class;
		p2p.channel = wpa_s->conf->p2p_listen_channel;
		p2p.channel_forced = 1;
	} else {
		/*
		 * Pick one of the social channels randomly as the listen
		 * channel.
		 */
		if (p2p_config_get_random_social(&p2p, &p2p.reg_class,
						 &p2p.channel,
						 &global->p2p_go_avoid_freq,
						 &global->p2p_disallow_freq) !=
		    0) {
			wpa_printf(MSG_INFO,
				   "P2P: No social channels supported by the driver - do not enable P2P");
			return 0;
		}
		p2p.channel_forced = 0;
	}
	wpa_printf(MSG_DEBUG, "P2P: Own listen channel: %d:%d",
		   p2p.reg_class, p2p.channel);

	if (wpa_s->conf->p2p_oper_reg_class &&
	    wpa_s->conf->p2p_oper_channel) {
		p2p.op_reg_class = wpa_s->conf->p2p_oper_reg_class;
		p2p.op_channel = wpa_s->conf->p2p_oper_channel;
		p2p.cfg_op_channel = 1;
		wpa_printf(MSG_DEBUG, "P2P: Configured operating channel: "
			   "%d:%d", p2p.op_reg_class, p2p.op_channel);

	} else {
		/*
		 * Use random operation channel from 2.4 GHz band social
		 * channels (1, 6, 11) or band 60 GHz social channel (2) if no
		 * other preference is indicated.
		 */
		if (p2p_config_get_random_social(&p2p, &p2p.op_reg_class,
						 &p2p.op_channel, NULL,
						 NULL) != 0) {
			wpa_printf(MSG_INFO,
				   "P2P: Failed to select random social channel as operation channel");
			p2p.op_reg_class = 0;
			p2p.op_channel = 0;
			/* This will be overridden during group setup in
			 * p2p_prepare_channel(), so allow setup to continue. */
		}
		p2p.cfg_op_channel = 0;
		wpa_printf(MSG_DEBUG, "P2P: Random operating channel: "
			   "%d:%d", p2p.op_reg_class, p2p.op_channel);
	}

	if (wpa_s->conf->p2p_pref_chan && wpa_s->conf->num_p2p_pref_chan) {
		p2p.pref_chan = wpa_s->conf->p2p_pref_chan;
		p2p.num_pref_chan = wpa_s->conf->num_p2p_pref_chan;
	}

	if (wpa_s->conf->country[0] && wpa_s->conf->country[1]) {
		os_memcpy(p2p.country, wpa_s->conf->country, 2);
		p2p.country[2] = 0x04;
	} else
		os_memcpy(p2p.country, "XX\x04", 3);

	os_memcpy(p2p.pri_dev_type, wpa_s->conf->device_type,
		  WPS_DEV_TYPE_LEN);

	p2p.num_sec_dev_types = wpa_s->conf->num_sec_device_types;
	os_memcpy(p2p.sec_dev_type, wpa_s->conf->sec_device_type,
		  p2p.num_sec_dev_types * WPS_DEV_TYPE_LEN);

	p2p.concurrent_operations = !!(wpa_s->drv_flags &
				       WPA_DRIVER_FLAGS_P2P_CONCURRENT);

	p2p.max_peers = 100;

	if (wpa_s->conf->p2p_ssid_postfix) {
		p2p.ssid_postfix_len =
			os_strlen(wpa_s->conf->p2p_ssid_postfix);
		if (p2p.ssid_postfix_len > sizeof(p2p.ssid_postfix))
			p2p.ssid_postfix_len = sizeof(p2p.ssid_postfix);
		os_memcpy(p2p.ssid_postfix, wpa_s->conf->p2p_ssid_postfix,
			  p2p.ssid_postfix_len);
	}

	p2p.p2p_intra_bss = wpa_s->conf->p2p_intra_bss;

	p2p.max_listen = wpa_s->max_remain_on_chan;

	if (wpa_s->conf->p2p_passphrase_len >= 8 &&
	    wpa_s->conf->p2p_passphrase_len <= 63)
		p2p.passphrase_len = wpa_s->conf->p2p_passphrase_len;
	else
		p2p.passphrase_len = 8;

	global->p2p = p2p_init(&p2p);
	if (global->p2p == NULL)
		return -1;
	global->p2p_init_wpa_s = wpa_s;

	for (i = 0; i < MAX_WPS_VENDOR_EXT; i++) {
		if (wpa_s->conf->wps_vendor_ext[i] == NULL)
			continue;
		p2p_add_wps_vendor_extension(
			global->p2p, wpa_s->conf->wps_vendor_ext[i]);
	}

	p2p_set_no_go_freq(global->p2p, &wpa_s->conf->p2p_no_go_freq);

	return 0;
}


/**
 * wpas_p2p_deinit - Deinitialize per-interface P2P data
 * @wpa_s: Pointer to wpa_supplicant data from wpa_supplicant_add_iface()
 *
 * This function deinitialize per-interface P2P data.
 */
void wpas_p2p_deinit(struct wpa_supplicant *wpa_s)
{
	if (wpa_s->driver && wpa_s->drv_priv)
		wpa_drv_probe_req_report(wpa_s, 0);

	if (wpa_s->go_params) {
		/* Clear any stored provisioning info */
		p2p_clear_provisioning_info(
			wpa_s->global->p2p,
			wpa_s->go_params->peer_device_addr);
	}

	os_free(wpa_s->go_params);
	wpa_s->go_params = NULL;
	eloop_cancel_timeout(wpas_p2p_psk_failure_removal, wpa_s, NULL);
	eloop_cancel_timeout(wpas_p2p_group_formation_timeout, wpa_s, NULL);
	eloop_cancel_timeout(wpas_p2p_join_scan, wpa_s, NULL);
	wpa_s->global->p2p_long_listen = 0;
	eloop_cancel_timeout(wpas_p2p_long_listen_timeout, wpa_s, NULL);
	eloop_cancel_timeout(wpas_p2p_group_idle_timeout, wpa_s, NULL);
	wpas_p2p_remove_pending_group_interface(wpa_s);
	eloop_cancel_timeout(wpas_p2p_group_freq_conflict, wpa_s, NULL);
	eloop_cancel_timeout(wpas_p2p_reconsider_moving_go, wpa_s, NULL);
	wpas_p2p_listen_work_done(wpa_s);
	if (wpa_s->p2p_send_action_work) {
		os_free(wpa_s->p2p_send_action_work->ctx);
		radio_work_done(wpa_s->p2p_send_action_work);
		wpa_s->p2p_send_action_work = NULL;
	}
	eloop_cancel_timeout(wpas_p2p_send_action_work_timeout, wpa_s, NULL);

	wpabuf_free(wpa_s->p2p_oob_dev_pw);
	wpa_s->p2p_oob_dev_pw = NULL;

	os_free(wpa_s->p2p_group_common_freqs);
	wpa_s->p2p_group_common_freqs = NULL;
	wpa_s->p2p_group_common_freqs_num = 0;

	/* TODO: remove group interface from the driver if this wpa_s instance
	 * is on top of a P2P group interface */
}


/**
 * wpas_p2p_deinit_global - Deinitialize global P2P module
 * @global: Pointer to global data from wpa_supplicant_init()
 *
 * This function deinitializes the global (per device) P2P module.
 */
static void wpas_p2p_deinit_global(struct wpa_global *global)
{
	struct wpa_supplicant *wpa_s, *tmp;

	wpa_s = global->ifaces;

	wpas_p2p_service_flush(global->p2p_init_wpa_s);

	/* Remove remaining P2P group interfaces */
	while (wpa_s && wpa_s->p2p_group_interface != NOT_P2P_GROUP_INTERFACE)
		wpa_s = wpa_s->next;
	while (wpa_s) {
		tmp = global->ifaces;
		while (tmp &&
		       (tmp == wpa_s ||
			tmp->p2p_group_interface == NOT_P2P_GROUP_INTERFACE)) {
			tmp = tmp->next;
		}
		if (tmp == NULL)
			break;
		/* Disconnect from the P2P group and deinit the interface */
		wpas_p2p_disconnect(tmp);
	}

	/*
	 * Deinit GO data on any possibly remaining interface (if main
	 * interface is used as GO).
	 */
	for (wpa_s = global->ifaces; wpa_s; wpa_s = wpa_s->next) {
		if (wpa_s->ap_iface)
			wpas_p2p_group_deinit(wpa_s);
	}

	p2p_deinit(global->p2p);
	global->p2p = NULL;
	global->p2p_init_wpa_s = NULL;
}


static int wpas_p2p_create_iface(struct wpa_supplicant *wpa_s)
{
	if (wpa_s->conf->p2p_no_group_iface)
		return 0; /* separate interface disabled per configuration */
	if (wpa_s->drv_flags &
	    (WPA_DRIVER_FLAGS_P2P_DEDICATED_INTERFACE |
	     WPA_DRIVER_FLAGS_P2P_MGMT_AND_NON_P2P))
		return 1; /* P2P group requires a new interface in every case
			   */
	if (!(wpa_s->drv_flags & WPA_DRIVER_FLAGS_P2P_CONCURRENT))
		return 0; /* driver does not support concurrent operations */
	if (wpa_s->global->ifaces->next)
		return 1; /* more that one interface already in use */
	if (wpa_s->wpa_state >= WPA_AUTHENTICATING)
		return 1; /* this interface is already in use */
	return 0;
}


static int wpas_p2p_start_go_neg(struct wpa_supplicant *wpa_s,
				 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,
				 struct wpa_ssid *ssid, unsigned int pref_freq)
{
	if (persistent_group && wpa_s->conf->persistent_reconnect)
		persistent_group = 2;

	/*
	 * Increase GO config timeout if HT40 is used since it takes some time
	 * to scan channels for coex purposes before the BSS can be started.
	 */
	p2p_set_config_timeout(wpa_s->global->p2p,
			       wpa_s->p2p_go_ht40 ? 255 : 100, 20);

	return p2p_connect(wpa_s->global->p2p, peer_addr, wps_method,
			   go_intent, own_interface_addr, force_freq,
			   persistent_group, ssid ? ssid->ssid : NULL,
			   ssid ? ssid->ssid_len : 0,
			   wpa_s->p2p_pd_before_go_neg, pref_freq,
			   wps_method == WPS_NFC ? wpa_s->p2p_oob_dev_pw_id :
			   0);
}


static int wpas_p2p_auth_go_neg(struct wpa_supplicant *wpa_s,
				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,
				struct wpa_ssid *ssid, unsigned int pref_freq)
{
	if (persistent_group && wpa_s->conf->persistent_reconnect)
		persistent_group = 2;

	return p2p_authorize(wpa_s->global->p2p, peer_addr, wps_method,
			     go_intent, own_interface_addr, force_freq,
			     persistent_group, ssid ? ssid->ssid : NULL,
			     ssid ? ssid->ssid_len : 0, pref_freq,
			     wps_method == WPS_NFC ? wpa_s->p2p_oob_dev_pw_id :
			     0);
}


static void wpas_p2p_check_join_scan_limit(struct wpa_supplicant *wpa_s)
{
	wpa_s->p2p_join_scan_count++;
	wpa_printf(MSG_DEBUG, "P2P: Join scan attempt %d",
		   wpa_s->p2p_join_scan_count);
	if (wpa_s->p2p_join_scan_count > P2P_MAX_JOIN_SCAN_ATTEMPTS) {
		wpa_printf(MSG_DEBUG, "P2P: Failed to find GO " MACSTR
			   " for join operationg - stop join attempt",
			   MAC2STR(wpa_s->pending_join_iface_addr));
		eloop_cancel_timeout(wpas_p2p_join_scan, wpa_s, NULL);
		if (wpa_s->p2p_auto_pd) {
			wpa_s->p2p_auto_pd = 0;
			wpa_msg_global(wpa_s, MSG_INFO,
				       P2P_EVENT_PROV_DISC_FAILURE
				       " p2p_dev_addr=" MACSTR " status=N/A",
				       MAC2STR(wpa_s->pending_join_dev_addr));
			return;
		}
		if (wpa_s->p2p_fallback_to_go_neg) {
			wpa_dbg(wpa_s, MSG_DEBUG, "P2P: Join operating "
				"failed - fall back to GO Negotiation");
			wpa_msg_global(wpa_s->p2pdev, MSG_INFO,
				       P2P_EVENT_FALLBACK_TO_GO_NEG
				       "reason=join-failed");
			wpas_p2p_fallback_to_go_neg(wpa_s, 0);
			return;
		}
		wpa_msg_global(wpa_s->p2pdev, MSG_INFO,
			       P2P_EVENT_GROUP_FORMATION_FAILURE);
		wpas_notify_p2p_group_formation_failure(wpa_s, "");
	}
}


static int wpas_check_freq_conflict(struct wpa_supplicant *wpa_s, int freq)
{
	int res;
	unsigned int num, i;
	struct wpa_used_freq_data *freqs;

	if (wpas_p2p_num_unused_channels(wpa_s) > 0) {
		/* Multiple channels are supported and not all are in use */
		return 0;
	}

	freqs = os_calloc(wpa_s->num_multichan_concurrent,
			  sizeof(struct wpa_used_freq_data));
	if (!freqs)
		return 1;

	num = wpas_p2p_valid_oper_freqs(wpa_s, freqs,
					wpa_s->num_multichan_concurrent);

	for (i = 0; i < num; i++) {
		if (freqs[i].freq == freq) {
			wpa_printf(MSG_DEBUG, "P2P: Frequency %d MHz in use by another virtual interface and can be used",
				   freq);
			res = 0;
			goto exit_free;
		}
	}

	wpa_printf(MSG_DEBUG, "P2P: No valid operating frequencies");
	res = 1;

exit_free:
	os_free(freqs);
	return res;
}


static int wpas_p2p_peer_go(struct wpa_supplicant *wpa_s,
			    const u8 *peer_dev_addr)
{
	struct wpa_bss *bss;
	int updated;

	bss = wpa_bss_get_p2p_dev_addr(wpa_s, peer_dev_addr);
	if (bss == NULL)
		return -1;
	if (bss->last_update_idx < wpa_s->bss_update_idx) {
		wpa_printf(MSG_DEBUG, "P2P: Peer BSS entry not updated in the "
			   "last scan");
		return 0;
	}

	updated = os_reltime_before(&wpa_s->p2p_auto_started,
				    &bss->last_update);
	wpa_printf(MSG_DEBUG, "P2P: Current BSS entry for peer updated at "
		   "%ld.%06ld (%supdated in last scan)",
		   bss->last_update.sec, bss->last_update.usec,
		   updated ? "": "not ");

	return updated;
}


static void wpas_p2p_scan_res_join(struct wpa_supplicant *wpa_s,
				   struct wpa_scan_results *scan_res)
{
	struct wpa_bss *bss = NULL;
	int freq;
	u8 iface_addr[ETH_ALEN];

	eloop_cancel_timeout(wpas_p2p_join_scan, wpa_s, NULL);

	if (wpa_s->global->p2p_disabled)
		return;

	wpa_printf(MSG_DEBUG, "P2P: Scan results received (%d BSS) for %sjoin",
		   scan_res ? (int) scan_res->num : -1,
		   wpa_s->p2p_auto_join ? "auto_" : "");

	if (scan_res)
		wpas_p2p_scan_res_handler(wpa_s, scan_res);

	if (wpa_s->p2p_auto_pd) {
		int join = wpas_p2p_peer_go(wpa_s,
					    wpa_s->pending_join_dev_addr);
		if (join == 0 &&
		    wpa_s->auto_pd_scan_retry < P2P_AUTO_PD_SCAN_ATTEMPTS) {
			wpa_s->auto_pd_scan_retry++;
			bss = wpa_bss_get_bssid_latest(
				wpa_s, wpa_s->pending_join_dev_addr);
			if (bss) {
				freq = bss->freq;
				wpa_printf(MSG_DEBUG, "P2P: Scan retry %d for "
					   "the peer " MACSTR " at %d MHz",
					   wpa_s->auto_pd_scan_retry,
					   MAC2STR(wpa_s->
						   pending_join_dev_addr),
					   freq);
				wpas_p2p_join_scan_req(wpa_s, freq, NULL, 0);
				return;
			}
		}

		if (join < 0)
			join = 0;

		wpa_s->p2p_auto_pd = 0;
		wpa_s->pending_pd_use = join ? AUTO_PD_JOIN : AUTO_PD_GO_NEG;
		wpa_printf(MSG_DEBUG, "P2P: Auto PD with " MACSTR " join=%d",
			   MAC2STR(wpa_s->pending_join_dev_addr), join);
		if (p2p_prov_disc_req(wpa_s->global->p2p,
				      wpa_s->pending_join_dev_addr, NULL,
				      wpa_s->pending_pd_config_methods, join,
				      0, wpa_s->user_initiated_pd) < 0) {
			wpa_s->p2p_auto_pd = 0;
			wpa_msg_global(wpa_s, MSG_INFO,
				       P2P_EVENT_PROV_DISC_FAILURE
				       " p2p_dev_addr=" MACSTR " status=N/A",
				       MAC2STR(wpa_s->pending_join_dev_addr));
		}
		return;
	}

	if (wpa_s->p2p_auto_join) {
		int join = wpas_p2p_peer_go(wpa_s,
					    wpa_s->pending_join_dev_addr);
		if (join < 0) {
			wpa_printf(MSG_DEBUG, "P2P: Peer was not found to be "
				   "running a GO -> use GO Negotiation");
			wpa_msg_global(wpa_s->p2pdev, MSG_INFO,
				       P2P_EVENT_FALLBACK_TO_GO_NEG
				       "reason=peer-not-running-GO");
			wpas_p2p_connect(wpa_s, wpa_s->pending_join_dev_addr,
					 wpa_s->p2p_pin, wpa_s->p2p_wps_method,
					 wpa_s->p2p_persistent_group, 0, 0, 0,
					 wpa_s->p2p_go_intent,
					 wpa_s->p2p_connect_freq,
					 wpa_s->p2p_go_vht_center_freq2,
					 wpa_s->p2p_persistent_id,
					 wpa_s->p2p_pd_before_go_neg,
					 wpa_s->p2p_go_ht40,
					 wpa_s->p2p_go_vht,
					 wpa_s->p2p_go_max_oper_chwidth,
					 wpa_s->p2p_go_he,
					 wpa_s->p2p_go_edmg,
					 NULL, 0,
					 is_p2p_allow_6ghz(wpa_s->global->p2p));
			return;
		}

		wpa_printf(MSG_DEBUG, "P2P: Peer was found running GO%s -> "
			   "try to join the group", join ? "" :
			   " in older scan");
		if (!join) {
			wpa_msg_global(wpa_s->p2pdev, MSG_INFO,
				       P2P_EVENT_FALLBACK_TO_GO_NEG_ENABLED);
			wpa_s->p2p_fallback_to_go_neg = 1;
		}
	}

	freq = p2p_get_oper_freq(wpa_s->global->p2p,
				 wpa_s->pending_join_iface_addr);
	if (freq < 0 &&
	    p2p_get_interface_addr(wpa_s->global->p2p,
				   wpa_s->pending_join_dev_addr,
				   iface_addr) == 0 &&
	    os_memcmp(iface_addr, wpa_s->pending_join_dev_addr, ETH_ALEN) != 0
	    && !wpa_bss_get_bssid(wpa_s, wpa_s->pending_join_iface_addr)) {
		wpa_printf(MSG_DEBUG, "P2P: Overwrite pending interface "
			   "address for join from " MACSTR " to " MACSTR
			   " based on newly discovered P2P peer entry",
			   MAC2STR(wpa_s->pending_join_iface_addr),
			   MAC2STR(iface_addr));
		os_memcpy(wpa_s->pending_join_iface_addr, iface_addr,
			  ETH_ALEN);

		freq = p2p_get_oper_freq(wpa_s->global->p2p,
					 wpa_s->pending_join_iface_addr);
	}
	if (freq >= 0) {
		wpa_printf(MSG_DEBUG, "P2P: Target GO operating frequency "
			   "from P2P peer table: %d MHz", freq);
	}
	if (wpa_s->p2p_join_ssid_len) {
		wpa_printf(MSG_DEBUG, "P2P: Trying to find target GO BSS entry based on BSSID "
			   MACSTR " and SSID %s",
			   MAC2STR(wpa_s->pending_join_iface_addr),
			   wpa_ssid_txt(wpa_s->p2p_join_ssid,
					wpa_s->p2p_join_ssid_len));
		bss = wpa_bss_get(wpa_s, wpa_s->pending_join_iface_addr,
				  wpa_s->p2p_join_ssid,
				  wpa_s->p2p_join_ssid_len);
	} else if (!bss) {
		wpa_printf(MSG_DEBUG, "P2P: Trying to find target GO BSS entry based on BSSID "
			   MACSTR, MAC2STR(wpa_s->pending_join_iface_addr));
		bss = wpa_bss_get_bssid_latest(wpa_s,
					       wpa_s->pending_join_iface_addr);
	}
	if (bss) {
		u8 dev_addr[ETH_ALEN];

		freq = bss->freq;
		wpa_printf(MSG_DEBUG, "P2P: Target GO operating frequency "
			   "from BSS table: %d MHz (SSID %s)", freq,
			   wpa_ssid_txt(bss->ssid, bss->ssid_len));
		if (p2p_parse_dev_addr(wpa_bss_ie_ptr(bss), bss->ie_len,
				       dev_addr) == 0 &&
		    os_memcmp(wpa_s->pending_join_dev_addr,
			      wpa_s->pending_join_iface_addr, ETH_ALEN) == 0 &&
		    os_memcmp(dev_addr, wpa_s->pending_join_dev_addr,
			      ETH_ALEN) != 0) {
			wpa_printf(MSG_DEBUG,
				   "P2P: Update target GO device address based on BSS entry: " MACSTR " (was " MACSTR ")",
				   MAC2STR(dev_addr),
				   MAC2STR(wpa_s->pending_join_dev_addr));
			os_memcpy(wpa_s->pending_join_dev_addr, dev_addr,
				  ETH_ALEN);
		}
	}
	if (freq > 0) {
		u16 method;

		if (wpas_check_freq_conflict(wpa_s, freq) > 0) {
			wpa_msg_global(wpa_s->p2pdev, MSG_INFO,
				       P2P_EVENT_GROUP_FORMATION_FAILURE
				       "reason=FREQ_CONFLICT");
			wpas_notify_p2p_group_formation_failure(
				wpa_s, "FREQ_CONFLICT");
			return;
		}

		wpa_printf(MSG_DEBUG, "P2P: Send Provision Discovery Request "
			   "prior to joining an existing group (GO " MACSTR
			   " freq=%u MHz)",
			   MAC2STR(wpa_s->pending_join_dev_addr), freq);
		wpa_s->pending_pd_before_join = 1;

		switch (wpa_s->pending_join_wps_method) {
		case WPS_PIN_DISPLAY:
			method = WPS_CONFIG_KEYPAD;
			break;
		case WPS_PIN_KEYPAD:
			method = WPS_CONFIG_DISPLAY;
			break;
		case WPS_PBC:
			method = WPS_CONFIG_PUSHBUTTON;
			break;
		case WPS_P2PS:
			method = WPS_CONFIG_P2PS;
			break;
		default:
			method = 0;
			break;
		}

		if ((p2p_get_provisioning_info(wpa_s->global->p2p,
					       wpa_s->pending_join_dev_addr) ==
		     method)) {
			/*
			 * We have already performed provision discovery for
			 * joining the group. Proceed directly to join
			 * operation without duplicated provision discovery. */
			wpa_printf(MSG_DEBUG, "P2P: Provision discovery "
				   "with " MACSTR " already done - proceed to "
				   "join",
				   MAC2STR(wpa_s->pending_join_dev_addr));
			wpa_s->pending_pd_before_join = 0;
			goto start;
		}

		if (p2p_prov_disc_req(wpa_s->global->p2p,
				      wpa_s->pending_join_dev_addr,
				      NULL, method, 1,
				      freq, wpa_s->user_initiated_pd) < 0) {
			wpa_printf(MSG_DEBUG, "P2P: Failed to send Provision "
				   "Discovery Request before joining an "
				   "existing group");
			wpa_s->pending_pd_before_join = 0;
			goto start;
		}
		return;
	}

	wpa_printf(MSG_DEBUG, "P2P: Failed to find BSS/GO - try again later");
	eloop_cancel_timeout(wpas_p2p_join_scan, wpa_s, NULL);
	eloop_register_timeout(1, 0, wpas_p2p_join_scan, wpa_s, NULL);
	wpas_p2p_check_join_scan_limit(wpa_s);
	return;

start:
	/* Start join operation immediately */
	wpas_p2p_join_start(wpa_s, 0, wpa_s->p2p_join_ssid,
			    wpa_s->p2p_join_ssid_len);
}


static void wpas_p2p_join_scan_req(struct wpa_supplicant *wpa_s, int freq,
				   const u8 *ssid, size_t ssid_len)
{
	int ret;
	struct wpa_driver_scan_params params;
	struct wpabuf *wps_ie, *ies;
	size_t ielen;
	int freqs[2] = { 0, 0 };
	unsigned int bands;

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

	/* P2P Wildcard SSID */
	params.num_ssids = 1;
	if (ssid && ssid_len) {
		params.ssids[0].ssid = ssid;
		params.ssids[0].ssid_len = ssid_len;
		os_memcpy(wpa_s->p2p_join_ssid, ssid, ssid_len);
		wpa_s->p2p_join_ssid_len = ssid_len;
	} else {
		params.ssids[0].ssid = (u8 *) P2P_WILDCARD_SSID;
		params.ssids[0].ssid_len = P2P_WILDCARD_SSID_LEN;
		wpa_s->p2p_join_ssid_len = 0;
	}

	wpa_s->wps->dev.p2p = 1;
	wps_ie = wps_build_probe_req_ie(DEV_PW_DEFAULT, &wpa_s->wps->dev,
					wpa_s->wps->uuid, WPS_REQ_ENROLLEE, 0,
					NULL);
	if (wps_ie == NULL) {
		wpas_p2p_scan_res_join(wpa_s, NULL);
		return;
	}

	if (!freq) {
		int oper_freq;
		/*
		 * If freq is not provided, check the operating freq of the GO
		 * and use a single channel scan on if possible.
		 */
		oper_freq = p2p_get_oper_freq(wpa_s->global->p2p,
					      wpa_s->pending_join_iface_addr);
		if (oper_freq > 0)
			freq = oper_freq;
	}
	if (freq > 0) {
		freqs[0] = freq;
		params.freqs = freqs;
	} else if (wpa_s->conf->p2p_6ghz_disable ||
		   !is_p2p_allow_6ghz(wpa_s->global->p2p)) {
		wpa_printf(MSG_DEBUG,
			   "P2P: 6 GHz disabled - update the scan frequency list");
		wpa_add_scan_freqs_list(wpa_s, HOSTAPD_MODE_IEEE80211G, &params,
					0);
		wpa_add_scan_freqs_list(wpa_s, HOSTAPD_MODE_IEEE80211A, &params,
					0);
	}

	ielen = p2p_scan_ie_buf_len(wpa_s->global->p2p);
	ies = wpabuf_alloc(wpabuf_len(wps_ie) + ielen);
	if (ies == NULL) {
		wpabuf_free(wps_ie);
		wpas_p2p_scan_res_join(wpa_s, NULL);
		return;
	}
	wpabuf_put_buf(ies, wps_ie);
	wpabuf_free(wps_ie);

	bands = wpas_get_bands(wpa_s, freqs);
	p2p_scan_ie(wpa_s->global->p2p, ies, NULL, bands);

	params.p2p_probe = 1;
	params.extra_ies = wpabuf_head(ies);
	params.extra_ies_len = wpabuf_len(ies);

	if (wpa_s->clear_driver_scan_cache) {
		wpa_printf(MSG_DEBUG,
			   "Request driver to clear scan cache due to local BSS flush");
		params.only_new_results = 1;
	}

	/*
	 * Run a scan to update BSS table and start Provision Discovery once
	 * the new scan results become available.
	 */
	ret = wpa_drv_scan(wpa_s, &params);
	if (params.freqs != freqs)
		os_free(params.freqs);
	if (!ret) {
		os_get_reltime(&wpa_s->scan_trigger_time);
		wpa_s->scan_res_handler = wpas_p2p_scan_res_join;
		wpa_s->own_scan_requested = 1;
		wpa_s->clear_driver_scan_cache = 0;
	}

	wpabuf_free(ies);

	if (ret) {
		wpa_printf(MSG_DEBUG, "P2P: Failed to start scan for join - "
			   "try again later");
		eloop_cancel_timeout(wpas_p2p_join_scan, wpa_s, NULL);
		eloop_register_timeout(1, 0, wpas_p2p_join_scan, wpa_s, NULL);
		wpas_p2p_check_join_scan_limit(wpa_s);
	}
}


static void wpas_p2p_join_scan(void *eloop_ctx, void *timeout_ctx)
{
	struct wpa_supplicant *wpa_s = eloop_ctx;
	wpas_p2p_join_scan_req(wpa_s, 0, NULL, 0);
}


static int wpas_p2p_join(struct wpa_supplicant *wpa_s, const u8 *iface_addr,
			 const u8 *dev_addr, enum p2p_wps_method wps_method,
			 int auto_join, int op_freq,
			 const u8 *ssid, size_t ssid_len)
{
	wpa_printf(MSG_DEBUG, "P2P: Request to join existing group (iface "
		   MACSTR " dev " MACSTR " op_freq=%d)%s",
		   MAC2STR(iface_addr), MAC2STR(dev_addr), op_freq,
		   auto_join ? " (auto_join)" : "");
	if (ssid && ssid_len) {
		wpa_printf(MSG_DEBUG, "P2P: Group SSID specified: %s",
			   wpa_ssid_txt(ssid, ssid_len));
	}

	wpa_s->p2p_auto_pd = 0;
	wpa_s->p2p_auto_join = !!auto_join;
	os_memcpy(wpa_s->pending_join_iface_addr, iface_addr, ETH_ALEN);
	os_memcpy(wpa_s->pending_join_dev_addr, dev_addr, ETH_ALEN);
	wpa_s->pending_join_wps_method = wps_method;

	/* Make sure we are not running find during connection establishment */
	wpas_p2p_stop_find(wpa_s);

	wpa_s->p2p_join_scan_count = 0;
	wpas_p2p_join_scan_req(wpa_s, op_freq, ssid, ssid_len);
	return 0;
}


static int wpas_p2p_join_start(struct wpa_supplicant *wpa_s, int freq,
			       const u8 *ssid, size_t ssid_len)
{
	struct wpa_supplicant *group;
	struct p2p_go_neg_results res;
	struct wpa_bss *bss;

	group = wpas_p2p_get_group_iface(wpa_s, 0, 0);
	if (group == NULL)
		return -1;
	if (group != wpa_s) {
		os_memcpy(group->p2p_pin, wpa_s->p2p_pin,
			  sizeof(group->p2p_pin));
		group->p2p_wps_method = wpa_s->p2p_wps_method;
	}

	/*
	 * Need to mark the current interface for p2p_group_formation
	 * when a separate group interface is not used. This is needed
	 * to allow p2p_cancel stop a pending p2p_connect-join.
	 * wpas_p2p_init_group_interface() addresses this for the case
	 * where a separate group interface is used.
	 */
	if (group == wpa_s->parent)
		wpa_s->global->p2p_group_formation = group;

	group->p2p_in_provisioning = 1;
	group->p2p_fallback_to_go_neg = wpa_s->p2p_fallback_to_go_neg;

	os_memset(&res, 0, sizeof(res));
	os_memcpy(res.peer_device_addr, wpa_s->pending_join_dev_addr, ETH_ALEN);
	os_memcpy(res.peer_interface_addr, wpa_s->pending_join_iface_addr,
		  ETH_ALEN);
	res.wps_method = wpa_s->pending_join_wps_method;
	if (freq && ssid && ssid_len) {
		res.freq = freq;
		res.ssid_len = ssid_len;
		os_memcpy(res.ssid, ssid, ssid_len);
	} else {
		if (ssid && ssid_len) {
			bss = wpa_bss_get(wpa_s, wpa_s->pending_join_iface_addr,
					  ssid, ssid_len);
		} else {
			bss = wpa_bss_get_bssid_latest(
				wpa_s, wpa_s->pending_join_iface_addr);
		}
		if (bss) {
			res.freq = bss->freq;
			res.ssid_len = bss->ssid_len;
			os_memcpy(res.ssid, bss->ssid, bss->ssid_len);
			wpa_printf(MSG_DEBUG, "P2P: Join target GO operating frequency from BSS table: %d MHz (SSID %s)",
				   bss->freq,
				   wpa_ssid_txt(bss->ssid, bss->ssid_len));
		} else if (ssid && ssid_len) {
			res.ssid_len = ssid_len;
			os_memcpy(res.ssid, ssid, ssid_len);
			wpa_printf(MSG_DEBUG, "P2P: Join target GO (SSID %s)",
				   wpa_ssid_txt(ssid, ssid_len));
		}
	}

	if (wpa_s->off_channel_freq || wpa_s->roc_waiting_drv_freq) {
		wpa_printf(MSG_DEBUG, "P2P: Cancel remain-on-channel prior to "
			   "starting client");
		wpa_drv_cancel_remain_on_channel(wpa_s);
		wpa_s->off_channel_freq = 0;
		wpa_s->roc_waiting_drv_freq = 0;
	}
	wpas_start_wps_enrollee(group, &res);

	/*
	 * Allow a longer timeout for join-a-running-group than normal 15
	 * second group formation timeout since the GO may not have authorized
	 * our connection yet.
	 */
	eloop_cancel_timeout(wpas_p2p_group_formation_timeout, wpa_s, NULL);
	eloop_register_timeout(60, 0, wpas_p2p_group_formation_timeout,
			       wpa_s, NULL);

	return 0;
}


static int wpas_p2p_setup_freqs(struct wpa_supplicant *wpa_s, int freq,
				int *force_freq, int *pref_freq, int go,
				unsigned int *pref_freq_list,
				unsigned int *num_pref_freq)
{
	struct wpa_used_freq_data *freqs;
	int res, best_freq, num_unused;
	unsigned int freq_in_use = 0, num, i, max_pref_freq;
	int p2p_pref_freq;

	max_pref_freq = *num_pref_freq;
	*num_pref_freq = 0;

	freqs = os_calloc(wpa_s->num_multichan_concurrent,
			  sizeof(struct wpa_used_freq_data));
	if (!freqs)
		return -1;

	num = wpas_p2p_valid_oper_freqs(wpa_s, freqs,
					wpa_s->num_multichan_concurrent);

	/*
	 * It is possible that the total number of used frequencies is bigger
	 * than the number of frequencies used for P2P, so get the system wide
	 * number of unused frequencies.
	 */
	num_unused = wpas_p2p_num_unused_channels(wpa_s);

	wpa_printf(MSG_DEBUG,
		   "P2P: Setup freqs: freq=%d num_MCC=%d shared_freqs=%u num_unused=%d",
		   freq, wpa_s->num_multichan_concurrent, num, num_unused);

	if (freq > 0) {
		int ret;
		if (go)
			ret = p2p_supported_freq(wpa_s->global->p2p, freq);
		else
			ret = p2p_supported_freq_cli(wpa_s->global->p2p, freq);
		if (!ret) {
			if ((wpa_s->drv_flags & WPA_DRIVER_FLAGS_DFS_OFFLOAD) &&
			    ieee80211_is_dfs(freq, wpa_s->hw.modes,
					     wpa_s->hw.num_modes)) {
				/*
				 * If freq is a DFS channel and DFS is offloaded
				 * to the driver, allow P2P GO to use it.
				 */
				wpa_printf(MSG_DEBUG,
					   "P2P: The forced channel for GO (%u MHz) is DFS, and DFS is offloaded to the driver",
					   freq);
			} else {
				wpa_printf(MSG_DEBUG,
					   "P2P: The forced channel (%u MHz) is not supported for P2P uses",
					   freq);
				res = -3;
				goto exit_free;
			}
		}

		for (i = 0; i < num; i++) {
			if (freqs[i].freq == freq)
				freq_in_use = 1;
		}

		if (num_unused <= 0 && !freq_in_use) {
			wpa_printf(MSG_DEBUG, "P2P: Cannot start P2P group on %u MHz as there are no available channels",
				   freq);
			res = -2;
			goto exit_free;
		}
		wpa_printf(MSG_DEBUG, "P2P: Trying to force us to use the "
			   "requested channel (%u MHz)", freq);
		*force_freq = freq;
		goto exit_ok;
	}

	best_freq = wpas_p2p_pick_best_used_freq(wpa_s, freqs, num);

	if (*pref_freq == 0) {
		if (wpa_s->conf->num_p2p_pref_chan && IS_2GHZ(best_freq)) {
			i = 0;
			while (i < wpa_s->conf->num_p2p_pref_chan) {
				p2p_pref_freq = ieee80211_chan_to_freq(NULL,
					wpa_s->conf->p2p_pref_chan[i].op_class,
					wpa_s->conf->p2p_pref_chan[i].chan);

				if (p2p_supported_freq(wpa_s->global->p2p, p2p_pref_freq) &&
					!wpas_p2p_disallowed_freq(wpa_s->global, p2p_pref_freq)) {
					best_freq = p2p_pref_freq;
					wpa_printf(MSG_DEBUG, "P2P: Using frequency (%u MHz) "
						"from P2P preferred channel list", best_freq);
					break;
				} else {
					wpa_printf(MSG_MSGDUMP, "P2P: Skipping preferred "
						"frequency (%u MHz) ", p2p_pref_freq);
				}
				i++;
			}
		} else if (!wpa_s->conf->num_p2p_pref_chan) {
			enum wpa_driver_if_type iface_type;

			if (go)
				iface_type = WPA_IF_P2P_GO;
			else
				iface_type = WPA_IF_P2P_CLIENT;

			wpa_printf(MSG_DEBUG, "P2P: best_freq=%d, go=%d",
				best_freq, go);

			res = wpa_drv_get_pref_freq_list(wpa_s, iface_type,
						 &max_pref_freq,
						 pref_freq_list);
			if (!res && max_pref_freq > 0) {
				*num_pref_freq = max_pref_freq;
				i = 0;
				while (i < *num_pref_freq &&
					(!p2p_supported_freq(wpa_s->global->p2p,
						pref_freq_list[i]) ||
					wpas_p2p_disallowed_freq(wpa_s->global,
							pref_freq_list[i]))) {
					wpa_printf(MSG_DEBUG,
						"P2P: preferred_freq_list[%d]=%d is disallowed",
						i, pref_freq_list[i]);
					i++;
				}
				if (i != *num_pref_freq) {
					best_freq = pref_freq_list[i];
					wpa_printf(MSG_DEBUG,
						"P2P: Using preferred_freq_list[%d]=%d",
						i, best_freq);
				} else {
					wpa_printf(MSG_DEBUG,
						"P2P: All driver preferred frequencies are "
						"disallowed for P2P use");
					*num_pref_freq = 0;
				}
			} else {
				wpa_printf(MSG_DEBUG,
					"P2P: No preferred frequency list available");
			}
		}
	}

	/* We have a candidate frequency to use */
	if (best_freq > 0) {
		if (*pref_freq == 0 && num_unused > 0) {
			wpa_printf(MSG_DEBUG, "P2P: Try to prefer a frequency (%u MHz) we are already using",
				   best_freq);
			*pref_freq = best_freq;
		} else {
			wpa_printf(MSG_DEBUG, "P2P: Try to force us to use frequency (%u MHz) which is already in use",
				   best_freq);
			*force_freq = best_freq;
		}
	} else if (num_unused > 0) {
		wpa_printf(MSG_DEBUG,
			   "P2P: Current operating channels are not available for P2P. Try to use another channel");
		*force_freq = 0;
	} else {
		wpa_printf(MSG_DEBUG,
			   "P2P: All channels are in use and none of them are P2P enabled. Cannot start P2P group");
		res = -2;
		goto exit_free;
	}

exit_ok:
	res = 0;
exit_free:
	os_free(freqs);
	return res;
}


static bool is_p2p_6ghz_supported(struct wpa_supplicant *wpa_s,
				  const u8 *peer_addr)
{
	if (wpa_s->conf->p2p_6ghz_disable ||
	    !get_mode(wpa_s->hw.modes, wpa_s->hw.num_modes,
		      HOSTAPD_MODE_IEEE80211A, true))
		return false;

	if (!p2p_wfd_enabled(wpa_s->global->p2p))
		return false;
	if (peer_addr && !p2p_peer_wfd_enabled(wpa_s->global->p2p, peer_addr))
		return false;

	return true;
}


static int wpas_p2p_check_6ghz(struct wpa_supplicant *wpa_s,
			       const u8 *peer_addr, bool allow_6ghz, int freq)
{
	if (allow_6ghz && is_p2p_6ghz_supported(wpa_s, peer_addr)) {
		wpa_printf(MSG_DEBUG,
			   "P2P: Allow connection on 6 GHz channels");
		p2p_set_6ghz_dev_capab(wpa_s->global->p2p, true);
	} else {
		if (is_6ghz_freq(freq))
			return -2;
		p2p_set_6ghz_dev_capab(wpa_s->global->p2p, false);
	}

	return 0;
}


/**
 * wpas_p2p_connect - Request P2P Group Formation to be started
 * @wpa_s: Pointer to wpa_supplicant data from wpa_supplicant_add_iface()
 * @peer_addr: Address of the peer P2P Device
 * @pin: PIN to use during provisioning or %NULL to indicate PBC mode
 * @persistent_group: Whether to create a persistent group
 * @auto_join: Whether to select join vs. GO Negotiation automatically
 * @join: Whether to join an existing group (as a client) instead of starting
 *	Group Owner negotiation; @peer_addr is BSSID in that case
 * @auth: Whether to only authorize the connection instead of doing that and
 *	initiating Group Owner negotiation
 * @go_intent: GO Intent or -1 to use default
 * @freq: Frequency for the group or 0 for auto-selection
 * @freq2: Center frequency of segment 1 for the GO operating in VHT 80P80 mode
 * @persistent_id: Persistent group credentials to use for forcing GO
 *	parameters or -1 to generate new values (SSID/passphrase)
 * @pd: Whether to send Provision Discovery prior to GO Negotiation as an
 *	interoperability workaround when initiating group formation
 * @ht40: Start GO with 40 MHz channel width
 * @vht:  Start GO with VHT support
 * @vht_chwidth: Channel width supported by GO operating with VHT support
 *	(CHANWIDTH_*).
 * @group_ssid: Specific Group SSID for join or %NULL if not set
 * @group_ssid_len: Length of @group_ssid in octets
 * @allow_6ghz: Allow P2P connection on 6 GHz channels
 * Returns: 0 or new PIN (if pin was %NULL) on success, -1 on unspecified
 *	failure, -2 on failure due to channel not currently available,
 *	-3 if forced channel is not supported
 */
int wpas_p2p_connect(struct wpa_supplicant *wpa_s, const u8 *peer_addr,
		     const char *pin, enum p2p_wps_method wps_method,
		     int persistent_group, int auto_join, int join, int auth,
		     int go_intent, int freq, unsigned int vht_center_freq2,
		     int persistent_id, int pd, int ht40, int vht,
		     unsigned int vht_chwidth, int he, int edmg,
		     const u8 *group_ssid, size_t group_ssid_len,
		     bool allow_6ghz)
{
	int force_freq = 0, pref_freq = 0;
	int ret = 0, res;
	enum wpa_driver_if_type iftype;
	const u8 *if_addr;
	struct wpa_ssid *ssid = NULL;
	unsigned int pref_freq_list[P2P_MAX_PREF_CHANNELS], size;

	if (wpa_s->global->p2p_disabled || wpa_s->global->p2p == NULL)
		return -1;

	if (persistent_id >= 0) {
		ssid = wpa_config_get_network(wpa_s->conf, persistent_id);
		if (ssid == NULL || ssid->disabled != 2 ||
		    ssid->mode != WPAS_MODE_P2P_GO)
			return -1;
	}

	if (wpas_p2p_check_6ghz(wpa_s, peer_addr, allow_6ghz, freq))
		return -2;

	os_free(wpa_s->global->add_psk);
	wpa_s->global->add_psk = NULL;

	wpa_s->global->p2p_fail_on_wps_complete = 0;
	wpa_s->global->pending_p2ps_group = 0;
	wpa_s->global->pending_p2ps_group_freq = 0;
	wpa_s->p2ps_method_config_any = 0;

	if (go_intent < 0)
		go_intent = wpa_s->conf->p2p_go_intent;

	if (!auth)
		wpa_s->global->p2p_long_listen = 0;

	wpa_s->p2p_wps_method = wps_method;
	wpa_s->p2p_persistent_group = !!persistent_group;
	wpa_s->p2p_persistent_id = persistent_id;
	wpa_s->p2p_go_intent = go_intent;
	wpa_s->p2p_connect_freq = freq;
	wpa_s->p2p_fallback_to_go_neg = 0;
	wpa_s->p2p_pd_before_go_neg = !!pd;
	wpa_s->p2p_go_ht40 = !!ht40;
	wpa_s->p2p_go_vht = !!vht;
	wpa_s->p2p_go_vht_center_freq2 = vht_center_freq2;
	wpa_s->p2p_go_max_oper_chwidth = vht_chwidth;
	wpa_s->p2p_go_he = !!he;
	wpa_s->p2p_go_edmg = !!edmg;

	if (pin)
		os_strlcpy(wpa_s->p2p_pin, pin, sizeof(wpa_s->p2p_pin));
	else if (wps_method == WPS_PIN_DISPLAY) {
		if (wps_generate_pin((unsigned int *) &ret) < 0)
			return -1;
		res = os_snprintf(wpa_s->p2p_pin, sizeof(wpa_s->p2p_pin),
				  "%08d", ret);
		if (os_snprintf_error(sizeof(wpa_s->p2p_pin), res))
			wpa_s->p2p_pin[sizeof(wpa_s->p2p_pin) - 1] = '\0';
		wpa_printf(MSG_DEBUG, "P2P: Randomly generated PIN: %s",
			   wpa_s->p2p_pin);
	} else if (wps_method == WPS_P2PS) {
		/* Force the P2Ps default PIN to be used */
		os_strlcpy(wpa_s->p2p_pin, "12345670", sizeof(wpa_s->p2p_pin));
	} else
		wpa_s->p2p_pin[0] = '\0';

	if (join || auto_join) {
		u8 iface_addr[ETH_ALEN], dev_addr[ETH_ALEN];
		if (auth) {
			wpa_printf(MSG_DEBUG, "P2P: Authorize invitation to "
				   "connect a running group from " MACSTR,
				   MAC2STR(peer_addr));
			os_memcpy(wpa_s->p2p_auth_invite, peer_addr, ETH_ALEN);
			return ret;
		}
		os_memcpy(dev_addr, peer_addr, ETH_ALEN);
		if (p2p_get_interface_addr(wpa_s->global->p2p, peer_addr,
					   iface_addr) < 0) {
			os_memcpy(iface_addr, peer_addr, ETH_ALEN);
			p2p_get_dev_addr(wpa_s->global->p2p, peer_addr,
					 dev_addr);
		}
		if (auto_join) {
			os_get_reltime(&wpa_s->p2p_auto_started);
			wpa_printf(MSG_DEBUG, "P2P: Auto join started at "
				   "%ld.%06ld",
				   wpa_s->p2p_auto_started.sec,
				   wpa_s->p2p_auto_started.usec);
		}
		wpa_s->user_initiated_pd = 1;
		if (wpas_p2p_join(wpa_s, iface_addr, dev_addr, wps_method,
				  auto_join, freq,
				  group_ssid, group_ssid_len) < 0)
			return -1;
		return ret;
	}

	size = P2P_MAX_PREF_CHANNELS;
	res = wpas_p2p_setup_freqs(wpa_s, freq, &force_freq, &pref_freq,
				   go_intent == 15, pref_freq_list, &size);
	if (res)
		return res;
	wpas_p2p_set_own_freq_preference(wpa_s,
					 force_freq ? force_freq : pref_freq);

	p2p_set_own_pref_freq_list(wpa_s->global->p2p, pref_freq_list, size);

	wpa_s->create_p2p_iface = wpas_p2p_create_iface(wpa_s);

	if (wpa_s->create_p2p_iface) {
		/* Prepare to add a new interface for the group */
		iftype = WPA_IF_P2P_GROUP;
		if (go_intent == 15)
			iftype = WPA_IF_P2P_GO;
		if (wpas_p2p_add_group_interface(wpa_s, iftype) < 0) {
			wpa_printf(MSG_ERROR, "P2P: Failed to allocate a new "
				   "interface for the group");
			return -1;
		}

		if_addr = wpa_s->pending_interface_addr;
	} else {
		if (wpa_s->p2p_mgmt)
			if_addr = wpa_s->parent->own_addr;
		else
			if_addr = wpa_s->own_addr;
		os_memset(wpa_s->go_dev_addr, 0, ETH_ALEN);
	}

	if (auth) {
		if (wpas_p2p_auth_go_neg(wpa_s, peer_addr, wps_method,
					 go_intent, if_addr,
					 force_freq, persistent_group, ssid,
					 pref_freq) < 0)
			return -1;
		return ret;
	}

	if (wpas_p2p_start_go_neg(wpa_s, peer_addr, wps_method,
				  go_intent, if_addr, force_freq,
				  persistent_group, ssid, pref_freq) < 0) {
		if (wpa_s->create_p2p_iface)
			wpas_p2p_remove_pending_group_interface(wpa_s);
		return -1;
	}
	return ret;
}


/**
 * wpas_p2p_remain_on_channel_cb - Indication of remain-on-channel start
 * @wpa_s: Pointer to wpa_supplicant data from wpa_supplicant_add_iface()
 * @freq: Frequency of the channel in MHz
 * @duration: Duration of the stay on the channel in milliseconds
 *
 * This callback is called when the driver indicates that it has started the
 * requested remain-on-channel duration.
 */
void wpas_p2p_remain_on_channel_cb(struct wpa_supplicant *wpa_s,
				   unsigned int freq, unsigned int duration)
{
	if (wpa_s->global->p2p_disabled || wpa_s->global->p2p == NULL)
		return;
	wpa_printf(MSG_DEBUG, "P2P: remain-on-channel callback (off_channel_freq=%u pending_listen_freq=%d roc_waiting_drv_freq=%d freq=%u duration=%u)",
		   wpa_s->off_channel_freq, wpa_s->pending_listen_freq,
		   wpa_s->roc_waiting_drv_freq, freq, duration);
	if (wpa_s->off_channel_freq &&
	    wpa_s->off_channel_freq == wpa_s->pending_listen_freq) {
		p2p_listen_cb(wpa_s->global->p2p, wpa_s->pending_listen_freq,
			      wpa_s->pending_listen_duration);
		wpa_s->pending_listen_freq = 0;
	} else {
		wpa_printf(MSG_DEBUG, "P2P: Ignore remain-on-channel callback (off_channel_freq=%u pending_listen_freq=%d freq=%u duration=%u)",
			   wpa_s->off_channel_freq, wpa_s->pending_listen_freq,
			   freq, duration);
	}
}


int wpas_p2p_listen_start(struct wpa_supplicant *wpa_s, unsigned int timeout)
{
	/* Limit maximum Listen state time based on driver limitation. */
	if (timeout > wpa_s->max_remain_on_chan)
		timeout = wpa_s->max_remain_on_chan;

	return p2p_listen(wpa_s->global->p2p, timeout);
}


/**
 * wpas_p2p_cancel_remain_on_channel_cb - Remain-on-channel timeout
 * @wpa_s: Pointer to wpa_supplicant data from wpa_supplicant_add_iface()
 * @freq: Frequency of the channel in MHz
 *
 * This callback is called when the driver indicates that a remain-on-channel
 * operation has been completed, i.e., the duration on the requested channel
 * has timed out.
 */
void wpas_p2p_cancel_remain_on_channel_cb(struct wpa_supplicant *wpa_s,
					  unsigned int freq)
{
	wpa_printf(MSG_DEBUG, "P2P: Cancel remain-on-channel callback "
		   "(p2p_long_listen=%d ms pending_action_tx=%p)",
		   wpa_s->global->p2p_long_listen,
		   offchannel_pending_action_tx(wpa_s));
	wpas_p2p_listen_work_done(wpa_s);
	if (wpa_s->global->p2p_disabled || wpa_s->global->p2p == NULL)
		return;
	if (wpa_s->global->p2p_long_listen > 0)
		wpa_s->global->p2p_long_listen -= wpa_s->max_remain_on_chan;
	if (p2p_listen_end(wpa_s->global->p2p, freq) > 0)
		return; /* P2P module started a new operation */
	if (offchannel_pending_action_tx(wpa_s))
		return;
	if (wpa_s->global->p2p_long_listen > 0) {
		wpa_printf(MSG_DEBUG, "P2P: Continuing long Listen state");
		wpas_p2p_listen_start(wpa_s, wpa_s->global->p2p_long_listen);
	} else {
		/*
		 * When listen duration is over, stop listen & update p2p_state
		 * to IDLE.
		 */
		p2p_stop_listen(wpa_s->global->p2p);
	}
}


/**
 * wpas_p2p_group_remove - Remove a P2P group
 * @wpa_s: Pointer to wpa_supplicant data from wpa_supplicant_add_iface()
 * @ifname: Network interface name of the group interface or "*" to remove all
 *	groups
 * Returns: 0 on success, -1 on failure
 *
 * This function is used to remove a P2P group. This can be used to disconnect
 * from a group in which the local end is a P2P Client or to end a P2P Group in
 * case the local end is the Group Owner. If a virtual network interface was
 * created for this group, that interface will be removed. Otherwise, only the
 * configured P2P group network will be removed from the interface.
 */
int wpas_p2p_group_remove(struct wpa_supplicant *wpa_s, const char *ifname)
{
	struct wpa_global *global = wpa_s->global;
	struct wpa_supplicant *calling_wpa_s = wpa_s;

	if (os_strcmp(ifname, "*") == 0) {
		struct wpa_supplicant *prev;
		bool calling_wpa_s_group_removed = false;

		wpa_s = global->ifaces;
		while (wpa_s) {
			prev = wpa_s;
			wpa_s = wpa_s->next;
			if (prev->p2p_group_interface !=
			    NOT_P2P_GROUP_INTERFACE ||
			    (prev->current_ssid &&
			     prev->current_ssid->p2p_group)) {
				wpas_p2p_disconnect_safely(prev, calling_wpa_s);
				if (prev == calling_wpa_s)
					calling_wpa_s_group_removed = true;
			}
		}

		if (!calling_wpa_s_group_removed &&
		    (calling_wpa_s->p2p_group_interface !=
		     NOT_P2P_GROUP_INTERFACE ||
		     (calling_wpa_s->current_ssid &&
		      calling_wpa_s->current_ssid->p2p_group))) {
			wpa_printf(MSG_DEBUG, "Remove calling_wpa_s P2P group");
			wpas_p2p_disconnect_safely(calling_wpa_s,
						   calling_wpa_s);
		}

		return 0;
	}

	for (wpa_s = global->ifaces; wpa_s; wpa_s = wpa_s->next) {
		if (os_strcmp(wpa_s->ifname, ifname) == 0)
			break;
	}

	return wpas_p2p_disconnect_safely(wpa_s, calling_wpa_s);
}


static int wpas_p2p_select_go_freq(struct wpa_supplicant *wpa_s, int freq)
{
	unsigned int r;

	if (!wpa_s->conf->num_p2p_pref_chan && !freq) {
		unsigned int i, size = P2P_MAX_PREF_CHANNELS;
		unsigned int pref_freq_list[P2P_MAX_PREF_CHANNELS];
		int res;

		res = wpa_drv_get_pref_freq_list(wpa_s, WPA_IF_P2P_GO,
						 &size, pref_freq_list);
		if (!is_p2p_allow_6ghz(wpa_s->global->p2p))
			size = p2p_remove_6ghz_channels(pref_freq_list, size);

		if (!res && size > 0) {
			i = 0;
			while (i < size &&
			       (!p2p_supported_freq(wpa_s->global->p2p,
						    pref_freq_list[i]) ||
				wpas_p2p_disallowed_freq(wpa_s->global,
							 pref_freq_list[i]))) {
				wpa_printf(MSG_DEBUG,
					   "P2P: preferred_freq_list[%d]=%d is disallowed",
					   i, pref_freq_list[i]);
				i++;
			}
			if (i != size) {
				freq = pref_freq_list[i];
				wpa_printf(MSG_DEBUG,
					   "P2P: Using preferred_freq_list[%d]=%d",
					   i, freq);
			} else {
				wpa_printf(MSG_DEBUG,
					   "P2P: All driver preferred frequencies are disallowed for P2P use");
			}
		} else {
			wpa_printf(MSG_DEBUG,
				   "P2P: No preferred frequency list available");
		}
	}

	if (freq == 2) {
		wpa_printf(MSG_DEBUG, "P2P: Request to start GO on 2.4 GHz "
			   "band");
		if (wpa_s->best_24_freq > 0 &&
		    p2p_supported_freq_go(wpa_s->global->p2p,
					  wpa_s->best_24_freq)) {
			freq = wpa_s->best_24_freq;
			wpa_printf(MSG_DEBUG, "P2P: Use best 2.4 GHz band "
				   "channel: %d MHz", freq);
		} else {
			if (os_get_random((u8 *) &r, sizeof(r)) < 0)
				return -1;
			int possible_2g_freqs[] = {
				/* operating class 81 */
				2412, 2437, 2462,
			};
			int possible_2g_freqs_num =
			    sizeof(possible_2g_freqs)/sizeof(possible_2g_freqs[0]);
			int i;
			for (i = 0; i < possible_2g_freqs_num; i++, r++) {
				freq = possible_2g_freqs[r % possible_2g_freqs_num];
				if (p2p_supported_freq_go(wpa_s->global->p2p, freq)) {
					break;
				}
			}

			if (i >= possible_2g_freqs_num) {
				wpa_printf(MSG_DEBUG, "P2P: Could not select "
					   "2.4 GHz channel for P2P group");
				return -1;
			}
			wpa_printf(MSG_DEBUG, "P2P: Use random 2.4 GHz band "
				   "channel: %d MHz", freq);
		}
	}

	if (freq == 5) {
		wpa_printf(MSG_DEBUG, "P2P: Request to start GO on 5 GHz "
			   "band");
		if (wpa_s->best_5_freq > 0 &&
		    p2p_supported_freq_go(wpa_s->global->p2p,
				       wpa_s->best_5_freq)) {
			freq = wpa_s->best_5_freq;
			wpa_printf(MSG_DEBUG, "P2P: Use best 5 GHz band "
				   "channel: %d MHz", freq);
		} else {
			const int freqs[] = {
				/* operating class 115 */
				5180, 5200, 5220, 5240,
				/* operating class 124 */
				5745, 5765, 5785, 5805,
			};
			unsigned int i, num_freqs = ARRAY_SIZE(freqs);

			if (os_get_random((u8 *) &r, sizeof(r)) < 0)
				return -1;

			/*
			 * most of 5G channels are DFS, only operating class 115 and 124
			 * are available possibly, randomly pick a start to check them.
			 */
			int possible_5g_freqs[] = {
				/* operating class 115 */
				5180, 5200, 5220, 5240,
				/* operating class 124 */
				5745, 5765, 5785, 5805,
			};
			int possible_5g_freqs_num =
			    sizeof(possible_5g_freqs)/sizeof(possible_5g_freqs[0]);

			for (i = 0; i < possible_5g_freqs_num; i++, r++) {
				if (p2p_supported_freq_go(
				    wpa_s->global->p2p,
				    possible_5g_freqs[r % possible_5g_freqs_num])) {
					freq = possible_5g_freqs[r % possible_5g_freqs_num];
					break;
				}
			}

			if (i >= possible_5g_freqs_num) {
				wpa_printf(MSG_DEBUG, "P2P: Could not select "
					   "5 GHz channel for P2P group");
				return -1;
			}
			wpa_printf(MSG_DEBUG, "P2P: Use random 5 GHz band "
				   "channel: %d MHz", freq);
		}
	}

	if (freq > 0 && !p2p_supported_freq_go(wpa_s->global->p2p, freq)) {
		if ((wpa_s->drv_flags & WPA_DRIVER_FLAGS_DFS_OFFLOAD) &&
		    ieee80211_is_dfs(freq, wpa_s->hw.modes,
				     wpa_s->hw.num_modes)) {
			/*
			 * If freq is a DFS channel and DFS is offloaded to the
			 * driver, allow P2P GO to use it.
			 */
			wpa_printf(MSG_DEBUG, "P2P: "
				   "%s: The forced channel for GO (%u MHz) is DFS, and DFS is offloaded",
				   __func__, freq);
			return freq;
		}
		wpa_printf(MSG_DEBUG, "P2P: The forced channel for GO "
			   "(%u MHz) is not supported for P2P uses",
			   freq);
		return -1;
	}

	return freq;
}


static int wpas_p2p_supported_freq_go(struct wpa_supplicant *wpa_s,
				      const struct p2p_channels *channels,
				      int freq)
{
	if (!wpas_p2p_disallowed_freq(wpa_s->global, freq) &&
	    p2p_supported_freq_go(wpa_s->global->p2p, freq) &&
	    freq_included(wpa_s, channels, freq))
		return 1;
	return 0;
}


static void wpas_p2p_select_go_freq_no_pref(struct wpa_supplicant *wpa_s,
					    struct p2p_go_neg_results *params,
					    const struct p2p_channels *channels)
{
	unsigned int i, r;

	/* try all channels in operating class 115 */
	for (i = 0; i < 4; i++) {
		params->freq = 5180 + i * 20;
		if (wpas_p2p_supported_freq_go(wpa_s, channels, params->freq))
			goto out;
	}

	/* try all channels in operating class 124 */
	for (i = 0; i < 4; i++) {
		params->freq = 5745 + i * 20;
		if (wpas_p2p_supported_freq_go(wpa_s, channels, params->freq))
			goto out;
	}

	/* try social channel class 180 channel 2 */
	params->freq = 58320 + 1 * 2160;
	if (wpas_p2p_supported_freq_go(wpa_s, channels, params->freq))
		goto out;

	/* try all channels in reg. class 180 */
	for (i = 0; i < 4; i++) {
		params->freq = 58320 + i * 2160;
		if (wpas_p2p_supported_freq_go(wpa_s, channels, params->freq))
			goto out;
	}

	/* try some random selection of the social channels */
	if (os_get_random((u8 *) &r, sizeof(r)) < 0)
		return;

	for (i = 0; i < 3; i++) {
		params->freq = 2412 + ((r + i) % 3) * 25;
		if (wpas_p2p_supported_freq_go(wpa_s, channels, params->freq))
			goto out;
	}

	/* try all other channels in operating class 81 */
	for (i = 0; i < 11; i++) {
		params->freq = 2412 + i * 5;

		/* skip social channels; covered in the previous loop */
		if (params->freq == 2412 ||
		    params->freq == 2437 ||
		    params->freq == 2462)
			continue;

		if (wpas_p2p_supported_freq_go(wpa_s, channels, params->freq))
			goto out;
	}

	params->freq = 0;
	wpa_printf(MSG_DEBUG, "P2P: No 2.4, 5, or 60 GHz channel allowed");
	return;
out:
	wpa_printf(MSG_DEBUG, "P2P: Set GO freq %d MHz (no preference known)",
		   params->freq);
}


static int wpas_same_band(int freq1, int freq2)
{
	enum hostapd_hw_mode mode1, mode2;
	u8 chan1, chan2;

	mode1 = ieee80211_freq_to_chan(freq1, &chan1);
	mode2 = ieee80211_freq_to_chan(freq2, &chan2);
	if (mode1 == NUM_HOSTAPD_MODES)
		return 0;
	return mode1 == mode2;
}


static int wpas_p2p_init_go_params(struct wpa_supplicant *wpa_s,
				   struct p2p_go_neg_results *params,
				   int freq, int vht_center_freq2, int ht40,
				   int vht, int max_oper_chwidth, int he,
				   int edmg,
				   const struct p2p_channels *channels)
{
	struct wpa_used_freq_data *freqs;
	unsigned int cand;
	unsigned int num, i;
	int ignore_no_freqs = 0;
	int unused_channels = wpas_p2p_num_unused_channels(wpa_s) > 0;

	os_memset(params, 0, sizeof(*params));
	params->role_go = 1;
	params->ht40 = ht40;
	params->vht = vht;
	params->he = he;
	params->max_oper_chwidth = max_oper_chwidth;
	params->vht_center_freq2 = vht_center_freq2;
	params->edmg = edmg;

	freqs = os_calloc(wpa_s->num_multichan_concurrent,
			  sizeof(struct wpa_used_freq_data));
	if (!freqs)
		return -1;

	num = get_shared_radio_freqs_data(wpa_s, freqs,
					  wpa_s->num_multichan_concurrent);

	if (wpa_s->current_ssid &&
	    wpa_s->current_ssid->mode == WPAS_MODE_P2P_GO &&
	    wpa_s->wpa_state == WPA_COMPLETED) {
		wpa_printf(MSG_DEBUG, "P2P: %s called for an active GO",
			   __func__);

		/*
		 * If the frequency selection is done for an active P2P GO that
		 * is not sharing a frequency, allow to select a new frequency
		 * even if there are no unused frequencies as we are about to
		 * move the P2P GO so its frequency can be re-used.
		 */
		for (i = 0; i < num; i++) {
			if (freqs[i].freq == wpa_s->current_ssid->frequency &&
			    freqs[i].flags == 0) {
				ignore_no_freqs = 1;
				break;
			}
		}
	}

	/* Try to use EDMG channel */
	if (params->edmg) {
		if (wpas_p2p_try_edmg_channel(wpa_s, params) == 0)
			goto success;
		params->edmg = 0;
	}

	/* try using the forced freq */
	if (freq) {
		if (wpas_p2p_disallowed_freq(wpa_s->global, freq) ||
		    !freq_included(wpa_s, channels, freq)) {
			wpa_printf(MSG_DEBUG,
				   "P2P: Forced GO freq %d MHz disallowed",
				   freq);
			goto fail;
		}
		if (!p2p_supported_freq_go(wpa_s->global->p2p, freq)) {
			if ((wpa_s->drv_flags & WPA_DRIVER_FLAGS_DFS_OFFLOAD) &&
			    ieee80211_is_dfs(freq, wpa_s->hw.modes,
					     wpa_s->hw.num_modes)) {
				/*
				 * If freq is a DFS channel and DFS is offloaded
				 * to the driver, allow P2P GO to use it.
				 */
				wpa_printf(MSG_DEBUG,
					   "P2P: %s: The forced channel for GO (%u MHz) requires DFS and DFS is offloaded",
					   __func__, freq);
			} else {
				wpa_printf(MSG_DEBUG,
					   "P2P: The forced channel for GO (%u MHz) is not supported for P2P uses",
					   freq);
				goto fail;
			}
		}

		for (i = 0; i < num; i++) {
			if (freqs[i].freq == freq) {
				wpa_printf(MSG_DEBUG,
					   "P2P: forced freq (%d MHz) is also shared",
					   freq);
				params->freq = freq;
				goto success;
			}
		}

		if (!ignore_no_freqs && !unused_channels) {
			wpa_printf(MSG_DEBUG,
				   "P2P: Cannot force GO on freq (%d MHz) as all the channels are in use",
				   freq);
			goto fail;
		}

		wpa_printf(MSG_DEBUG,
			   "P2P: force GO freq (%d MHz) on a free channel",
			   freq);
		params->freq = freq;
		goto success;
	}

	/* consider using one of the shared frequencies */
	if (num &&
	    (!wpa_s->conf->p2p_ignore_shared_freq || !unused_channels)) {
		cand = wpas_p2p_pick_best_used_freq(wpa_s, freqs, num);
		if (wpas_p2p_supported_freq_go(wpa_s, channels, cand)) {
			wpa_printf(MSG_DEBUG,
				   "P2P: Use shared freq (%d MHz) for GO",
				   cand);
			params->freq = cand;
			goto success;
		}

		/* try using one of the shared freqs */
		for (i = 0; i < num; i++) {
			if (wpas_p2p_supported_freq_go(wpa_s, channels,
						       freqs[i].freq)) {
				wpa_printf(MSG_DEBUG,
					   "P2P: Use shared freq (%d MHz) for GO",
					   freqs[i].freq);
				params->freq = freqs[i].freq;
				goto success;
			}
		}
	}

	if (!ignore_no_freqs && !unused_channels) {
		wpa_printf(MSG_DEBUG,
			   "P2P: Cannot force GO on any of the channels we are already using");
		goto fail;
	}

	/* try using the setting from the configuration file */
	if (wpa_s->conf->p2p_oper_reg_class == 81 &&
	    wpa_s->conf->p2p_oper_channel >= 1 &&
	    wpa_s->conf->p2p_oper_channel <= 11 &&
	    wpas_p2p_supported_freq_go(
		    wpa_s, channels,
		    2407 + 5 * wpa_s->conf->p2p_oper_channel)) {
		params->freq = 2407 + 5 * wpa_s->conf->p2p_oper_channel;
		wpa_printf(MSG_DEBUG, "P2P: Set GO freq based on configured "
			   "frequency %d MHz", params->freq);
		goto success;
	}

	if ((wpa_s->conf->p2p_oper_reg_class == 115 ||
	     wpa_s->conf->p2p_oper_reg_class == 116 ||
	     wpa_s->conf->p2p_oper_reg_class == 117 ||
	     wpa_s->conf->p2p_oper_reg_class == 124 ||
	     wpa_s->conf->p2p_oper_reg_class == 125 ||
	     wpa_s->conf->p2p_oper_reg_class == 126 ||
	     wpa_s->conf->p2p_oper_reg_class == 127) &&
	    wpas_p2p_supported_freq_go(wpa_s, channels,
				       5000 +
				       5 * wpa_s->conf->p2p_oper_channel)) {
		params->freq = 5000 + 5 * wpa_s->conf->p2p_oper_channel;
		wpa_printf(MSG_DEBUG, "P2P: Set GO freq based on configured "
			   "frequency %d MHz", params->freq);
		goto success;
	}

	/* Try using best channels */
	if (wpa_s->conf->p2p_oper_channel == 0 &&
	    wpa_s->best_overall_freq > 0 &&
	    wpas_p2p_supported_freq_go(wpa_s, channels,
				       wpa_s->best_overall_freq)) {
		params->freq = wpa_s->best_overall_freq;
		wpa_printf(MSG_DEBUG, "P2P: Set GO freq based on best overall "
			   "channel %d MHz", params->freq);
		goto success;
	}

	if (wpa_s->conf->p2p_oper_channel == 0 &&
	    wpa_s->best_24_freq > 0 &&
	    wpas_p2p_supported_freq_go(wpa_s, channels,
				       wpa_s->best_24_freq)) {
		params->freq = wpa_s->best_24_freq;
		wpa_printf(MSG_DEBUG, "P2P: Set GO freq based on best 2.4 GHz "
			   "channel %d MHz", params->freq);
		goto success;
	}

	if (wpa_s->conf->p2p_oper_channel == 0 &&
	    wpa_s->best_5_freq > 0 &&
	    wpas_p2p_supported_freq_go(wpa_s, channels,
				       wpa_s->best_5_freq)) {
		params->freq = wpa_s->best_5_freq;
		wpa_printf(MSG_DEBUG, "P2P: Set GO freq based on best 5 GHz "
			   "channel %d MHz", params->freq);
		goto success;
	}

	/* try using preferred channels */
	cand = p2p_get_pref_freq(wpa_s->global->p2p, channels);
	if (cand && wpas_p2p_supported_freq_go(wpa_s, channels, cand)) {
		params->freq = cand;
		wpa_printf(MSG_DEBUG, "P2P: Set GO freq %d MHz from preferred "
			   "channels", params->freq);
		goto success;
	}

	/* Try using a channel that allows VHT to be used with 80 MHz */
	if (wpa_s->hw.modes && wpa_s->p2p_group_common_freqs) {
		for (i = 0; i < wpa_s->p2p_group_common_freqs_num; i++) {
			enum hostapd_hw_mode mode;
			struct hostapd_hw_modes *hwmode;
			u8 chan;
			u8 op_class;

			cand = wpa_s->p2p_group_common_freqs[i];
			op_class = is_6ghz_freq(cand) ? 133 : 128;
			mode = ieee80211_freq_to_chan(cand, &chan);
			hwmode = get_mode(wpa_s->hw.modes, wpa_s->hw.num_modes,
					  mode, is_6ghz_freq(cand));
			if (!hwmode ||
			    wpas_p2p_verify_channel(wpa_s, hwmode, op_class,
						    chan, BW80) != ALLOWED)
				continue;
			if (wpas_p2p_supported_freq_go(wpa_s, channels, cand)) {
				params->freq = cand;
				wpa_printf(MSG_DEBUG,
					   "P2P: Use freq %d MHz common with the peer and allowing VHT80",
					   params->freq);
				goto success;
			}
		}
	}

	/* Try using a channel that allows HT to be used with 40 MHz on the same
	 * band so that CSA can be used */
	if (wpa_s->current_ssid && wpa_s->hw.modes &&
	    wpa_s->p2p_group_common_freqs) {
		for (i = 0; i < wpa_s->p2p_group_common_freqs_num; i++) {
			enum hostapd_hw_mode mode;
			struct hostapd_hw_modes *hwmode;
			u8 chan, op_class;
			bool is_6ghz, supported = false;

			is_6ghz = is_6ghz_freq(cand);
			cand = wpa_s->p2p_group_common_freqs[i];
			mode = ieee80211_freq_to_chan(cand, &chan);
			hwmode = get_mode(wpa_s->hw.modes, wpa_s->hw.num_modes,
					  mode, is_6ghz);
			if (!wpas_same_band(wpa_s->current_ssid->frequency,
					    cand) ||
			    !hwmode)
				continue;
			if (is_6ghz &&
			    wpas_p2p_verify_channel(wpa_s, hwmode, 132, chan,
						    BW40) == ALLOWED)
				supported = true;

			if (!is_6ghz &&
			    ieee80211_freq_to_channel_ext(
				    cand, -1, CHANWIDTH_USE_HT, &op_class,
				    &chan) != NUM_HOSTAPD_MODES &&
			    wpas_p2p_verify_channel(
				    wpa_s, hwmode, op_class, chan,
				    BW40MINUS) == ALLOWED)
				supported = true;

			if (!supported && !is_6ghz &&
			    ieee80211_freq_to_channel_ext(
				    cand, 1, CHANWIDTH_USE_HT, &op_class,
				    &chan) != NUM_HOSTAPD_MODES &&
			    wpas_p2p_verify_channel(
				    wpa_s, hwmode, op_class, chan,
				    BW40PLUS) == ALLOWED)
				supported = true;

			if (!supported)
				continue;

			if (wpas_p2p_supported_freq_go(wpa_s, channels, cand)) {
				params->freq = cand;
				wpa_printf(MSG_DEBUG,
					   "P2P: Use freq %d MHz common with the peer, allowing HT40, and maintaining same band",
					   params->freq);
				goto success;
			}
		}
	}

	/* Try using one of the group common freqs on the same band so that CSA
	 * can be used */
	if (wpa_s->current_ssid && wpa_s->p2p_group_common_freqs) {
		for (i = 0; i < wpa_s->p2p_group_common_freqs_num; i++) {
			cand = wpa_s->p2p_group_common_freqs[i];
			if (!wpas_same_band(wpa_s->current_ssid->frequency,
					    cand))
				continue;
			if (wpas_p2p_supported_freq_go(wpa_s, channels, cand)) {
				params->freq = cand;
				wpa_printf(MSG_DEBUG,
					   "P2P: Use freq %d MHz common with the peer and maintaining same band",
					   params->freq);
				goto success;
			}
		}
	}

	/* Try using one of the group common freqs */
	if (wpa_s->p2p_group_common_freqs) {
		for (i = 0; i < wpa_s->p2p_group_common_freqs_num; i++) {
			cand = wpa_s->p2p_group_common_freqs[i];
			if (wpas_p2p_supported_freq_go(wpa_s, channels, cand)) {
				params->freq = cand;
				wpa_printf(MSG_DEBUG,
					   "P2P: Use freq %d MHz common with the peer",
					   params->freq);
				goto success;
			}
		}
	}

	/* no preference, select some channel */
	wpas_p2p_select_go_freq_no_pref(wpa_s, params, channels);

	if (params->freq == 0) {
		wpa_printf(MSG_DEBUG, "P2P: did not find a freq for GO use");
		goto fail;
	}

success:
	os_free(freqs);
	return 0;
fail:
	os_free(freqs);
	return -1;
}


static struct wpa_supplicant *
wpas_p2p_get_group_iface(struct wpa_supplicant *wpa_s, int addr_allocated,
			 int go)
{
	struct wpa_supplicant *group_wpa_s;

	if (!wpas_p2p_create_iface(wpa_s)) {
		if (wpa_s->p2p_mgmt) {
			/*
			 * We may be called on the p2p_dev interface which
			 * cannot be used for group operations, so always use
			 * the primary interface.
			 */
			wpa_s->parent->p2pdev = wpa_s;
			wpa_s = wpa_s->parent;
		}
		wpa_dbg(wpa_s, MSG_DEBUG,
			"P2P: Use primary interface for group operations");
		wpa_s->p2p_first_connection_timeout = 0;
		if (wpa_s != wpa_s->p2pdev)
			wpas_p2p_clone_config(wpa_s, wpa_s->p2pdev);
		return wpa_s;
	}

	if (wpas_p2p_add_group_interface(wpa_s, go ? WPA_IF_P2P_GO :
					 WPA_IF_P2P_CLIENT) < 0) {
		wpa_msg_global(wpa_s, MSG_ERROR,
			       "P2P: Failed to add group interface");
		return NULL;
	}
	group_wpa_s = wpas_p2p_init_group_interface(wpa_s, go);
	if (group_wpa_s == NULL) {
		wpa_msg_global(wpa_s, MSG_ERROR,
			       "P2P: Failed to initialize group interface");
		wpas_p2p_remove_pending_group_interface(wpa_s);
		return NULL;
	}

	if (go && wpa_s->p2p_go_do_acs) {
		group_wpa_s->p2p_go_do_acs = wpa_s->p2p_go_do_acs;
		group_wpa_s->p2p_go_acs_band = wpa_s->p2p_go_acs_band;
		wpa_s->p2p_go_do_acs = 0;
	}

	if (go && wpa_s->p2p_go_allow_dfs) {
		group_wpa_s->p2p_go_allow_dfs = wpa_s->p2p_go_allow_dfs;
		wpa_s->p2p_go_allow_dfs = 0;
	}

	wpa_dbg(wpa_s, MSG_DEBUG, "P2P: Use separate group interface %s",
		group_wpa_s->ifname);
	group_wpa_s->p2p_first_connection_timeout = 0;
	return group_wpa_s;
}


/**
 * wpas_p2p_group_add - Add a new P2P group with local end as Group Owner
 * @wpa_s: Pointer to wpa_supplicant data from wpa_supplicant_add_iface()
 * @persistent_group: Whether to create a persistent group
 * @freq: Frequency for the group or 0 to indicate no hardcoding
 * @vht_center_freq2: segment_1 center frequency for GO operating in VHT 80P80
 * @ht40: Start GO with 40 MHz channel width
 * @vht:  Start GO with VHT support
 * @vht_chwidth: channel bandwidth for GO operating with VHT support
 * @edmg: Start GO with EDMG support
 * @allow_6ghz: Allow P2P group creation on a 6 GHz channel
 * Returns: 0 on success, -1 on failure
 *
 * This function creates a new P2P group with the local end as the Group Owner,
 * i.e., without using Group Owner Negotiation.
 */
int wpas_p2p_group_add(struct wpa_supplicant *wpa_s, int persistent_group,
		       int freq, int vht_center_freq2, int ht40, int vht,
		       int max_oper_chwidth, int he, int edmg,
		       bool allow_6ghz)
{
	struct p2p_go_neg_results params;

	if (wpa_s->global->p2p_disabled || wpa_s->global->p2p == NULL)
		return -1;
	if (wpas_p2p_check_6ghz(wpa_s, NULL, allow_6ghz, freq))
		return -1;

	os_free(wpa_s->global->add_psk);
	wpa_s->global->add_psk = NULL;

	/* Make sure we are not running find during connection establishment */
	wpa_printf(MSG_DEBUG, "P2P: Stop any on-going P2P FIND");
	wpas_p2p_stop_find_oper(wpa_s);

	if (!wpa_s->p2p_go_do_acs) {
		freq = wpas_p2p_select_go_freq(wpa_s, freq);
		if (freq < 0)
			return -1;
	}

	if (wpas_p2p_init_go_params(wpa_s, &params, freq, vht_center_freq2,
				    ht40, vht, max_oper_chwidth, he, edmg,
				    NULL))
		return -1;

	p2p_go_params(wpa_s->global->p2p, &params);
	params.persistent_group = persistent_group;

	wpa_s = wpas_p2p_get_group_iface(wpa_s, 0, 1);
	if (wpa_s == NULL)
		return -1;
	wpas_start_wps_go(wpa_s, &params, 0);

	return 0;
}


static int wpas_start_p2p_client(struct wpa_supplicant *wpa_s,
				 struct wpa_ssid *params, int addr_allocated,
				 int freq, int force_scan)
{
	struct wpa_ssid *ssid;

	wpa_s = wpas_p2p_get_group_iface(wpa_s, addr_allocated, 0);
	if (wpa_s == NULL)
		return -1;
	if (force_scan)
		os_get_reltime(&wpa_s->scan_min_time);
	wpa_s->p2p_last_4way_hs_fail = NULL;

	wpa_supplicant_ap_deinit(wpa_s);

	ssid = wpa_config_add_network(wpa_s->conf);
	if (ssid == NULL)
		return -1;
	os_memset(wpa_s->go_dev_addr, 0, ETH_ALEN);
	wpa_config_set_network_defaults(ssid);
	ssid->temporary = 1;
	ssid->proto = WPA_PROTO_RSN;
	ssid->pbss = params->pbss;
	ssid->pairwise_cipher = params->pbss ? WPA_CIPHER_GCMP :
		WPA_CIPHER_CCMP;
	ssid->group_cipher = params->pbss ? WPA_CIPHER_GCMP : WPA_CIPHER_CCMP;
	ssid->key_mgmt = WPA_KEY_MGMT_PSK;
	ssid->ssid = os_malloc(params->ssid_len);
	if (ssid->ssid == NULL) {
		wpa_config_remove_network(wpa_s->conf, ssid->id);
		return -1;
	}
	os_memcpy(ssid->ssid, params->ssid, params->ssid_len);
	ssid->ssid_len = params->ssid_len;
	ssid->p2p_group = 1;
	ssid->export_keys = 1;
	if (params->psk_set) {
		os_memcpy(ssid->psk, params->psk, 32);
		ssid->psk_set = 1;
	}
	if (params->passphrase)
		ssid->passphrase = os_strdup(params->passphrase);

	wpa_s->show_group_started = 1;
	wpa_s->p2p_in_invitation = 1;
	wpa_s->p2p_invite_go_freq = freq;
	wpa_s->p2p_go_group_formation_completed = 0;
	wpa_s->global->p2p_group_formation = wpa_s;

	eloop_cancel_timeout(wpas_p2p_group_formation_timeout, wpa_s->p2pdev,
			     NULL);
	eloop_register_timeout(P2P_MAX_INITIAL_CONN_WAIT, 0,
			       wpas_p2p_group_formation_timeout,
			       wpa_s->p2pdev, NULL);
	wpa_supplicant_select_network(wpa_s, ssid);

	return 0;
}


int wpas_p2p_group_add_persistent(struct wpa_supplicant *wpa_s,
				  struct wpa_ssid *ssid, int addr_allocated,
				  int force_freq, int neg_freq,
				  int vht_center_freq2, int ht40,
				  int vht, int max_oper_chwidth, int he,
				  int edmg,
				  const struct p2p_channels *channels,
				  int connection_timeout, int force_scan,
				  bool allow_6ghz)
{
	struct p2p_go_neg_results params;
	int go = 0, freq;

	if (ssid->disabled != 2 || ssid->ssid == NULL)
		return -1;

	if (wpas_get_p2p_group(wpa_s, ssid->ssid, ssid->ssid_len, &go) &&
	    go == (ssid->mode == WPAS_MODE_P2P_GO)) {
		wpa_printf(MSG_DEBUG, "P2P: Requested persistent group is "
			   "already running");
		if (go == 0 &&
		    eloop_cancel_timeout(wpas_p2p_group_formation_timeout,
					 wpa_s->p2pdev, NULL)) {
			/*
			 * This can happen if Invitation Response frame was lost
			 * and the peer (GO of a persistent group) tries to
			 * invite us again. Reschedule the timeout to avoid
			 * terminating the wait for the connection too early
			 * since we now know that the peer is still trying to
			 * invite us instead of having already started the GO.
			 */
			wpa_printf(MSG_DEBUG,
				   "P2P: Reschedule group formation timeout since peer is still trying to invite us");
			eloop_register_timeout(P2P_MAX_INITIAL_CONN_WAIT, 0,
					       wpas_p2p_group_formation_timeout,
					       wpa_s->p2pdev, NULL);
		}
		return 0;
	}

	os_free(wpa_s->global->add_psk);
	wpa_s->global->add_psk = NULL;

	/* Make sure we are not running find during connection establishment */
	wpas_p2p_stop_find_oper(wpa_s);

	wpa_s->p2p_fallback_to_go_neg = 0;

	if (ssid->mode == WPAS_MODE_P2P_GO) {
		if (force_freq > 0) {
			freq = wpas_p2p_select_go_freq(wpa_s, force_freq);
			if (freq < 0)
				return -1;
		} else {
			freq = wpas_p2p_select_go_freq(wpa_s, neg_freq);
			if (freq < 0 ||
			    (freq > 0 && !freq_included(wpa_s, channels, freq)))
				freq = 0;
		}
	} else if (ssid->mode == WPAS_MODE_INFRA) {
		freq = neg_freq;
		if (freq <= 0 || !freq_included(wpa_s, channels, freq)) {
			struct os_reltime now;
			struct wpa_bss *bss =
				wpa_bss_get_p2p_dev_addr(wpa_s, ssid->bssid);

			os_get_reltime(&now);
			if (bss &&
			    !os_reltime_expired(&now, &bss->last_update, 5) &&
			    freq_included(wpa_s, channels, bss->freq))
				freq = bss->freq;
			else
				freq = 0;
		}

		return wpas_start_p2p_client(wpa_s, ssid, addr_allocated, freq,
					     force_scan);
	} else {
		return -1;
	}

	if (wpas_p2p_init_go_params(wpa_s, &params, freq, vht_center_freq2,
				    ht40, vht, max_oper_chwidth, he, edmg,
				    channels))
		return -1;

	params.role_go = 1;
	params.psk_set = ssid->psk_set;
	if (params.psk_set)
		os_memcpy(params.psk, ssid->psk, sizeof(params.psk));
	if (ssid->passphrase) {
		if (os_strlen(ssid->passphrase) >= sizeof(params.passphrase)) {
			wpa_printf(MSG_ERROR, "P2P: Invalid passphrase in "
				   "persistent group");
			return -1;
		}
		os_strlcpy(params.passphrase, ssid->passphrase,
			   sizeof(params.passphrase));
	}
	os_memcpy(params.ssid, ssid->ssid, ssid->ssid_len);
	params.ssid_len = ssid->ssid_len;
	params.persistent_group = 1;

	wpa_s = wpas_p2p_get_group_iface(wpa_s, addr_allocated, 1);
	if (wpa_s == NULL)
		return -1;

	p2p_channels_to_freqs(channels, params.freq_list, P2P_MAX_CHANNELS);

	wpa_s->p2p_first_connection_timeout = connection_timeout;
	wpas_start_wps_go(wpa_s, &params, 0);

	return 0;
}


static void wpas_p2p_ie_update(void *ctx, struct wpabuf *beacon_ies,
			       struct wpabuf *proberesp_ies)
{
	struct wpa_supplicant *wpa_s = ctx;
	if (wpa_s->ap_iface) {
		struct hostapd_data *hapd = wpa_s->ap_iface->bss[0];
		if (!(hapd->conf->p2p & P2P_GROUP_OWNER)) {
			wpabuf_free(beacon_ies);
			wpabuf_free(proberesp_ies);
			return;
		}
		if (beacon_ies) {
			wpabuf_free(hapd->p2p_beacon_ie);
			hapd->p2p_beacon_ie = beacon_ies;
		}
		wpabuf_free(hapd->p2p_probe_resp_ie);
		hapd->p2p_probe_resp_ie = proberesp_ies;
	} else {
		wpabuf_free(beacon_ies);
		wpabuf_free(proberesp_ies);
	}
	wpa_supplicant_ap_update_beacon(wpa_s);
}


static void wpas_p2p_idle_update(void *ctx, int idle)
{
	struct wpa_supplicant *wpa_s = ctx;
	if (!wpa_s->ap_iface)
		return;
	wpa_printf(MSG_DEBUG, "P2P: GO - group %sidle", idle ? "" : "not ");
	if (idle) {
		if (wpa_s->global->p2p_fail_on_wps_complete &&
		    wpa_s->p2p_in_provisioning) {
			wpas_p2p_grpform_fail_after_wps(wpa_s);
			return;
		}
		wpas_p2p_set_group_idle_timeout(wpa_s);
	} else
		eloop_cancel_timeout(wpas_p2p_group_idle_timeout, wpa_s, NULL);
}


struct p2p_group * wpas_p2p_group_init(struct wpa_supplicant *wpa_s,
				       struct wpa_ssid *ssid)
{
	struct p2p_group *group;
	struct p2p_group_config *cfg;

	if (wpa_s->global->p2p_disabled || wpa_s->global->p2p == NULL ||
	    !ssid->p2p_group)
		return NULL;

	cfg = os_zalloc(sizeof(*cfg));
	if (cfg == NULL)
		return NULL;

	if (ssid->p2p_persistent_group && wpa_s->conf->persistent_reconnect)
		cfg->persistent_group = 2;
	else if (ssid->p2p_persistent_group)
		cfg->persistent_group = 1;
	os_memcpy(cfg->interface_addr, wpa_s->own_addr, ETH_ALEN);
	if (wpa_s->max_stations &&
	    wpa_s->max_stations < wpa_s->conf->max_num_sta)
		cfg->max_clients = wpa_s->max_stations;
	else
		cfg->max_clients = wpa_s->conf->max_num_sta;
	os_memcpy(cfg->ssid, ssid->ssid, ssid->ssid_len);
	cfg->ssid_len = ssid->ssid_len;
	cfg->freq = ssid->frequency;
	cfg->cb_ctx = wpa_s;
	cfg->ie_update = wpas_p2p_ie_update;
	cfg->idle_update = wpas_p2p_idle_update;
	cfg->ip_addr_alloc = WPA_GET_BE32(wpa_s->p2pdev->conf->ip_addr_start)
		!= 0;

	group = p2p_group_init(wpa_s->global->p2p, cfg);
	if (group == NULL)
		os_free(cfg);
	if (ssid->mode != WPAS_MODE_P2P_GROUP_FORMATION)
		p2p_group_notif_formation_done(group);
	wpa_s->p2p_group = group;
	return group;
}


void wpas_p2p_wps_success(struct wpa_supplicant *wpa_s, const u8 *peer_addr,
			  int registrar)
{
	struct wpa_ssid *ssid = wpa_s->current_ssid;

	if (!wpa_s->p2p_in_provisioning) {
		wpa_printf(MSG_DEBUG, "P2P: Ignore WPS success event - P2P "
			   "provisioning not in progress");
		return;
	}

	if (ssid && ssid->mode == WPAS_MODE_INFRA) {
		u8 go_dev_addr[ETH_ALEN];
		os_memcpy(go_dev_addr, wpa_s->bssid, ETH_ALEN);
		wpas_p2p_persistent_group(wpa_s, go_dev_addr, ssid->ssid,
					  ssid->ssid_len);
		/* Clear any stored provisioning info */
		p2p_clear_provisioning_info(wpa_s->global->p2p, go_dev_addr);
	}

	eloop_cancel_timeout(wpas_p2p_group_formation_timeout, wpa_s->p2pdev,
			     NULL);
	wpa_s->p2p_go_group_formation_completed = 1;
	if (ssid && ssid->mode == WPAS_MODE_INFRA) {
		/*
		 * Use a separate timeout for initial data connection to
		 * complete to allow the group to be removed automatically if
		 * something goes wrong in this step before the P2P group idle
		 * timeout mechanism is taken into use.
		 */
		wpa_dbg(wpa_s, MSG_DEBUG,
			"P2P: Re-start group formation timeout (%d seconds) as client for initial connection",
			P2P_MAX_INITIAL_CONN_WAIT);
		eloop_register_timeout(P2P_MAX_INITIAL_CONN_WAIT, 0,
				       wpas_p2p_group_formation_timeout,
				       wpa_s->p2pdev, NULL);
		/* Complete group formation on successful data connection. */
		wpa_s->p2p_go_group_formation_completed = 0;
	} else if (ssid) {
		/*
		 * Use a separate timeout for initial data connection to
		 * complete to allow the group to be removed automatically if
		 * the client does not complete data connection successfully.
		 */
		wpa_dbg(wpa_s, MSG_DEBUG,
			"P2P: Re-start group formation timeout (%d seconds) as GO for initial connection",
			P2P_MAX_INITIAL_CONN_WAIT_GO);
		eloop_register_timeout(P2P_MAX_INITIAL_CONN_WAIT_GO, 0,
				       wpas_p2p_group_formation_timeout,
				       wpa_s->p2pdev, NULL);
		/*
		 * Complete group formation on first successful data connection
		 */
		wpa_s->p2p_go_group_formation_completed = 0;
	}
	if (wpa_s->global->p2p)
		p2p_wps_success_cb(wpa_s->global->p2p, peer_addr);
	wpas_group_formation_completed(wpa_s, 1, 0);
}


void wpas_p2p_wps_failed(struct wpa_supplicant *wpa_s,
			 struct wps_event_fail *fail)
{
	if (!wpa_s->p2p_in_provisioning) {
		wpa_printf(MSG_DEBUG, "P2P: Ignore WPS fail event - P2P "
			   "provisioning not in progress");
		return;
	}

	if (wpa_s->go_params) {
		p2p_clear_provisioning_info(
			wpa_s->global->p2p,
			wpa_s->go_params->peer_device_addr);
	}

	wpas_notify_p2p_wps_failed(wpa_s, fail);

	if (wpa_s == wpa_s->global->p2p_group_formation) {
		/*
		 * Allow some time for the failed WPS negotiation exchange to
		 * complete, but remove the group since group formation cannot
		 * succeed after provisioning failure.
		 */
		wpa_printf(MSG_DEBUG, "P2P: WPS step failed during group formation - reject connection from timeout");
		wpa_s->global->p2p_fail_on_wps_complete = 1;
		eloop_deplete_timeout(0, 50000,
				      wpas_p2p_group_formation_timeout,
				      wpa_s->p2pdev, NULL);
	}
}


int wpas_p2p_wps_eapol_cb(struct wpa_supplicant *wpa_s)
{
	if (!wpa_s->global->p2p_fail_on_wps_complete ||
	    !wpa_s->p2p_in_provisioning)
		return 0;

	wpas_p2p_grpform_fail_after_wps(wpa_s);

	return 1;
}


int wpas_p2p_prov_disc(struct wpa_supplicant *wpa_s, const u8 *peer_addr,
		       const char *config_method,
		       enum wpas_p2p_prov_disc_use use,
		       struct p2ps_provision *p2ps_prov)
{
	u16 config_methods;

	wpa_s->global->pending_p2ps_group = 0;
	wpa_s->global->pending_p2ps_group_freq = 0;
	wpa_s->p2p_fallback_to_go_neg = 0;
	wpa_s->pending_pd_use = NORMAL_PD;
	if (p2ps_prov && use == WPAS_P2P_PD_FOR_ASP) {
		p2ps_prov->conncap = p2ps_group_capability(
			wpa_s, P2PS_SETUP_NONE, p2ps_prov->role,
			&p2ps_prov->force_freq, &p2ps_prov->pref_freq);

		wpa_printf(MSG_DEBUG,
			   "P2P: %s conncap: %d - ASP parsed: %x %x %d %s",
			   __func__, p2ps_prov->conncap,
			   p2ps_prov->adv_id, p2ps_prov->conncap,
			   p2ps_prov->status, p2ps_prov->info);

		config_methods = 0;
	} else if (os_strncmp(config_method, "display", 7) == 0)
		config_methods = WPS_CONFIG_DISPLAY;
	else if (os_strncmp(config_method, "keypad", 6) == 0)
		config_methods = WPS_CONFIG_KEYPAD;
	else if (os_strncmp(config_method, "pbc", 3) == 0 ||
		 os_strncmp(config_method, "pushbutton", 10) == 0)
		config_methods = WPS_CONFIG_PUSHBUTTON;
	else {
		wpa_printf(MSG_DEBUG, "P2P: Unknown config method");
		os_free(p2ps_prov);
		return -1;
	}

	if (use == WPAS_P2P_PD_AUTO) {
		os_memcpy(wpa_s->pending_join_dev_addr, peer_addr, ETH_ALEN);
		wpa_s->pending_pd_config_methods = config_methods;
		wpa_s->p2p_auto_pd = 1;
		wpa_s->p2p_auto_join = 0;
		wpa_s->pending_pd_before_join = 0;
		wpa_s->auto_pd_scan_retry = 0;
		wpas_p2p_stop_find(wpa_s);
		wpa_s->p2p_join_scan_count = 0;
		os_get_reltime(&wpa_s->p2p_auto_started);
		wpa_printf(MSG_DEBUG, "P2P: Auto PD started at %ld.%06ld",
			   wpa_s->p2p_auto_started.sec,
			   wpa_s->p2p_auto_started.usec);
		wpas_p2p_join_scan(wpa_s, NULL);
		return 0;
	}

	if (wpa_s->global->p2p == NULL || wpa_s->global->p2p_disabled) {
		os_free(p2ps_prov);
		return -1;
	}

	return p2p_prov_disc_req(wpa_s->global->p2p, peer_addr, p2ps_prov,
				 config_methods, use == WPAS_P2P_PD_FOR_JOIN,
				 0, 1);
}


int wpas_p2p_scan_result_text(const u8 *ies, size_t ies_len, char *buf,
			      char *end)
{
	return p2p_scan_result_text(ies, ies_len, buf, end);
}


static void wpas_p2p_clear_pending_action_tx(struct wpa_supplicant *wpa_s)
{
	if (!offchannel_pending_action_tx(wpa_s))
		return;

	if (wpa_s->p2p_send_action_work) {
		wpas_p2p_free_send_action_work(wpa_s);
		eloop_cancel_timeout(wpas_p2p_send_action_work_timeout,
				     wpa_s, NULL);
		offchannel_send_action_done(wpa_s);
	}

	wpa_printf(MSG_DEBUG, "P2P: Drop pending Action TX due to new "
		   "operation request");
	offchannel_clear_pending_action_tx(wpa_s);
}


int wpas_p2p_find(struct wpa_supplicant *wpa_s, 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,
		  u8 seek_cnt, const char **seek_string, int freq,
		  bool include_6ghz)
{
	wpas_p2p_clear_pending_action_tx(wpa_s);
	wpa_s->global->p2p_long_listen = 0;

	if (wpa_s->global->p2p_disabled || wpa_s->global->p2p == NULL ||
	    wpa_s->p2p_in_provisioning) {
		wpa_dbg(wpa_s, MSG_DEBUG, "P2P: Reject p2p_find operation%s%s",
			(wpa_s->global->p2p_disabled || !wpa_s->global->p2p) ?
			" (P2P disabled)" : "",
			wpa_s->p2p_in_provisioning ?
			" (p2p_in_provisioning)" : "");
		return -1;
	}

	wpa_supplicant_cancel_sched_scan(wpa_s);

	return p2p_find(wpa_s->global->p2p, timeout, type,
			num_req_dev_types, req_dev_types, dev_id,
			search_delay, seek_cnt, seek_string, freq,
			include_6ghz);
}


static void wpas_p2p_scan_res_ignore_search(struct wpa_supplicant *wpa_s,
					    struct wpa_scan_results *scan_res)
{
	wpa_printf(MSG_DEBUG, "P2P: Ignore scan results");

	if (wpa_s->p2p_scan_work) {
		struct wpa_radio_work *work = wpa_s->p2p_scan_work;
		wpa_s->p2p_scan_work = NULL;
		radio_work_done(work);
	}

	if (wpa_s->global->p2p_disabled || wpa_s->global->p2p == NULL)
		return;

	/*
	 * Indicate that results have been processed so that the P2P module can
	 * continue pending tasks.
	 */
	wpas_p2p_scan_res_handled(wpa_s);
}


static void wpas_p2p_stop_find_oper(struct wpa_supplicant *wpa_s)
{
	wpas_p2p_clear_pending_action_tx(wpa_s);
	wpa_s->global->p2p_long_listen = 0;
	eloop_cancel_timeout(wpas_p2p_long_listen_timeout, wpa_s, NULL);
	eloop_cancel_timeout(wpas_p2p_join_scan, wpa_s, NULL);

	if (wpa_s->global->p2p)
		p2p_stop_find(wpa_s->global->p2p);

	if (wpa_s->scan_res_handler == wpas_p2p_scan_res_handler) {
		wpa_printf(MSG_DEBUG,
			   "P2P: Do not consider the scan results after stop_find");
		wpa_s->scan_res_handler = wpas_p2p_scan_res_ignore_search;
	}
}


void wpas_p2p_stop_find(struct wpa_supplicant *wpa_s)
{
	wpas_p2p_stop_find_oper(wpa_s);
	if (!wpa_s->global->pending_group_iface_for_p2ps)
		wpas_p2p_remove_pending_group_interface(wpa_s);
}


static void wpas_p2p_long_listen_timeout(void *eloop_ctx, void *timeout_ctx)
{
	struct wpa_supplicant *wpa_s = eloop_ctx;
	wpa_s->global->p2p_long_listen = 0;
}


int wpas_p2p_listen(struct wpa_supplicant *wpa_s, unsigned int timeout)
{
	int res;

	if (wpa_s->global->p2p_disabled || wpa_s->global->p2p == NULL)
		return -1;

	if (wpa_s->p2p_lo_started) {
		wpa_printf(MSG_DEBUG,
			"P2P: Cannot start P2P listen, it is offloaded");
		return -1;
	}

	wpa_supplicant_cancel_sched_scan(wpa_s);
	wpas_p2p_clear_pending_action_tx(wpa_s);

	if (timeout == 0) {
		/*
		 * This is a request for unlimited Listen state. However, at
		 * least for now, this is mapped to a Listen state for one
		 * hour.
		 */
		timeout = 3600;
	}
	eloop_cancel_timeout(wpas_p2p_long_listen_timeout, wpa_s, NULL);
	wpa_s->global->p2p_long_listen = 0;

	/*
	 * Stop previous find/listen operation to avoid trying to request a new
	 * remain-on-channel operation while the driver is still running the
	 * previous one.
	 */
	if (wpa_s->global->p2p)
		p2p_stop_find(wpa_s->global->p2p);

	res = wpas_p2p_listen_start(wpa_s, timeout * 1000);
	if (res == 0 && timeout * 1000 > wpa_s->max_remain_on_chan) {
		wpa_s->global->p2p_long_listen = timeout * 1000;
		eloop_register_timeout(timeout, 0,
				       wpas_p2p_long_listen_timeout,
				       wpa_s, NULL);
	}

	return res;
}


int wpas_p2p_assoc_req_ie(struct wpa_supplicant *wpa_s, struct wpa_bss *bss,
			  u8 *buf, size_t len, int p2p_group)
{
	struct wpabuf *p2p_ie;
	int ret;

	if (wpa_s->global->p2p_disabled)
		return -1;
	/*
	 * Advertize mandatory cross connection capability even on
	 * p2p_disabled=1 interface when associating with a P2P Manager WLAN AP.
	 */
	if (wpa_s->conf->p2p_disabled && p2p_group)
		return -1;
	if (wpa_s->global->p2p == NULL)
		return -1;
	if (bss == NULL)
		return -1;

	p2p_ie = wpa_bss_get_vendor_ie_multi(bss, P2P_IE_VENDOR_TYPE);
	ret = p2p_assoc_req_ie(wpa_s->global->p2p, bss->bssid, buf, len,
			       p2p_group, p2p_ie);
	wpabuf_free(p2p_ie);

	return ret;
}


int wpas_p2p_probe_req_rx(struct wpa_supplicant *wpa_s, const u8 *addr,
			  const u8 *dst, const u8 *bssid,
			  const u8 *ie, size_t ie_len,
			  unsigned int rx_freq, int ssi_signal)
{
	if (wpa_s->global->p2p_disabled)
		return 0;
	if (wpa_s->global->p2p == NULL)
		return 0;

	switch (p2p_probe_req_rx(wpa_s->global->p2p, addr, dst, bssid,
				 ie, ie_len, rx_freq, wpa_s->p2p_lo_started)) {
	case P2P_PREQ_NOT_P2P:
		wpas_notify_preq(wpa_s, addr, dst, bssid, ie, ie_len,
				 ssi_signal);
		/* fall through */
	case P2P_PREQ_MALFORMED:
	case P2P_PREQ_NOT_LISTEN:
	case P2P_PREQ_NOT_PROCESSED:
	default: /* make gcc happy */
		return 0;
	case P2P_PREQ_PROCESSED:
		return 1;
	}
}


void wpas_p2p_rx_action(struct wpa_supplicant *wpa_s, const u8 *da,
			const u8 *sa, const u8 *bssid,
			u8 category, const u8 *data, size_t len, int freq)
{
	if (wpa_s->global->p2p_disabled)
		return;
	if (wpa_s->global->p2p == NULL)
		return;

	p2p_rx_action(wpa_s->global->p2p, da, sa, bssid, category, data, len,
		      freq);
}


void wpas_p2p_scan_ie(struct wpa_supplicant *wpa_s, struct wpabuf *ies)
{
	unsigned int bands;

	if (wpa_s->global->p2p_disabled)
		return;
	if (wpa_s->global->p2p == NULL)
		return;

	bands = wpas_get_bands(wpa_s, NULL);
	p2p_scan_ie(wpa_s->global->p2p, ies, NULL, bands);
}


static void wpas_p2p_group_deinit(struct wpa_supplicant *wpa_s)
{
	p2p_group_deinit(wpa_s->p2p_group);
	wpa_s->p2p_group = NULL;

	wpa_s->ap_configured_cb = NULL;
	wpa_s->ap_configured_cb_ctx = NULL;
	wpa_s->ap_configured_cb_data = NULL;
	wpa_s->connect_without_scan = NULL;
}


int wpas_p2p_reject(struct wpa_supplicant *wpa_s, const u8 *addr)
{
	wpa_s->global->p2p_long_listen = 0;

	if (wpa_s->global->p2p_disabled || wpa_s->global->p2p == NULL)
		return -1;

	return p2p_reject(wpa_s->global->p2p, addr);
}


/* Invite to reinvoke a persistent group */
int wpas_p2p_invite(struct wpa_supplicant *wpa_s, const u8 *peer_addr,
		    struct wpa_ssid *ssid, const u8 *go_dev_addr, int freq,
		    int vht_center_freq2, int ht40, int vht, int max_chwidth,
		    int pref_freq, int he, int edmg, bool allow_6ghz)
{
	enum p2p_invite_role role;
	u8 *bssid = NULL;
	int force_freq = 0;
	int res;
	int no_pref_freq_given = pref_freq == 0;
	unsigned int pref_freq_list[P2P_MAX_PREF_CHANNELS], size;

	if (wpas_p2p_check_6ghz(wpa_s, NULL, allow_6ghz, freq))
		return -1;

	wpa_s->global->p2p_invite_group = NULL;
	if (peer_addr)
		os_memcpy(wpa_s->p2p_auth_invite, peer_addr, ETH_ALEN);
	else
		os_memset(wpa_s->p2p_auth_invite, 0, ETH_ALEN);

	wpa_s->p2p_persistent_go_freq = freq;
	wpa_s->p2p_go_ht40 = !!ht40;
	wpa_s->p2p_go_vht = !!vht;
	wpa_s->p2p_go_he = !!he;
	wpa_s->p2p_go_max_oper_chwidth = max_chwidth;
	wpa_s->p2p_go_vht_center_freq2 = vht_center_freq2;
	wpa_s->p2p_go_edmg = !!edmg;
	if (ssid->mode == WPAS_MODE_P2P_GO) {
		role = P2P_INVITE_ROLE_GO;
		if (peer_addr == NULL) {
			wpa_printf(MSG_DEBUG, "P2P: Missing peer "
				   "address in invitation command");
			return -1;
		}
		if (wpas_p2p_create_iface(wpa_s)) {
			if (wpas_p2p_add_group_interface(wpa_s,
							 WPA_IF_P2P_GO) < 0) {
				wpa_printf(MSG_ERROR, "P2P: Failed to "
					   "allocate a new interface for the "
					   "group");
				return -1;
			}
			bssid = wpa_s->pending_interface_addr;
		} else if (wpa_s->p2p_mgmt)
			bssid = wpa_s->parent->own_addr;
		else
			bssid = wpa_s->own_addr;
	} else {
		role = P2P_INVITE_ROLE_CLIENT;
		peer_addr = ssid->bssid;
	}
	wpa_s->pending_invite_ssid_id = ssid->id;

	size = P2P_MAX_PREF_CHANNELS;
	res = wpas_p2p_setup_freqs(wpa_s, freq, &force_freq, &pref_freq,
				   role == P2P_INVITE_ROLE_GO,
				   pref_freq_list, &size);
	if (res)
		return res;

	if (wpa_s->global->p2p_disabled || wpa_s->global->p2p == NULL)
		return -1;

	p2p_set_own_pref_freq_list(wpa_s->global->p2p, pref_freq_list, size);

	if (wpa_s->parent->conf->p2p_ignore_shared_freq &&
	    no_pref_freq_given && pref_freq > 0 &&
	    wpa_s->num_multichan_concurrent > 1 &&
	    wpas_p2p_num_unused_channels(wpa_s) > 0) {
		wpa_printf(MSG_DEBUG, "P2P: Ignore own channel preference %d MHz for invitation due to p2p_ignore_shared_freq=1 configuration",
			   pref_freq);
		pref_freq = 0;
	}

	/*
	 * Stop any find/listen operations before invitation and possibly
	 * connection establishment.
	 */
	wpas_p2p_stop_find_oper(wpa_s);

	return p2p_invite(wpa_s->global->p2p, peer_addr, role, bssid,
			  ssid->ssid, ssid->ssid_len, force_freq, go_dev_addr,
			  1, pref_freq, -1);
}


/* Invite to join an active group */
int wpas_p2p_invite_group(struct wpa_supplicant *wpa_s, const char *ifname,
			  const u8 *peer_addr, const u8 *go_dev_addr,
			  bool allow_6ghz)
{
	struct wpa_global *global = wpa_s->global;
	enum p2p_invite_role role;
	u8 *bssid = NULL;
	struct wpa_ssid *ssid;
	int persistent;
	int freq = 0, force_freq = 0, pref_freq = 0;
	int res;
	unsigned int pref_freq_list[P2P_MAX_PREF_CHANNELS], size;

	wpa_s->p2p_persistent_go_freq = 0;
	wpa_s->p2p_go_ht40 = 0;
	wpa_s->p2p_go_vht = 0;
	wpa_s->p2p_go_vht_center_freq2 = 0;
	wpa_s->p2p_go_max_oper_chwidth = 0;
	wpa_s->p2p_go_edmg = 0;

	for (wpa_s = global->ifaces; wpa_s; wpa_s = wpa_s->next) {
		if (os_strcmp(wpa_s->ifname, ifname) == 0)
			break;
	}
	if (wpa_s == NULL) {
		wpa_printf(MSG_DEBUG, "P2P: Interface '%s' not found", ifname);
		return -1;
	}

	ssid = wpa_s->current_ssid;
	if (ssid == NULL) {
		wpa_printf(MSG_DEBUG, "P2P: No current SSID to use for "
			   "invitation");
		return -1;
	}

	wpa_s->global->p2p_invite_group = wpa_s;
	persistent = ssid->p2p_persistent_group &&
		wpas_p2p_get_persistent(wpa_s->p2pdev, peer_addr,
					ssid->ssid, ssid->ssid_len);

	if (ssid->mode == WPAS_MODE_P2P_GO) {
		role = P2P_INVITE_ROLE_ACTIVE_GO;
		bssid = wpa_s->own_addr;
		if (go_dev_addr == NULL)
			go_dev_addr = wpa_s->global->p2p_dev_addr;
		freq = ssid->frequency;
	} else {
		role = P2P_INVITE_ROLE_CLIENT;
		if (wpa_s->wpa_state < WPA_ASSOCIATED) {
			wpa_printf(MSG_DEBUG, "P2P: Not associated - cannot "
				   "invite to current group");
			return -1;
		}
		bssid = wpa_s->bssid;
		if (go_dev_addr == NULL &&
		    !is_zero_ether_addr(wpa_s->go_dev_addr))
			go_dev_addr = wpa_s->go_dev_addr;
		freq = wpa_s->current_bss ? wpa_s->current_bss->freq :
			(int) wpa_s->assoc_freq;
	}
	wpa_s->p2pdev->pending_invite_ssid_id = -1;

	if (wpa_s->global->p2p_disabled || wpa_s->global->p2p == NULL)
		return -1;
	if (wpas_p2p_check_6ghz(wpa_s, peer_addr, allow_6ghz, freq))
		return -1;

	size = P2P_MAX_PREF_CHANNELS;
	res = wpas_p2p_setup_freqs(wpa_s, freq, &force_freq, &pref_freq,
				   role == P2P_INVITE_ROLE_ACTIVE_GO,
				   pref_freq_list, &size);
	if (res)
		return res;
	wpas_p2p_set_own_freq_preference(wpa_s, force_freq);

	return p2p_invite(wpa_s->global->p2p, peer_addr, role, bssid,
			  ssid->ssid, ssid->ssid_len, force_freq,
			  go_dev_addr, persistent, pref_freq, -1);
}


void wpas_p2p_completed(struct wpa_supplicant *wpa_s)
{
	struct wpa_ssid *ssid = wpa_s->current_ssid;
	u8 go_dev_addr[ETH_ALEN];
	int persistent;
	int freq;
	u8 ip[3 * 4], *ip_ptr = NULL;
	char ip_addr[100];

	if (ssid == NULL || ssid->mode != WPAS_MODE_P2P_GROUP_FORMATION) {
		eloop_cancel_timeout(wpas_p2p_group_formation_timeout,
				     wpa_s->p2pdev, NULL);
	}

	if (!wpa_s->show_group_started || !ssid)
		return;

	wpa_s->show_group_started = 0;
	if (!wpa_s->p2p_go_group_formation_completed &&
	    wpa_s->global->p2p_group_formation == wpa_s) {
		wpa_dbg(wpa_s, MSG_DEBUG,
			"P2P: Marking group formation completed on client on data connection");
		wpa_s->p2p_go_group_formation_completed = 1;
		wpa_s->global->p2p_group_formation = NULL;
		wpa_s->p2p_in_provisioning = 0;
		wpa_s->p2p_in_invitation = 0;
	}

	os_memset(go_dev_addr, 0, ETH_ALEN);
	if (ssid->bssid_set)
		os_memcpy(go_dev_addr, ssid->bssid, ETH_ALEN);
	persistent = wpas_p2p_persistent_group(wpa_s, go_dev_addr, ssid->ssid,
					       ssid->ssid_len);
	os_memcpy(wpa_s->go_dev_addr, go_dev_addr, ETH_ALEN);

	if (wpa_s->global->p2p_group_formation == wpa_s)
		wpa_s->global->p2p_group_formation = NULL;

	freq = wpa_s->current_bss ? wpa_s->current_bss->freq :
		(int) wpa_s->assoc_freq;

	ip_addr[0] = '\0';
	if (wpa_sm_get_p2p_ip_addr(wpa_s->wpa, ip) == 0) {
		int res;

		res = os_snprintf(ip_addr, sizeof(ip_addr),
				  " ip_addr=%u.%u.%u.%u "
				  "ip_mask=%u.%u.%u.%u go_ip_addr=%u.%u.%u.%u",
				  ip[0], ip[1], ip[2], ip[3],
				  ip[4], ip[5], ip[6], ip[7],
				  ip[8], ip[9], ip[10], ip[11]);
		if (os_snprintf_error(sizeof(ip_addr), res))
			ip_addr[0] = '\0';
		ip_ptr = ip;
	}

	wpas_p2p_group_started(wpa_s, 0, ssid, freq,
			       ssid->passphrase == NULL && ssid->psk_set ?
			       ssid->psk : NULL,
			       ssid->passphrase, go_dev_addr, persistent,
			       ip_addr);

	if (persistent)
		wpas_p2p_store_persistent_group(wpa_s->p2pdev,
						ssid, go_dev_addr);

	wpas_notify_p2p_group_started(wpa_s, ssid, persistent, 1, ip_ptr);
}


int wpas_p2p_presence_req(struct wpa_supplicant *wpa_s, u32 duration1,
			  u32 interval1, u32 duration2, u32 interval2)
{
	int ret;

	if (wpa_s->global->p2p_disabled || wpa_s->global->p2p == NULL)
		return -1;

	if (wpa_s->wpa_state < WPA_ASSOCIATED ||
	    wpa_s->current_ssid == NULL ||
	    wpa_s->current_ssid->mode != WPAS_MODE_INFRA)
		return -1;

	ret = p2p_presence_req(wpa_s->global->p2p, wpa_s->bssid,
			       wpa_s->own_addr, wpa_s->assoc_freq,
			       duration1, interval1, duration2, interval2);
	if (ret == 0)
		wpa_s->waiting_presence_resp = 1;

	return ret;
}


int wpas_p2p_ext_listen(struct wpa_supplicant *wpa_s, unsigned int period,
			unsigned int interval)
{
	if (wpa_s->global->p2p_disabled || wpa_s->global->p2p == NULL)
		return -1;

	return p2p_ext_listen(wpa_s->global->p2p, period, interval);
}


static int wpas_p2p_is_client(struct wpa_supplicant *wpa_s)
{
	if (wpa_s->current_ssid == NULL) {
		/*
		 * current_ssid can be cleared when P2P client interface gets
		 * disconnected, so assume this interface was used as P2P
		 * client.
		 */
		return 1;
	}
	return wpa_s->current_ssid->p2p_group &&
		wpa_s->current_ssid->mode == WPAS_MODE_INFRA;
}


static void wpas_p2p_group_idle_timeout(void *eloop_ctx, void *timeout_ctx)
{
	struct wpa_supplicant *wpa_s = eloop_ctx;

	if (wpa_s->conf->p2p_group_idle == 0 && !wpas_p2p_is_client(wpa_s)) {
		wpa_printf(MSG_DEBUG, "P2P: Ignore group idle timeout - "
			   "disabled");
		return;
	}

	wpa_printf(MSG_DEBUG, "P2P: Group idle timeout reached - terminate "
		   "group");
	wpas_p2p_group_delete(wpa_s, P2P_GROUP_REMOVAL_IDLE_TIMEOUT);
}


static void wpas_p2p_set_group_idle_timeout(struct wpa_supplicant *wpa_s)
{
	int timeout;

	if (eloop_cancel_timeout(wpas_p2p_group_idle_timeout, wpa_s, NULL) > 0)
		wpa_printf(MSG_DEBUG, "P2P: Cancelled P2P group idle timeout");

	if (wpa_s->current_ssid == NULL || !wpa_s->current_ssid->p2p_group)
		return;

	timeout = wpa_s->conf->p2p_group_idle;
	if (wpa_s->current_ssid->mode == WPAS_MODE_INFRA &&
	    (timeout == 0 || timeout > P2P_MAX_CLIENT_IDLE))
	    timeout = P2P_MAX_CLIENT_IDLE;

	if (timeout == 0)
		return;

	if (timeout < 0) {
		if (wpa_s->current_ssid->mode == WPAS_MODE_INFRA)
			timeout = 0; /* special client mode no-timeout */
		else
			return;
	}

	if (wpa_s->p2p_in_provisioning) {
		/*
		 * Use the normal group formation timeout during the
		 * provisioning phase to avoid terminating this process too
		 * early due to group idle timeout.
		 */
		wpa_printf(MSG_DEBUG, "P2P: Do not use P2P group idle timeout "
			   "during provisioning");
		return;
	}

	if (wpa_s->show_group_started) {
		/*
		 * Use the normal group formation timeout between the end of
		 * the provisioning phase and completion of 4-way handshake to
		 * avoid terminating this process too early due to group idle
		 * timeout.
		 */
		wpa_printf(MSG_DEBUG, "P2P: Do not use P2P group idle timeout "
			   "while waiting for initial 4-way handshake to "
			   "complete");
		return;
	}

	wpa_printf(MSG_DEBUG, "P2P: Set P2P group idle timeout to %u seconds",
		   timeout);
	eloop_register_timeout(timeout, 0, wpas_p2p_group_idle_timeout,
			       wpa_s, NULL);
}


/* Returns 1 if the interface was removed */
int wpas_p2p_deauth_notif(struct wpa_supplicant *wpa_s, const u8 *bssid,
			  u16 reason_code, const u8 *ie, size_t ie_len,
			  int locally_generated)
{
	if (wpa_s->global->p2p_disabled || wpa_s->global->p2p == NULL)
		return 0;

	if (!locally_generated)
		p2p_deauth_notif(wpa_s->global->p2p, bssid, reason_code, ie,
				 ie_len);

	if (reason_code == WLAN_REASON_DEAUTH_LEAVING && !locally_generated &&
	    wpa_s->current_ssid &&
	    wpa_s->current_ssid->p2p_group &&
	    wpa_s->current_ssid->mode == WPAS_MODE_INFRA) {
		wpa_printf(MSG_DEBUG, "P2P: GO indicated that the P2P Group "
			   "session is ending");
		if (wpas_p2p_group_delete(wpa_s,
					  P2P_GROUP_REMOVAL_GO_ENDING_SESSION)
		    > 0)
			return 1;
	}

	return 0;
}


void wpas_p2p_disassoc_notif(struct wpa_supplicant *wpa_s, const u8 *bssid,
			     u16 reason_code, const u8 *ie, size_t ie_len,
			     int locally_generated)
{
	if (wpa_s->global->p2p_disabled || wpa_s->global->p2p == NULL)
		return;

	if (!locally_generated)
		p2p_disassoc_notif(wpa_s->global->p2p, bssid, reason_code, ie,
				   ie_len);
}


void wpas_p2p_update_config(struct wpa_supplicant *wpa_s)
{
	struct p2p_data *p2p = wpa_s->global->p2p;

	if (p2p == NULL)
		return;

	if (!(wpa_s->drv_flags & WPA_DRIVER_FLAGS_P2P_CAPABLE))
		return;

	if (wpa_s->conf->changed_parameters & CFG_CHANGED_DEVICE_NAME)
		p2p_set_dev_name(p2p, wpa_s->conf->device_name);

	if (wpa_s->conf->changed_parameters & CFG_CHANGED_DEVICE_TYPE)
		p2p_set_pri_dev_type(p2p, wpa_s->conf->device_type);

	if (wpa_s->wps &&
	    (wpa_s->conf->changed_parameters & CFG_CHANGED_CONFIG_METHODS))
		p2p_set_config_methods(p2p, wpa_s->wps->config_methods);

	if (wpa_s->wps && (wpa_s->conf->changed_parameters & CFG_CHANGED_UUID))
		p2p_set_uuid(p2p, wpa_s->wps->uuid);

	if (wpa_s->conf->changed_parameters & CFG_CHANGED_WPS_STRING) {
		p2p_set_manufacturer(p2p, wpa_s->conf->manufacturer);
		p2p_set_model_name(p2p, wpa_s->conf->model_name);
		p2p_set_model_number(p2p, wpa_s->conf->model_number);
		p2p_set_serial_number(p2p, wpa_s->conf->serial_number);
	}

	if (wpa_s->conf->changed_parameters & CFG_CHANGED_SEC_DEVICE_TYPE)
		p2p_set_sec_dev_types(p2p,
				      (void *) wpa_s->conf->sec_device_type,
				      wpa_s->conf->num_sec_device_types);

	if (wpa_s->conf->changed_parameters & CFG_CHANGED_VENDOR_EXTENSION) {
		int i;
		p2p_remove_wps_vendor_extensions(p2p);
		for (i = 0; i < MAX_WPS_VENDOR_EXT; i++) {
			if (wpa_s->conf->wps_vendor_ext[i] == NULL)
				continue;
			p2p_add_wps_vendor_extension(
				p2p, wpa_s->conf->wps_vendor_ext[i]);
		}
	}

	if ((wpa_s->conf->changed_parameters & CFG_CHANGED_COUNTRY) &&
	    wpa_s->conf->country[0] && wpa_s->conf->country[1]) {
		char country[3];
		country[0] = wpa_s->conf->country[0];
		country[1] = wpa_s->conf->country[1];
		country[2] = 0x04;
		p2p_set_country(p2p, country);
	}

	if (wpa_s->conf->changed_parameters & CFG_CHANGED_P2P_SSID_POSTFIX) {
		p2p_set_ssid_postfix(p2p, (u8 *) wpa_s->conf->p2p_ssid_postfix,
				     wpa_s->conf->p2p_ssid_postfix ?
				     os_strlen(wpa_s->conf->p2p_ssid_postfix) :
				     0);
	}

	if (wpa_s->conf->changed_parameters & CFG_CHANGED_P2P_INTRA_BSS)
		p2p_set_intra_bss_dist(p2p, wpa_s->conf->p2p_intra_bss);

	if (wpa_s->conf->changed_parameters & CFG_CHANGED_P2P_LISTEN_CHANNEL) {
		u8 reg_class, channel;
		int ret;
		unsigned int r;
		u8 channel_forced;

		if (wpa_s->conf->p2p_listen_reg_class &&
		    wpa_s->conf->p2p_listen_channel) {
			reg_class = wpa_s->conf->p2p_listen_reg_class;
			channel = wpa_s->conf->p2p_listen_channel;
			channel_forced = 1;
		} else {
			reg_class = 81;
			/*
			 * Pick one of the social channels randomly as the
			 * listen channel.
			 */
			if (os_get_random((u8 *) &r, sizeof(r)) < 0)
				channel = 1;
			else
				channel = 1 + (r % 3) * 5;
			channel_forced = 0;
		}
		ret = p2p_set_listen_channel(p2p, reg_class, channel,
					     channel_forced);
		if (ret)
			wpa_printf(MSG_ERROR, "P2P: Own listen channel update "
				   "failed: %d", ret);
	}
	if (wpa_s->conf->changed_parameters & CFG_CHANGED_P2P_OPER_CHANNEL) {
		u8 op_reg_class, op_channel, cfg_op_channel;
		int ret = 0;
		unsigned int r;
		if (wpa_s->conf->p2p_oper_reg_class &&
		    wpa_s->conf->p2p_oper_channel) {
			op_reg_class = wpa_s->conf->p2p_oper_reg_class;
			op_channel = wpa_s->conf->p2p_oper_channel;
			cfg_op_channel = 1;
		} else {
			op_reg_class = 81;
			/*
			 * Use random operation channel from (1, 6, 11)
			 *if no other preference is indicated.
			 */
			if (os_get_random((u8 *) &r, sizeof(r)) < 0)
				op_channel = 1;
			else
				op_channel = 1 + (r % 3) * 5;
			cfg_op_channel = 0;
		}
		ret = p2p_set_oper_channel(p2p, op_reg_class, op_channel,
					   cfg_op_channel);
		if (ret)
			wpa_printf(MSG_ERROR, "P2P: Own oper channel update "
				   "failed: %d", ret);
	}

	if (wpa_s->conf->changed_parameters & CFG_CHANGED_P2P_PREF_CHAN) {
		if (p2p_set_pref_chan(p2p, wpa_s->conf->num_p2p_pref_chan,
				      wpa_s->conf->p2p_pref_chan) < 0) {
			wpa_printf(MSG_ERROR, "P2P: Preferred channel list "
				   "update failed");
		}

		if (p2p_set_no_go_freq(p2p, &wpa_s->conf->p2p_no_go_freq) < 0) {
			wpa_printf(MSG_ERROR, "P2P: No GO channel list "
				   "update failed");
		}
	}

	if (wpa_s->conf->changed_parameters & CFG_CHANGED_P2P_PASSPHRASE_LEN)
		p2p_set_passphrase_len(p2p, wpa_s->conf->p2p_passphrase_len);
}


int wpas_p2p_set_noa(struct wpa_supplicant *wpa_s, u8 count, int start,
		     int duration)
{
	if (!wpa_s->ap_iface)
		return -1;
	return hostapd_p2p_set_noa(wpa_s->ap_iface->bss[0], count, start,
				   duration);
}


int wpas_p2p_set_cross_connect(struct wpa_supplicant *wpa_s, int enabled)
{
	if (wpa_s->global->p2p_disabled || wpa_s->global->p2p == NULL)
		return -1;

	wpa_s->global->cross_connection = enabled;
	p2p_set_cross_connect(wpa_s->global->p2p, enabled);

	if (!enabled) {
		struct wpa_supplicant *iface;

		for (iface = wpa_s->global->ifaces; iface; iface = iface->next)
		{
			if (iface->cross_connect_enabled == 0)
				continue;

			iface->cross_connect_enabled = 0;
			iface->cross_connect_in_use = 0;
			wpa_msg_global(iface->p2pdev, MSG_INFO,
				       P2P_EVENT_CROSS_CONNECT_DISABLE "%s %s",
				       iface->ifname,
				       iface->cross_connect_uplink);
		}
	}

	return 0;
}


static void wpas_p2p_enable_cross_connect(struct wpa_supplicant *uplink)
{
	struct wpa_supplicant *iface;

	if (!uplink->global->cross_connection)
		return;

	for (iface = uplink->global->ifaces; iface; iface = iface->next) {
		if (!iface->cross_connect_enabled)
			continue;
		if (os_strcmp(uplink->ifname, iface->cross_connect_uplink) !=
		    0)
			continue;
		if (iface->ap_iface == NULL)
			continue;
		if (iface->cross_connect_in_use)
			continue;

		iface->cross_connect_in_use = 1;
		wpa_msg_global(iface->p2pdev, MSG_INFO,
			       P2P_EVENT_CROSS_CONNECT_ENABLE "%s %s",
			       iface->ifname, iface->cross_connect_uplink);
	}
}


static void wpas_p2p_disable_cross_connect(struct wpa_supplicant *uplink)
{
	struct wpa_supplicant *iface;

	for (iface = uplink->global->ifaces; iface; iface = iface->next) {
		if (!iface->cross_connect_enabled)
			continue;
		if (os_strcmp(uplink->ifname, iface->cross_connect_uplink) !=
		    0)
			continue;
		if (!iface->cross_connect_in_use)
			continue;

		wpa_msg_global(iface->p2pdev, MSG_INFO,
			       P2P_EVENT_CROSS_CONNECT_DISABLE "%s %s",
			       iface->ifname, iface->cross_connect_uplink);
		iface->cross_connect_in_use = 0;
	}
}


void wpas_p2p_notif_connected(struct wpa_supplicant *wpa_s)
{
	if (wpa_s->ap_iface || wpa_s->current_ssid == NULL ||
	    wpa_s->current_ssid->mode != WPAS_MODE_INFRA ||
	    wpa_s->cross_connect_disallowed)
		wpas_p2p_disable_cross_connect(wpa_s);
	else
		wpas_p2p_enable_cross_connect(wpa_s);
	if (!wpa_s->ap_iface &&
	    eloop_cancel_timeout(wpas_p2p_group_idle_timeout, wpa_s, NULL) > 0)
		wpa_printf(MSG_DEBUG, "P2P: Cancelled P2P group idle timeout");
}


void wpas_p2p_notif_disconnected(struct wpa_supplicant *wpa_s)
{
	wpas_p2p_disable_cross_connect(wpa_s);
	if (!wpa_s->ap_iface &&
	    !eloop_is_timeout_registered(wpas_p2p_group_idle_timeout,
					 wpa_s, NULL))
		wpas_p2p_set_group_idle_timeout(wpa_s);
}


static void wpas_p2p_cross_connect_setup(struct wpa_supplicant *wpa_s)
{
	struct wpa_supplicant *iface;

	if (!wpa_s->global->cross_connection)
		return;

	for (iface = wpa_s->global->ifaces; iface; iface = iface->next) {
		if (iface == wpa_s)
			continue;
		if (iface->drv_flags &
		    WPA_DRIVER_FLAGS_P2P_DEDICATED_INTERFACE)
			continue;
		if ((iface->drv_flags & WPA_DRIVER_FLAGS_P2P_CAPABLE) &&
		    iface != wpa_s->parent)
			continue;

		wpa_s->cross_connect_enabled = 1;
		os_strlcpy(wpa_s->cross_connect_uplink, iface->ifname,
			   sizeof(wpa_s->cross_connect_uplink));
		wpa_printf(MSG_DEBUG, "P2P: Enable cross connection from "
			   "%s to %s whenever uplink is available",
			   wpa_s->ifname, wpa_s->cross_connect_uplink);

		if (iface->ap_iface || iface->current_ssid == NULL ||
		    iface->current_ssid->mode != WPAS_MODE_INFRA ||
		    iface->cross_connect_disallowed ||
		    iface->wpa_state != WPA_COMPLETED)
			break;

		wpa_s->cross_connect_in_use = 1;
		wpa_msg_global(wpa_s->p2pdev, MSG_INFO,
			       P2P_EVENT_CROSS_CONNECT_ENABLE "%s %s",
			       wpa_s->ifname, wpa_s->cross_connect_uplink);
		break;
	}
}


int wpas_p2p_notif_pbc_overlap(struct wpa_supplicant *wpa_s)
{
	if (wpa_s->p2p_group_interface != P2P_GROUP_INTERFACE_CLIENT &&
	    !wpa_s->p2p_in_provisioning)
		return 0; /* not P2P client operation */

	wpa_printf(MSG_DEBUG, "P2P: Terminate connection due to WPS PBC "
		   "session overlap");
	if (wpa_s != wpa_s->p2pdev)
		wpa_msg_ctrl(wpa_s->p2pdev, MSG_INFO, WPS_EVENT_OVERLAP);
	wpas_p2p_group_formation_failed(wpa_s, 0);
	return 1;
}


void wpas_p2p_pbc_overlap_cb(void *eloop_ctx, void *timeout_ctx)
{
	struct wpa_supplicant *wpa_s = eloop_ctx;
	wpas_p2p_notif_pbc_overlap(wpa_s);
}


void wpas_p2p_update_channel_list(struct wpa_supplicant *wpa_s,
				  enum wpas_p2p_channel_update_trig trig)
{
	struct p2p_channels chan, cli_chan;
	struct wpa_used_freq_data *freqs = NULL;
	unsigned int num = wpa_s->num_multichan_concurrent;

	if (wpa_s->global == NULL || wpa_s->global->p2p == NULL)
		return;

	freqs = os_calloc(num, sizeof(struct wpa_used_freq_data));
	if (!freqs)
		return;

	num = get_shared_radio_freqs_data(wpa_s, freqs, num);

	os_memset(&chan, 0, sizeof(chan));
	os_memset(&cli_chan, 0, sizeof(cli_chan));
	if (wpas_p2p_setup_channels(wpa_s, &chan, &cli_chan,
				    is_p2p_6ghz_disabled(wpa_s->global->p2p))) {
		wpa_printf(MSG_ERROR, "P2P: Failed to update supported "
			   "channel list");
		return;
	}

	p2p_update_channel_list(wpa_s->global->p2p, &chan, &cli_chan);

	wpas_p2p_optimize_listen_channel(wpa_s, freqs, num);

	/*
	 * The used frequencies map changed, so it is possible that a GO is
	 * using a channel that is no longer valid for P2P use. It is also
	 * possible that due to policy consideration, it would be preferable to
	 * move it to a frequency already used by other station interfaces.
	 */
	wpas_p2p_consider_moving_gos(wpa_s, freqs, num, trig);

	os_free(freqs);
}


static void wpas_p2p_scan_res_ignore(struct wpa_supplicant *wpa_s,
				     struct wpa_scan_results *scan_res)
{
	wpa_printf(MSG_DEBUG, "P2P: Ignore scan results");
}


int wpas_p2p_cancel(struct wpa_supplicant *wpa_s)
{
	struct wpa_global *global = wpa_s->global;
	int found = 0;
	const u8 *peer;

	if (global->p2p == NULL)
		return -1;

	wpa_printf(MSG_DEBUG, "P2P: Request to cancel group formation");

	if (wpa_s->pending_interface_name[0] &&
	    !is_zero_ether_addr(wpa_s->pending_interface_addr))
		found = 1;

	peer = p2p_get_go_neg_peer(global->p2p);
	if (peer) {
		wpa_printf(MSG_DEBUG, "P2P: Unauthorize pending GO Neg peer "
			   MACSTR, MAC2STR(peer));
		p2p_unauthorize(global->p2p, peer);
		found = 1;
	}

	if (wpa_s->scan_res_handler == wpas_p2p_scan_res_join) {
		wpa_printf(MSG_DEBUG, "P2P: Stop pending scan for join");
		wpa_s->scan_res_handler = wpas_p2p_scan_res_ignore;
		found = 1;
	}

	if (wpa_s->pending_pd_before_join) {
		wpa_printf(MSG_DEBUG, "P2P: Stop pending PD before join");
		wpa_s->pending_pd_before_join = 0;
		found = 1;
	}

	wpas_p2p_stop_find(wpa_s);

	for (wpa_s = global->ifaces; wpa_s; wpa_s = wpa_s->next) {
		if (wpa_s == global->p2p_group_formation &&
		    (wpa_s->p2p_in_provisioning ||
		     wpa_s->parent->pending_interface_type ==
		     WPA_IF_P2P_CLIENT)) {
			wpa_printf(MSG_DEBUG, "P2P: Interface %s in group "
				   "formation found - cancelling",
				   wpa_s->ifname);
			found = 1;
			eloop_cancel_timeout(wpas_p2p_group_formation_timeout,
					     wpa_s->p2pdev, NULL);
			if (wpa_s->p2p_in_provisioning) {
				wpas_group_formation_completed(wpa_s, 0, 0);
				break;
			}
			wpas_p2p_group_delete(wpa_s,
					      P2P_GROUP_REMOVAL_REQUESTED);
			break;
		} else if (wpa_s->p2p_in_invitation) {
			wpa_printf(MSG_DEBUG, "P2P: Interface %s in invitation found - cancelling",
				   wpa_s->ifname);
			found = 1;
			wpas_p2p_group_formation_failed(wpa_s, 0);
			break;
		}
	}

	if (!found) {
		wpa_printf(MSG_DEBUG, "P2P: No ongoing group formation found");
		return -1;
	}

	return 0;
}


void wpas_p2p_interface_unavailable(struct wpa_supplicant *wpa_s)
{
	if (wpa_s->current_ssid == NULL || !wpa_s->current_ssid->p2p_group)
		return;

	wpa_printf(MSG_DEBUG, "P2P: Remove group due to driver resource not "
		   "being available anymore");
	wpas_p2p_group_delete(wpa_s, P2P_GROUP_REMOVAL_UNAVAILABLE);
}


void wpas_p2p_update_best_channels(struct wpa_supplicant *wpa_s,
				   int freq_24, int freq_5, int freq_overall)
{
	struct p2p_data *p2p = wpa_s->global->p2p;
	if (p2p == NULL)
		return;
	p2p_set_best_channels(p2p, freq_24, freq_5, freq_overall);
}


int wpas_p2p_unauthorize(struct wpa_supplicant *wpa_s, const char *addr)
{
	u8 peer[ETH_ALEN];
	struct p2p_data *p2p = wpa_s->global->p2p;

	if (p2p == NULL)
		return -1;

	if (hwaddr_aton(addr, peer))
		return -1;

	return p2p_unauthorize(p2p, peer);
}


/**
 * wpas_p2p_disconnect - Disconnect from a P2P Group
 * @wpa_s: Pointer to wpa_supplicant data
 * Returns: 0 on success, -1 on failure
 *
 * This can be used to disconnect from a group in which the local end is a P2P
 * Client or to end a P2P Group in case the local end is the Group Owner. If a
 * virtual network interface was created for this group, that interface will be
 * removed. Otherwise, only the configured P2P group network will be removed
 * from the interface.
 */
int wpas_p2p_disconnect(struct wpa_supplicant *wpa_s)
{

	if (wpa_s == NULL)
		return -1;

	return wpas_p2p_group_delete(wpa_s, P2P_GROUP_REMOVAL_REQUESTED) < 0 ?
		-1 : 0;
}


int wpas_p2p_in_progress(struct wpa_supplicant *wpa_s)
{
	int ret;

	if (wpa_s->global->p2p_disabled || wpa_s->global->p2p == NULL)
		return 0;

	ret = p2p_in_progress(wpa_s->global->p2p);
	if (ret == 0) {
		/*
		 * Check whether there is an ongoing WPS provisioning step (or
		 * other parts of group formation) on another interface since
		 * p2p_in_progress() does not report this to avoid issues for
		 * scans during such provisioning step.
		 */
		if (wpa_s->global->p2p_group_formation &&
		    wpa_s->global->p2p_group_formation != wpa_s) {
			wpa_dbg(wpa_s, MSG_DEBUG, "P2P: Another interface (%s) "
				"in group formation",
				wpa_s->global->p2p_group_formation->ifname);
			ret = 1;
		}
	}

	if (!ret && wpa_s->global->p2p_go_wait_client.sec) {
		struct os_reltime now;
		os_get_reltime(&now);
		if (os_reltime_expired(&now, &wpa_s->global->p2p_go_wait_client,
				       P2P_MAX_INITIAL_CONN_WAIT_GO)) {
			/* Wait for the first client has expired */
			wpa_s->global->p2p_go_wait_client.sec = 0;
		} else {
			wpa_dbg(wpa_s, MSG_DEBUG, "P2P: Waiting for initial client connection during group formation");
			ret = 1;
		}
	}

	return ret;
}


void wpas_p2p_network_removed(struct wpa_supplicant *wpa_s,
			      struct wpa_ssid *ssid)
{
	if (wpa_s->p2p_in_provisioning && ssid->p2p_group &&
	    eloop_cancel_timeout(wpas_p2p_group_formation_timeout,
				 wpa_s->p2pdev, NULL) > 0) {
		/**
		 * Remove the network by scheduling the group formation
		 * timeout to happen immediately. The teardown code
		 * needs to be scheduled to run asynch later so that we
		 * don't delete data from under ourselves unexpectedly.
		 * Calling wpas_p2p_group_formation_timeout directly
		 * causes a series of crashes in WPS failure scenarios.
		 */
		wpa_printf(MSG_DEBUG, "P2P: Canceled group formation due to "
			   "P2P group network getting removed");
		eloop_register_timeout(0, 0, wpas_p2p_group_formation_timeout,
				       wpa_s->p2pdev, NULL);
	}
}


struct wpa_ssid * wpas_p2p_get_persistent(struct wpa_supplicant *wpa_s,
					  const u8 *addr, const u8 *ssid,
					  size_t ssid_len)
{
	struct wpa_ssid *s;
	size_t i;

	for (s = wpa_s->conf->ssid; s; s = s->next) {
		if (s->disabled != 2)
			continue;
		if (ssid &&
		    (ssid_len != s->ssid_len ||
		     os_memcmp(ssid, s->ssid, ssid_len) != 0))
			continue;
		if (addr == NULL) {
			if (s->mode == WPAS_MODE_P2P_GO)
				return s;
			continue;
		}
		if (os_memcmp(s->bssid, addr, ETH_ALEN) == 0)
			return s; /* peer is GO in the persistent group */
		if (s->mode != WPAS_MODE_P2P_GO || s->p2p_client_list == NULL)
			continue;
		for (i = 0; i < s->num_p2p_clients; i++) {
			if (os_memcmp(s->p2p_client_list + i * 2 * ETH_ALEN,
				      addr, ETH_ALEN) == 0)
				return s; /* peer is P2P client in persistent
					   * group */
		}
	}

	return NULL;
}


void wpas_p2p_notify_ap_sta_authorized(struct wpa_supplicant *wpa_s,
				       const u8 *addr)
{
	if (eloop_cancel_timeout(wpas_p2p_group_formation_timeout,
				 wpa_s->p2pdev, NULL) > 0) {
		/*
		 * This can happen if WPS provisioning step is not terminated
		 * cleanly (e.g., P2P Client does not send WSC_Done). Since the
		 * peer was able to connect, there is no need to time out group
		 * formation after this, though. In addition, this is used with
		 * the initial connection wait on the GO as a separate formation
		 * timeout and as such, expected to be hit after the initial WPS
		 * provisioning step.
		 */
		wpa_printf(MSG_DEBUG, "P2P: Canceled P2P group formation timeout on data connection");

		if (!wpa_s->p2p_go_group_formation_completed &&
		    !wpa_s->group_formation_reported) {
			/*
			 * GO has not yet notified group formation success since
			 * the WPS step was not completed cleanly. Do that
			 * notification now since the P2P Client was able to
			 * connect and as such, must have received the
			 * credential from the WPS step.
			 */
			if (wpa_s->global->p2p)
				p2p_wps_success_cb(wpa_s->global->p2p, addr);
			wpas_group_formation_completed(wpa_s, 1, 0);
		}
	}
	if (!wpa_s->p2p_go_group_formation_completed) {
		wpa_dbg(wpa_s, MSG_DEBUG, "P2P: Marking group formation completed on GO on first data connection");
		wpa_s->p2p_go_group_formation_completed = 1;
		wpa_s->global->p2p_group_formation = NULL;
		wpa_s->p2p_in_provisioning = 0;
		wpa_s->p2p_in_invitation = 0;
	}
	wpa_s->global->p2p_go_wait_client.sec = 0;
	if (addr == NULL)
		return;
	wpas_p2p_add_persistent_group_client(wpa_s, addr);
}


static int wpas_p2p_fallback_to_go_neg(struct wpa_supplicant *wpa_s,
				       int group_added)
{
	struct wpa_supplicant *group = wpa_s;
	int ret = 0;

	if (wpa_s->global->p2p_group_formation)
		group = wpa_s->global->p2p_group_formation;
	wpa_s = wpa_s->global->p2p_init_wpa_s;
	offchannel_send_action_done(wpa_s);
	if (group_added)
		ret = wpas_p2p_group_delete(group, P2P_GROUP_REMOVAL_SILENT);
	wpa_dbg(wpa_s, MSG_DEBUG, "P2P: Fall back to GO Negotiation");
	wpas_p2p_connect(wpa_s, wpa_s->pending_join_dev_addr, wpa_s->p2p_pin,
			 wpa_s->p2p_wps_method, wpa_s->p2p_persistent_group, 0,
			 0, 0, wpa_s->p2p_go_intent, wpa_s->p2p_connect_freq,
			 wpa_s->p2p_go_vht_center_freq2,
			 wpa_s->p2p_persistent_id,
			 wpa_s->p2p_pd_before_go_neg,
			 wpa_s->p2p_go_ht40,
			 wpa_s->p2p_go_vht,
			 wpa_s->p2p_go_max_oper_chwidth,
			 wpa_s->p2p_go_he,
			 wpa_s->p2p_go_edmg,
			 NULL, 0, is_p2p_allow_6ghz(wpa_s->global->p2p));
	return ret;
}


int wpas_p2p_scan_no_go_seen(struct wpa_supplicant *wpa_s)
{
	int res;

	if (!wpa_s->p2p_fallback_to_go_neg ||
	    wpa_s->p2p_in_provisioning <= 5)
		return 0;

	if (wpas_p2p_peer_go(wpa_s, wpa_s->pending_join_dev_addr) > 0)
		return 0; /* peer operating as a GO */

	wpa_dbg(wpa_s, MSG_DEBUG, "P2P: GO not found for p2p_connect-auto - "
		"fallback to GO Negotiation");
	wpa_msg_global(wpa_s->p2pdev, MSG_INFO, P2P_EVENT_FALLBACK_TO_GO_NEG
		       "reason=GO-not-found");
	res = wpas_p2p_fallback_to_go_neg(wpa_s, 1);

	return res == 1 ? 2 : 1;
}


unsigned int wpas_p2p_search_delay(struct wpa_supplicant *wpa_s)
{
	struct wpa_supplicant *ifs;

	if (wpa_s->wpa_state > WPA_SCANNING) {
		wpa_dbg(wpa_s, MSG_DEBUG, "P2P: Use %u ms search delay due to "
			"concurrent operation",
			wpa_s->conf->p2p_search_delay);
		return wpa_s->conf->p2p_search_delay;
	}

	dl_list_for_each(ifs, &wpa_s->radio->ifaces, struct wpa_supplicant,
			 radio_list) {
		if (ifs != wpa_s && ifs->wpa_state > WPA_SCANNING) {
			wpa_dbg(wpa_s, MSG_DEBUG, "P2P: Use %u ms search "
				"delay due to concurrent operation on "
				"interface %s",
				wpa_s->conf->p2p_search_delay,
				ifs->ifname);
			return wpa_s->conf->p2p_search_delay;
		}
	}

	return 0;
}


static int wpas_p2p_remove_psk_entry(struct wpa_supplicant *wpa_s,
				     struct wpa_ssid *s, const u8 *addr,
				     int iface_addr)
{
	struct psk_list_entry *psk, *tmp;
	int changed = 0;

	dl_list_for_each_safe(psk, tmp, &s->psk_list, struct psk_list_entry,
			      list) {
		if ((iface_addr && !psk->p2p &&
		     os_memcmp(addr, psk->addr, ETH_ALEN) == 0) ||
		    (!iface_addr && psk->p2p &&
		     os_memcmp(addr, psk->addr, ETH_ALEN) == 0)) {
			wpa_dbg(wpa_s, MSG_DEBUG,
				"P2P: Remove persistent group PSK list entry for "
				MACSTR " p2p=%u",
				MAC2STR(psk->addr), psk->p2p);
			dl_list_del(&psk->list);
			os_free(psk);
			changed++;
		}
	}

	return changed;
}


void wpas_p2p_new_psk_cb(struct wpa_supplicant *wpa_s, const u8 *mac_addr,
			 const u8 *p2p_dev_addr,
			 const u8 *psk, size_t psk_len)
{
	struct wpa_ssid *ssid = wpa_s->current_ssid;
	struct wpa_ssid *persistent;
	struct psk_list_entry *p, *last;

	if (psk_len != sizeof(p->psk))
		return;

	if (p2p_dev_addr) {
		wpa_dbg(wpa_s, MSG_DEBUG, "P2P: New PSK for addr=" MACSTR
			" p2p_dev_addr=" MACSTR,
			MAC2STR(mac_addr), MAC2STR(p2p_dev_addr));
		if (is_zero_ether_addr(p2p_dev_addr))
			p2p_dev_addr = NULL;
	} else {
		wpa_dbg(wpa_s, MSG_DEBUG, "P2P: New PSK for addr=" MACSTR,
			MAC2STR(mac_addr));
	}

	if (ssid->mode == WPAS_MODE_P2P_GROUP_FORMATION) {
		wpa_dbg(wpa_s, MSG_DEBUG, "P2P: new_psk_cb during group formation");
		/* To be added to persistent group once created */
		if (wpa_s->global->add_psk == NULL) {
			wpa_s->global->add_psk = os_zalloc(sizeof(*p));
			if (wpa_s->global->add_psk == NULL)
				return;
		}
		p = wpa_s->global->add_psk;
		if (p2p_dev_addr) {
			p->p2p = 1;
			os_memcpy(p->addr, p2p_dev_addr, ETH_ALEN);
		} else {
			p->p2p = 0;
			os_memcpy(p->addr, mac_addr, ETH_ALEN);
		}
		os_memcpy(p->psk, psk, psk_len);
		return;
	}

	if (ssid->mode != WPAS_MODE_P2P_GO || !ssid->p2p_persistent_group) {
		wpa_dbg(wpa_s, MSG_DEBUG, "P2P: Ignore new_psk_cb on not-persistent GO");
		return;
	}

	persistent = wpas_p2p_get_persistent(wpa_s->p2pdev, NULL, ssid->ssid,
					     ssid->ssid_len);
	if (!persistent) {
		wpa_dbg(wpa_s, MSG_DEBUG, "P2P: Could not find persistent group information to store the new PSK");
		return;
	}

	p = os_zalloc(sizeof(*p));
	if (p == NULL)
		return;
	if (p2p_dev_addr) {
		p->p2p = 1;
		os_memcpy(p->addr, p2p_dev_addr, ETH_ALEN);
	} else {
		p->p2p = 0;
		os_memcpy(p->addr, mac_addr, ETH_ALEN);
	}
	os_memcpy(p->psk, psk, psk_len);

	if (dl_list_len(&persistent->psk_list) > P2P_MAX_STORED_CLIENTS &&
	    (last = dl_list_last(&persistent->psk_list,
				 struct psk_list_entry, list))) {
		wpa_dbg(wpa_s, MSG_DEBUG, "P2P: Remove oldest PSK entry for "
			MACSTR " (p2p=%u) to make room for a new one",
			MAC2STR(last->addr), last->p2p);
		dl_list_del(&last->list);
		os_free(last);
	}

	wpas_p2p_remove_psk_entry(wpa_s->p2pdev, persistent,
				  p2p_dev_addr ? p2p_dev_addr : mac_addr,
				  p2p_dev_addr == NULL);
	if (p2p_dev_addr) {
		wpa_dbg(wpa_s, MSG_DEBUG, "P2P: Add new PSK for p2p_dev_addr="
			MACSTR, MAC2STR(p2p_dev_addr));
	} else {
		wpa_dbg(wpa_s, MSG_DEBUG, "P2P: Add new PSK for addr=" MACSTR,
			MAC2STR(mac_addr));
	}
	dl_list_add(&persistent->psk_list, &p->list);

	if (wpa_s->p2pdev->conf->update_config &&
	    wpa_config_write(wpa_s->p2pdev->confname, wpa_s->p2pdev->conf))
		wpa_printf(MSG_DEBUG, "P2P: Failed to update configuration");
}


static void wpas_p2p_remove_psk(struct wpa_supplicant *wpa_s,
				struct wpa_ssid *s, const u8 *addr,
				int iface_addr)
{
	int res;

	res = wpas_p2p_remove_psk_entry(wpa_s, s, addr, iface_addr);
	if (res > 0 && wpa_s->conf->update_config &&
	    wpa_config_write(wpa_s->confname, wpa_s->conf))
		wpa_dbg(wpa_s, MSG_DEBUG,
			"P2P: Failed to update configuration");
}


static void wpas_p2p_remove_client_go(struct wpa_supplicant *wpa_s,
				      const u8 *peer, int iface_addr)
{
	struct hostapd_data *hapd;
	struct hostapd_wpa_psk *psk, *prev, *rem;
	struct sta_info *sta;

	if (wpa_s->ap_iface == NULL || wpa_s->current_ssid == NULL ||
	    wpa_s->current_ssid->mode != WPAS_MODE_P2P_GO)
		return;

	/* Remove per-station PSK entry */
	hapd = wpa_s->ap_iface->bss[0];
	prev = NULL;
	psk = hapd->conf->ssid.wpa_psk;
	while (psk) {
		if ((iface_addr && os_memcmp(peer, psk->addr, ETH_ALEN) == 0) ||
		    (!iface_addr &&
		     os_memcmp(peer, psk->p2p_dev_addr, ETH_ALEN) == 0)) {
			wpa_dbg(wpa_s, MSG_DEBUG, "P2P: Remove operating group PSK entry for "
				MACSTR " iface_addr=%d",
				MAC2STR(peer), iface_addr);
			if (prev)
				prev->next = psk->next;
			else
				hapd->conf->ssid.wpa_psk = psk->next;
			rem = psk;
			psk = psk->next;
			os_free(rem);
		} else {
			prev = psk;
			psk = psk->next;
		}
	}

	/* Disconnect from group */
	if (iface_addr)
		sta = ap_get_sta(hapd, peer);
	else
		sta = ap_get_sta_p2p(hapd, peer);
	if (sta) {
		wpa_dbg(wpa_s, MSG_DEBUG, "P2P: Disconnect peer " MACSTR
			" (iface_addr=%d) from group",
			MAC2STR(peer), iface_addr);
		hostapd_drv_sta_deauth(hapd, sta->addr,
				       WLAN_REASON_DEAUTH_LEAVING);
		ap_sta_deauthenticate(hapd, sta, WLAN_REASON_DEAUTH_LEAVING);
	}
}


void wpas_p2p_remove_client(struct wpa_supplicant *wpa_s, const u8 *peer,
			    int iface_addr)
{
	struct wpa_ssid *s;
	struct wpa_supplicant *w;
	struct wpa_supplicant *p2p_wpa_s = wpa_s->global->p2p_init_wpa_s;

	wpa_dbg(wpa_s, MSG_DEBUG, "P2P: Remove client " MACSTR, MAC2STR(peer));

	/* Remove from any persistent group */
	for (s = p2p_wpa_s->conf->ssid; s; s = s->next) {
		if (s->disabled != 2 || s->mode != WPAS_MODE_P2P_GO)
			continue;
		if (!iface_addr)
			wpas_remove_persistent_peer(p2p_wpa_s, s, peer, 0);
		wpas_p2p_remove_psk(p2p_wpa_s, s, peer, iface_addr);
	}

	/* Remove from any operating group */
	for (w = wpa_s->global->ifaces; w; w = w->next)
		wpas_p2p_remove_client_go(w, peer, iface_addr);
}


static void wpas_p2p_psk_failure_removal(void *eloop_ctx, void *timeout_ctx)
{
	struct wpa_supplicant *wpa_s = eloop_ctx;
	wpas_p2p_group_delete(wpa_s, P2P_GROUP_REMOVAL_PSK_FAILURE);
}


static void wpas_p2p_group_freq_conflict(void *eloop_ctx, void *timeout_ctx)
{
	struct wpa_supplicant *wpa_s = eloop_ctx;

	wpa_printf(MSG_DEBUG, "P2P: Frequency conflict - terminate group");
	wpas_p2p_group_delete(wpa_s, P2P_GROUP_REMOVAL_FREQ_CONFLICT);
}


int wpas_p2p_handle_frequency_conflicts(struct wpa_supplicant *wpa_s, int freq,
					struct wpa_ssid *ssid)
{
	struct wpa_supplicant *iface;

	for (iface = wpa_s->global->ifaces; iface; iface = iface->next) {
		if (!iface->current_ssid ||
		    iface->current_ssid->frequency == freq ||
		    (iface->p2p_group_interface == NOT_P2P_GROUP_INTERFACE &&
		     !iface->current_ssid->p2p_group))
			continue;

		/* Remove the connection with least priority */
		if (!wpas_is_p2p_prioritized(iface)) {
			/* STA connection has priority over existing
			 * P2P connection, so remove the interface. */
			wpa_printf(MSG_DEBUG, "P2P: Removing P2P connection due to single channel concurrent mode frequency conflict");
			eloop_register_timeout(0, 0,
					       wpas_p2p_group_freq_conflict,
					       iface, NULL);
			/* If connection in progress is P2P connection, do not
			 * proceed for the connection. */
			if (wpa_s == iface)
				return -1;
			else
				return 0;
		} else {
			/* P2P connection has priority, disable the STA network
			 */
			wpa_supplicant_disable_network(wpa_s->global->ifaces,
						       ssid);
			wpa_msg(wpa_s->global->ifaces, MSG_INFO,
				WPA_EVENT_FREQ_CONFLICT " id=%d", ssid->id);
			os_memset(wpa_s->global->ifaces->pending_bssid, 0,
				  ETH_ALEN);
			/* If P2P connection is in progress, continue
			 * connecting...*/
			if (wpa_s == iface)
				return 0;
			else
				return -1;
		}
	}

	return 0;
}


int wpas_p2p_4way_hs_failed(struct wpa_supplicant *wpa_s)
{
	struct wpa_ssid *ssid = wpa_s->current_ssid;

	if (ssid == NULL || !ssid->p2p_group)
		return 0;

	if (wpa_s->p2p_last_4way_hs_fail &&
	    wpa_s->p2p_last_4way_hs_fail == ssid) {
		u8 go_dev_addr[ETH_ALEN];
		struct wpa_ssid *persistent;

		if (wpas_p2p_persistent_group(wpa_s, go_dev_addr,
					      ssid->ssid,
					      ssid->ssid_len) <= 0) {
			wpa_dbg(wpa_s, MSG_DEBUG, "P2P: Could not determine whether 4-way handshake failures were for a persistent group");
			goto disconnect;
		}

		wpa_dbg(wpa_s, MSG_DEBUG, "P2P: Two 4-way handshake failures for a P2P group - go_dev_addr="
			MACSTR, MAC2STR(go_dev_addr));
		persistent = wpas_p2p_get_persistent(wpa_s->p2pdev, go_dev_addr,
						     ssid->ssid,
						     ssid->ssid_len);
		if (persistent == NULL || persistent->mode != WPAS_MODE_INFRA) {
			wpa_dbg(wpa_s, MSG_DEBUG, "P2P: No matching persistent group stored");
			goto disconnect;
		}
		wpa_msg_global(wpa_s->p2pdev, MSG_INFO,
			       P2P_EVENT_PERSISTENT_PSK_FAIL "%d",
			       persistent->id);
	disconnect:
		wpa_s->p2p_last_4way_hs_fail = NULL;
		/*
		 * Remove the group from a timeout to avoid issues with caller
		 * continuing to use the interface if this is on a P2P group
		 * interface.
		 */
		eloop_register_timeout(0, 0, wpas_p2p_psk_failure_removal,
				       wpa_s, NULL);
		return 1;
	}

	wpa_s->p2p_last_4way_hs_fail = ssid;
	return 0;
}


#ifdef CONFIG_WPS_NFC

static struct wpabuf * wpas_p2p_nfc_handover(int ndef, struct wpabuf *wsc,
					     struct wpabuf *p2p)
{
	struct wpabuf *ret;
	size_t wsc_len;

	if (p2p == NULL) {
		wpabuf_free(wsc);
		wpa_printf(MSG_DEBUG, "P2P: No p2p buffer for handover");
		return NULL;
	}

	wsc_len = wsc ? wpabuf_len(wsc) : 0;
	ret = wpabuf_alloc(2 + wsc_len + 2 + wpabuf_len(p2p));
	if (ret == NULL) {
		wpabuf_free(wsc);
		wpabuf_free(p2p);
		return NULL;
	}

	wpabuf_put_be16(ret, wsc_len);
	if (wsc)
		wpabuf_put_buf(ret, wsc);
	wpabuf_put_be16(ret, wpabuf_len(p2p));
	wpabuf_put_buf(ret, p2p);

	wpabuf_free(wsc);
	wpabuf_free(p2p);
	wpa_hexdump_buf(MSG_DEBUG,
			"P2P: Generated NFC connection handover message", ret);

	if (ndef && ret) {
		struct wpabuf *tmp;
		tmp = ndef_build_p2p(ret);
		wpabuf_free(ret);
		if (tmp == NULL) {
			wpa_printf(MSG_DEBUG, "P2P: Failed to NDEF encapsulate handover request");
			return NULL;
		}
		ret = tmp;
	}

	return ret;
}


static int wpas_p2p_cli_freq(struct wpa_supplicant *wpa_s,
			     struct wpa_ssid **ssid, u8 *go_dev_addr)
{
	struct wpa_supplicant *iface;

	if (go_dev_addr)
		os_memset(go_dev_addr, 0, ETH_ALEN);
	if (ssid)
		*ssid = NULL;
	for (iface = wpa_s->global->ifaces; iface; iface = iface->next) {
		if (iface->wpa_state < WPA_ASSOCIATING ||
		    iface->current_ssid == NULL || iface->assoc_freq == 0 ||
		    !iface->current_ssid->p2p_group ||
		    iface->current_ssid->mode != WPAS_MODE_INFRA)
			continue;
		if (ssid)
			*ssid = iface->current_ssid;
		if (go_dev_addr)
			os_memcpy(go_dev_addr, iface->go_dev_addr, ETH_ALEN);
		return iface->assoc_freq;
	}
	return 0;
}


struct wpabuf * wpas_p2p_nfc_handover_req(struct wpa_supplicant *wpa_s,
					  int ndef)
{
	struct wpabuf *wsc, *p2p;
	struct wpa_ssid *ssid;
	u8 go_dev_addr[ETH_ALEN];
	int cli_freq = wpas_p2p_cli_freq(wpa_s, &ssid, go_dev_addr);

	if (wpa_s->global->p2p_disabled || wpa_s->global->p2p == NULL) {
		wpa_printf(MSG_DEBUG, "P2P: P2P disabled - cannot build handover request");
		return NULL;
	}

	if (wpa_s->conf->wps_nfc_dh_pubkey == NULL &&
	    wps_nfc_gen_dh(&wpa_s->conf->wps_nfc_dh_pubkey,
			   &wpa_s->conf->wps_nfc_dh_privkey) < 0) {
		wpa_dbg(wpa_s, MSG_DEBUG, "P2P: No DH key available for handover request");
		return NULL;
	}

	if (cli_freq == 0) {
		wsc = wps_build_nfc_handover_req_p2p(
			wpa_s->parent->wps, wpa_s->conf->wps_nfc_dh_pubkey);
	} else
		wsc = NULL;
	p2p = p2p_build_nfc_handover_req(wpa_s->global->p2p, cli_freq,
					 go_dev_addr, ssid ? ssid->ssid : NULL,
					 ssid ? ssid->ssid_len : 0);

	return wpas_p2p_nfc_handover(ndef, wsc, p2p);
}


struct wpabuf * wpas_p2p_nfc_handover_sel(struct wpa_supplicant *wpa_s,
					  int ndef, int tag)
{
	struct wpabuf *wsc, *p2p;
	struct wpa_ssid *ssid;
	u8 go_dev_addr[ETH_ALEN];
	int cli_freq = wpas_p2p_cli_freq(wpa_s, &ssid, go_dev_addr);

	if (wpa_s->global->p2p_disabled || wpa_s->global->p2p == NULL)
		return NULL;

	if (!tag && wpa_s->conf->wps_nfc_dh_pubkey == NULL &&
	    wps_nfc_gen_dh(&wpa_s->conf->wps_nfc_dh_pubkey,
			   &wpa_s->conf->wps_nfc_dh_privkey) < 0)
		return NULL;

	if (cli_freq == 0) {
		wsc = wps_build_nfc_handover_sel_p2p(
			wpa_s->parent->wps,
			tag ? wpa_s->conf->wps_nfc_dev_pw_id :
			DEV_PW_NFC_CONNECTION_HANDOVER,
			wpa_s->conf->wps_nfc_dh_pubkey,
			tag ? wpa_s->conf->wps_nfc_dev_pw : NULL);
	} else
		wsc = NULL;
	p2p = p2p_build_nfc_handover_sel(wpa_s->global->p2p, cli_freq,
					 go_dev_addr, ssid ? ssid->ssid : NULL,
					 ssid ? ssid->ssid_len : 0);

	return wpas_p2p_nfc_handover(ndef, wsc, p2p);
}


static int wpas_p2p_nfc_join_group(struct wpa_supplicant *wpa_s,
				   struct p2p_nfc_params *params)
{
	wpa_printf(MSG_DEBUG, "P2P: Initiate join-group based on NFC "
		   "connection handover (freq=%d)",
		   params->go_freq);

	if (params->go_freq && params->go_ssid_len) {
		wpa_s->p2p_wps_method = WPS_NFC;
		wpa_s->pending_join_wps_method = WPS_NFC;
		os_memset(wpa_s->pending_join_iface_addr, 0, ETH_ALEN);
		os_memcpy(wpa_s->pending_join_dev_addr, params->go_dev_addr,
			  ETH_ALEN);
		return wpas_p2p_join_start(wpa_s, params->go_freq,
					   params->go_ssid,
					   params->go_ssid_len);
	}

	return wpas_p2p_connect(wpa_s, params->peer->p2p_device_addr, NULL,
				WPS_NFC, 0, 0, 1, 0, wpa_s->conf->p2p_go_intent,
				params->go_freq, wpa_s->p2p_go_vht_center_freq2,
				-1, 0, 1, 1, wpa_s->p2p_go_max_oper_chwidth,
				wpa_s->p2p_go_he, wpa_s->p2p_go_edmg,
				params->go_ssid_len ? params->go_ssid : NULL,
				params->go_ssid_len, false);
}


static int wpas_p2p_nfc_auth_join(struct wpa_supplicant *wpa_s,
				  struct p2p_nfc_params *params, int tag)
{
	int res, persistent;
	struct wpa_ssid *ssid;

	wpa_printf(MSG_DEBUG, "P2P: Authorize join-group based on NFC "
		   "connection handover");
	for (wpa_s = wpa_s->global->ifaces; wpa_s; wpa_s = wpa_s->next) {
		ssid = wpa_s->current_ssid;
		if (ssid == NULL)
			continue;
		if (ssid->mode != WPAS_MODE_P2P_GO)
			continue;
		if (wpa_s->ap_iface == NULL)
			continue;
		break;
	}
	if (wpa_s == NULL) {
		wpa_printf(MSG_DEBUG, "P2P: Could not find GO interface");
		return -1;
	}

	if (wpa_s->p2pdev->p2p_oob_dev_pw_id !=
	    DEV_PW_NFC_CONNECTION_HANDOVER &&
	    !wpa_s->p2pdev->p2p_oob_dev_pw) {
		wpa_printf(MSG_DEBUG, "P2P: No NFC Dev Pw known");
		return -1;
	}
	res = wpas_ap_wps_add_nfc_pw(
		wpa_s, wpa_s->p2pdev->p2p_oob_dev_pw_id,
		wpa_s->p2pdev->p2p_oob_dev_pw,
		wpa_s->p2pdev->p2p_peer_oob_pk_hash_known ?
		wpa_s->p2pdev->p2p_peer_oob_pubkey_hash : NULL);
	if (res)
		return res;

	if (!tag) {
		wpa_printf(MSG_DEBUG, "P2P: Negotiated handover - wait for peer to join without invitation");
		return 0;
	}

	if (!params->peer ||
	    !(params->peer->dev_capab & P2P_DEV_CAPAB_INVITATION_PROCEDURE))
		return 0;

	wpa_printf(MSG_DEBUG, "P2P: Static handover - invite peer " MACSTR
		   " to join", MAC2STR(params->peer->p2p_device_addr));

	wpa_s->global->p2p_invite_group = wpa_s;
	persistent = ssid->p2p_persistent_group &&
		wpas_p2p_get_persistent(wpa_s->p2pdev,
					params->peer->p2p_device_addr,
					ssid->ssid, ssid->ssid_len);
	wpa_s->p2pdev->pending_invite_ssid_id = -1;

	return p2p_invite(wpa_s->global->p2p, params->peer->p2p_device_addr,
			  P2P_INVITE_ROLE_ACTIVE_GO, wpa_s->own_addr,
			  ssid->ssid, ssid->ssid_len, ssid->frequency,
			  wpa_s->global->p2p_dev_addr, persistent, 0,
			  wpa_s->p2pdev->p2p_oob_dev_pw_id);
}


static int wpas_p2p_nfc_init_go_neg(struct wpa_supplicant *wpa_s,
				    struct p2p_nfc_params *params,
				    int forced_freq)
{
	wpa_printf(MSG_DEBUG, "P2P: Initiate GO Negotiation based on NFC "
		   "connection handover");
	return wpas_p2p_connect(wpa_s, params->peer->p2p_device_addr, NULL,
				WPS_NFC, 0, 0, 0, 0, wpa_s->conf->p2p_go_intent,
				forced_freq, wpa_s->p2p_go_vht_center_freq2,
				-1, 0, 1, 1, wpa_s->p2p_go_max_oper_chwidth,
				wpa_s->p2p_go_he, wpa_s->p2p_go_edmg,
				NULL, 0, false);
}


static int wpas_p2p_nfc_resp_go_neg(struct wpa_supplicant *wpa_s,
				    struct p2p_nfc_params *params,
				    int forced_freq)
{
	int res;

	wpa_printf(MSG_DEBUG, "P2P: Authorize GO Negotiation based on NFC "
		   "connection handover");
	res = wpas_p2p_connect(wpa_s, params->peer->p2p_device_addr, NULL,
			       WPS_NFC, 0, 0, 0, 1, wpa_s->conf->p2p_go_intent,
			       forced_freq, wpa_s->p2p_go_vht_center_freq2,
			       -1, 0, 1, 1, wpa_s->p2p_go_max_oper_chwidth,
			       wpa_s->p2p_go_he, wpa_s->p2p_go_edmg,
			       NULL, 0, false);
	if (res)
		return res;

	res = wpas_p2p_listen(wpa_s, 60);
	if (res) {
		p2p_unauthorize(wpa_s->global->p2p,
				params->peer->p2p_device_addr);
	}

	return res;
}


static int wpas_p2p_nfc_connection_handover(struct wpa_supplicant *wpa_s,
					    const struct wpabuf *data,
					    int sel, int tag, int forced_freq)
{
	const u8 *pos, *end;
	u16 len, id;
	struct p2p_nfc_params params;
	int res;

	os_memset(&params, 0, sizeof(params));
	params.sel = sel;

	wpa_hexdump_buf(MSG_DEBUG, "P2P: Received NFC tag payload", data);

	pos = wpabuf_head(data);
	end = pos + wpabuf_len(data);

	if (end - pos < 2) {
		wpa_printf(MSG_DEBUG, "P2P: Not enough data for Length of WSC "
			   "attributes");
		return -1;
	}
	len = WPA_GET_BE16(pos);
	pos += 2;
	if (len > end - pos) {
		wpa_printf(MSG_DEBUG, "P2P: Not enough data for WSC "
			   "attributes");
		return -1;
	}
	params.wsc_attr = pos;
	params.wsc_len = len;
	pos += len;

	if (end - pos < 2) {
		wpa_printf(MSG_DEBUG, "P2P: Not enough data for Length of P2P "
			   "attributes");
		return -1;
	}
	len = WPA_GET_BE16(pos);
	pos += 2;
	if (len > end - pos) {
		wpa_printf(MSG_DEBUG, "P2P: Not enough data for P2P "
			   "attributes");
		return -1;
	}
	params.p2p_attr = pos;
	params.p2p_len = len;
	pos += len;

	wpa_hexdump(MSG_DEBUG, "P2P: WSC attributes",
		    params.wsc_attr, params.wsc_len);
	wpa_hexdump(MSG_DEBUG, "P2P: P2P attributes",
		    params.p2p_attr, params.p2p_len);
	if (pos < end) {
		wpa_hexdump(MSG_DEBUG,
			    "P2P: Ignored extra data after P2P attributes",
			    pos, end - pos);
	}

	res = p2p_process_nfc_connection_handover(wpa_s->global->p2p, &params);
	if (res)
		return res;

	if (params.next_step == NO_ACTION)
		return 0;

	if (params.next_step == BOTH_GO) {
		wpa_msg(wpa_s, MSG_INFO, P2P_EVENT_NFC_BOTH_GO "peer=" MACSTR,
			MAC2STR(params.peer->p2p_device_addr));
		return 0;
	}

	if (params.next_step == PEER_CLIENT) {
		if (!is_zero_ether_addr(params.go_dev_addr)) {
			wpa_msg(wpa_s, MSG_INFO, P2P_EVENT_NFC_PEER_CLIENT
				"peer=" MACSTR " freq=%d go_dev_addr=" MACSTR
				" ssid=\"%s\"",
				MAC2STR(params.peer->p2p_device_addr),
				params.go_freq,
				MAC2STR(params.go_dev_addr),
				wpa_ssid_txt(params.go_ssid,
					     params.go_ssid_len));
		} else {
			wpa_msg(wpa_s, MSG_INFO, P2P_EVENT_NFC_PEER_CLIENT
				"peer=" MACSTR " freq=%d",
				MAC2STR(params.peer->p2p_device_addr),
				params.go_freq);
		}
		return 0;
	}

	if (wpas_p2p_cli_freq(wpa_s, NULL, NULL)) {
		wpa_msg(wpa_s, MSG_INFO, P2P_EVENT_NFC_WHILE_CLIENT "peer="
			MACSTR, MAC2STR(params.peer->p2p_device_addr));
		return 0;
	}

	wpabuf_free(wpa_s->p2p_oob_dev_pw);
	wpa_s->p2p_oob_dev_pw = NULL;

	if (params.oob_dev_pw_len < WPS_OOB_PUBKEY_HASH_LEN + 2) {
		wpa_printf(MSG_DEBUG, "P2P: No peer OOB Dev Pw "
			   "received");
		return -1;
	}

	id = WPA_GET_BE16(params.oob_dev_pw + WPS_OOB_PUBKEY_HASH_LEN);
	wpa_printf(MSG_DEBUG, "P2P: Peer OOB Dev Pw %u", id);
	wpa_hexdump(MSG_DEBUG, "P2P: Peer OOB Public Key hash",
		    params.oob_dev_pw, WPS_OOB_PUBKEY_HASH_LEN);
	os_memcpy(wpa_s->p2p_peer_oob_pubkey_hash,
		  params.oob_dev_pw, WPS_OOB_PUBKEY_HASH_LEN);
	wpa_s->p2p_peer_oob_pk_hash_known = 1;

	if (tag) {
		if (id < 0x10) {
			wpa_printf(MSG_DEBUG, "P2P: Static handover - invalid "
				   "peer OOB Device Password Id %u", id);
			return -1;
		}
		wpa_printf(MSG_DEBUG, "P2P: Static handover - use peer OOB "
			   "Device Password Id %u", id);
		wpa_hexdump_key(MSG_DEBUG, "P2P: Peer OOB Device Password",
				params.oob_dev_pw + WPS_OOB_PUBKEY_HASH_LEN + 2,
				params.oob_dev_pw_len -
				WPS_OOB_PUBKEY_HASH_LEN - 2);
		wpa_s->p2p_oob_dev_pw_id = id;
		wpa_s->p2p_oob_dev_pw = wpabuf_alloc_copy(
			params.oob_dev_pw + WPS_OOB_PUBKEY_HASH_LEN + 2,
			params.oob_dev_pw_len -
			WPS_OOB_PUBKEY_HASH_LEN - 2);
		if (wpa_s->p2p_oob_dev_pw == NULL)
			return -1;

		if (wpa_s->conf->wps_nfc_dh_pubkey == NULL &&
		    wps_nfc_gen_dh(&wpa_s->conf->wps_nfc_dh_pubkey,
				   &wpa_s->conf->wps_nfc_dh_privkey) < 0)
			return -1;
	} else {
		wpa_printf(MSG_DEBUG, "P2P: Using abbreviated WPS handshake "
			   "without Device Password");
		wpa_s->p2p_oob_dev_pw_id = DEV_PW_NFC_CONNECTION_HANDOVER;
	}

	switch (params.next_step) {
	case NO_ACTION:
	case BOTH_GO:
	case PEER_CLIENT:
		/* already covered above */
		return 0;
	case JOIN_GROUP:
		return wpas_p2p_nfc_join_group(wpa_s, &params);
	case AUTH_JOIN:
		return wpas_p2p_nfc_auth_join(wpa_s, &params, tag);
	case INIT_GO_NEG:
		return wpas_p2p_nfc_init_go_neg(wpa_s, &params, forced_freq);
	case RESP_GO_NEG:
		/* TODO: use own OOB Dev Pw */
		return wpas_p2p_nfc_resp_go_neg(wpa_s, &params, forced_freq);
	}

	return -1;
}


int wpas_p2p_nfc_tag_process(struct wpa_supplicant *wpa_s,
			     const struct wpabuf *data, int forced_freq)
{
	if (wpa_s->global->p2p_disabled || wpa_s->global->p2p == NULL)
		return -1;

	return wpas_p2p_nfc_connection_handover(wpa_s, data, 1, 1, forced_freq);
}


int wpas_p2p_nfc_report_handover(struct wpa_supplicant *wpa_s, int init,
				 const struct wpabuf *req,
				 const struct wpabuf *sel, int forced_freq)
{
	struct wpabuf *tmp;
	int ret;

	if (wpa_s->global->p2p_disabled || wpa_s->global->p2p == NULL)
		return -1;

	wpa_printf(MSG_DEBUG, "NFC: P2P connection handover reported");

	wpa_hexdump_ascii(MSG_DEBUG, "NFC: Req",
			  wpabuf_head(req), wpabuf_len(req));
	wpa_hexdump_ascii(MSG_DEBUG, "NFC: Sel",
			  wpabuf_head(sel), wpabuf_len(sel));
	if (forced_freq)
		wpa_printf(MSG_DEBUG, "NFC: Forced freq %d", forced_freq);
	tmp = ndef_parse_p2p(init ? sel : req);
	if (tmp == NULL) {
		wpa_printf(MSG_DEBUG, "P2P: Could not parse NDEF");
		return -1;
	}

	ret = wpas_p2p_nfc_connection_handover(wpa_s, tmp, init, 0,
					       forced_freq);
	wpabuf_free(tmp);

	return ret;
}


int wpas_p2p_nfc_tag_enabled(struct wpa_supplicant *wpa_s, int enabled)
{
	const u8 *if_addr;
	int go_intent = wpa_s->conf->p2p_go_intent;
	struct wpa_supplicant *iface;

	if (wpa_s->global->p2p == NULL)
		return -1;

	if (!enabled) {
		wpa_printf(MSG_DEBUG, "P2P: Disable use of own NFC Tag");
		for (iface = wpa_s->global->ifaces; iface; iface = iface->next)
		{
			if (!iface->ap_iface)
				continue;
			hostapd_wps_nfc_token_disable(iface->ap_iface->bss[0]);
		}
		p2p_set_authorized_oob_dev_pw_id(wpa_s->global->p2p, 0,
						 0, NULL);
		if (wpa_s->p2p_nfc_tag_enabled)
			wpas_p2p_remove_pending_group_interface(wpa_s);
		wpa_s->p2p_nfc_tag_enabled = 0;
		return 0;
	}

	if (wpa_s->global->p2p_disabled)
		return -1;

	if (wpa_s->conf->wps_nfc_dh_pubkey == NULL ||
	    wpa_s->conf->wps_nfc_dh_privkey == NULL ||
	    wpa_s->conf->wps_nfc_dev_pw == NULL ||
	    wpa_s->conf->wps_nfc_dev_pw_id < 0x10) {
		wpa_printf(MSG_DEBUG, "P2P: NFC password token not configured "
			   "to allow static handover cases");
		return -1;
	}

	wpa_printf(MSG_DEBUG, "P2P: Enable use of own NFC Tag");

	wpa_s->p2p_oob_dev_pw_id = wpa_s->conf->wps_nfc_dev_pw_id;
	wpabuf_free(wpa_s->p2p_oob_dev_pw);
	wpa_s->p2p_oob_dev_pw = wpabuf_dup(wpa_s->conf->wps_nfc_dev_pw);
	if (wpa_s->p2p_oob_dev_pw == NULL)
		return -1;
	wpa_s->p2p_peer_oob_pk_hash_known = 0;

	if (wpa_s->p2p_group_interface == P2P_GROUP_INTERFACE_GO ||
	    wpa_s->p2p_group_interface == P2P_GROUP_INTERFACE_CLIENT) {
		/*
		 * P2P Group Interface present and the command came on group
		 * interface, so enable the token for the current interface.
		 */
		wpa_s->create_p2p_iface = 0;
	} else {
		wpa_s->create_p2p_iface = wpas_p2p_create_iface(wpa_s);
	}

	if (wpa_s->create_p2p_iface) {
		enum wpa_driver_if_type iftype;
		/* Prepare to add a new interface for the group */
		iftype = WPA_IF_P2P_GROUP;
		if (go_intent == 15)
			iftype = WPA_IF_P2P_GO;
		if (wpas_p2p_add_group_interface(wpa_s, iftype) < 0) {
			wpa_printf(MSG_ERROR, "P2P: Failed to allocate a new "
				   "interface for the group");
			return -1;
		}

		if_addr = wpa_s->pending_interface_addr;
	} else if (wpa_s->p2p_mgmt)
		if_addr = wpa_s->parent->own_addr;
	else
		if_addr = wpa_s->own_addr;

	wpa_s->p2p_nfc_tag_enabled = enabled;

	for (iface = wpa_s->global->ifaces; iface; iface = iface->next) {
		struct hostapd_data *hapd;
		if (iface->ap_iface == NULL)
			continue;
		hapd = iface->ap_iface->bss[0];
		wpabuf_free(hapd->conf->wps_nfc_dh_pubkey);
		hapd->conf->wps_nfc_dh_pubkey =
			wpabuf_dup(wpa_s->conf->wps_nfc_dh_pubkey);
		wpabuf_free(hapd->conf->wps_nfc_dh_privkey);
		hapd->conf->wps_nfc_dh_privkey =
			wpabuf_dup(wpa_s->conf->wps_nfc_dh_privkey);
		wpabuf_free(hapd->conf->wps_nfc_dev_pw);
		hapd->conf->wps_nfc_dev_pw =
			wpabuf_dup(wpa_s->conf->wps_nfc_dev_pw);
		hapd->conf->wps_nfc_dev_pw_id = wpa_s->conf->wps_nfc_dev_pw_id;

		if (hostapd_wps_nfc_token_enable(iface->ap_iface->bss[0]) < 0) {
			wpa_dbg(iface, MSG_DEBUG,
				"P2P: Failed to enable NFC Tag for GO");
		}
	}
	p2p_set_authorized_oob_dev_pw_id(
		wpa_s->global->p2p, wpa_s->conf->wps_nfc_dev_pw_id, go_intent,
		if_addr);

	return 0;
}

#endif /* CONFIG_WPS_NFC */


static void wpas_p2p_optimize_listen_channel(struct wpa_supplicant *wpa_s,
					     struct wpa_used_freq_data *freqs,
					     unsigned int num)
{
	u8 curr_chan, cand, chan;
	unsigned int i;

	/*
	 * If possible, optimize the Listen channel to be a channel that is
	 * already used by one of the other interfaces.
	 */
	if (!wpa_s->conf->p2p_optimize_listen_chan)
		return;

	if (!wpa_s->current_ssid || wpa_s->wpa_state != WPA_COMPLETED)
		return;

	curr_chan = p2p_get_listen_channel(wpa_s->global->p2p);
	for (i = 0, cand = 0; i < num; i++) {
		ieee80211_freq_to_chan(freqs[i].freq, &chan);
		if (curr_chan == chan) {
			cand = 0;
			break;
		}

		if (chan == 1 || chan == 6 || chan == 11)
			cand = chan;
	}

	if (cand) {
		wpa_dbg(wpa_s, MSG_DEBUG,
			"P2P: Update Listen channel to %u based on operating channel",
			cand);
		p2p_set_listen_channel(wpa_s->global->p2p, 81, cand, 0);
	}
}


static int wpas_p2p_move_go_csa(struct wpa_supplicant *wpa_s)
{
	struct hostapd_config *conf;
	struct p2p_go_neg_results params;
	struct csa_settings csa_settings;
	struct wpa_ssid *current_ssid = wpa_s->current_ssid;
	int old_freq = current_ssid->frequency;
	int ret;

	if (!(wpa_s->drv_flags & WPA_DRIVER_FLAGS_AP_CSA)) {
		wpa_dbg(wpa_s, MSG_DEBUG, "CSA is not enabled");
		return -1;
	}

	/*
	 * TODO: This function may not always work correctly. For example,
	 * when we have a running GO and a BSS on a DFS channel.
	 */
	if (wpas_p2p_init_go_params(wpa_s, &params, 0, 0, 0, 0, 0, 0, 0,
				    NULL)) {
		wpa_dbg(wpa_s, MSG_DEBUG,
			"P2P CSA: Failed to select new frequency for GO");
		return -1;
	}

	if (current_ssid->frequency == params.freq) {
		wpa_dbg(wpa_s, MSG_DEBUG,
			"P2P CSA: Selected same frequency - not moving GO");
		return 0;
	}

	conf = hostapd_config_defaults();
	if (!conf) {
		wpa_dbg(wpa_s, MSG_DEBUG,
			"P2P CSA: Failed to allocate default config");
		return -1;
	}

	current_ssid->frequency = params.freq;
	if (wpa_supplicant_conf_ap_ht(wpa_s, current_ssid, conf)) {
		wpa_dbg(wpa_s, MSG_DEBUG,
			"P2P CSA: Failed to create new GO config");
		ret = -1;
		goto out;
	}

	if (conf->hw_mode != wpa_s->ap_iface->current_mode->mode) {
		wpa_dbg(wpa_s, MSG_DEBUG,
			"P2P CSA: CSA to a different band is not supported");
		ret = -1;
		goto out;
	}

	os_memset(&csa_settings, 0, sizeof(csa_settings));
	csa_settings.cs_count = P2P_GO_CSA_COUNT;
	csa_settings.block_tx = P2P_GO_CSA_BLOCK_TX;
	csa_settings.freq_params.freq = params.freq;
	csa_settings.freq_params.sec_channel_offset = conf->secondary_channel;
	csa_settings.freq_params.ht_enabled = conf->ieee80211n;
	csa_settings.freq_params.bandwidth = conf->secondary_channel ? 40 : 20;

	if (conf->ieee80211ac) {
		int freq1 = 0, freq2 = 0;
		u8 chan, opclass;

		if (ieee80211_freq_to_channel_ext(params.freq,
						  conf->secondary_channel,
						  conf->vht_oper_chwidth,
						  &opclass, &chan) ==
		    NUM_HOSTAPD_MODES) {
			wpa_printf(MSG_ERROR, "P2P CSA: Bad freq");
			ret = -1;
			goto out;
		}

		if (conf->vht_oper_centr_freq_seg0_idx)
			freq1 = ieee80211_chan_to_freq(
				NULL, opclass,
				conf->vht_oper_centr_freq_seg0_idx);

		if (conf->vht_oper_centr_freq_seg1_idx)
			freq2 = ieee80211_chan_to_freq(
				NULL, opclass,
				conf->vht_oper_centr_freq_seg1_idx);

		if (freq1 < 0 || freq2 < 0) {
			wpa_dbg(wpa_s, MSG_DEBUG,
				"P2P CSA: Selected invalid VHT center freqs");
			ret = -1;
			goto out;
		}

		csa_settings.freq_params.vht_enabled = conf->ieee80211ac;
		csa_settings.freq_params.center_freq1 = freq1;
		csa_settings.freq_params.center_freq2 = freq2;

		switch (conf->vht_oper_chwidth) {
		case CHANWIDTH_80MHZ:
		case CHANWIDTH_80P80MHZ:
			csa_settings.freq_params.bandwidth = 80;
			break;
		case CHANWIDTH_160MHZ:
			csa_settings.freq_params.bandwidth = 160;
			break;
		}
	}

	ret = ap_switch_channel(wpa_s, &csa_settings);
out:
	current_ssid->frequency = old_freq;
	hostapd_config_free(conf);
	return ret;
}


static void wpas_p2p_move_go_no_csa(struct wpa_supplicant *wpa_s)
{
	struct p2p_go_neg_results params;
	struct wpa_ssid *current_ssid = wpa_s->current_ssid;
	void (*ap_configured_cb)(void *ctx, void *data);
	void *ap_configured_cb_ctx, *ap_configured_cb_data;

	wpa_msg_global(wpa_s, MSG_INFO, P2P_EVENT_REMOVE_AND_REFORM_GROUP);

	wpa_dbg(wpa_s, MSG_DEBUG, "P2P: Move GO from freq=%d MHz",
		current_ssid->frequency);

	/* Stop the AP functionality */
	/* TODO: Should do this in a way that does not indicated to possible
	 * P2P Clients in the group that the group is terminated. */
	/* If this action occurs before a group is started, the callback should
	 * be preserved, or GROUP-STARTED event would be lost. If this action
	 * occurs after a group is started, these pointers are all NULL and
	 * harmless. */
	ap_configured_cb = wpa_s->ap_configured_cb;
	ap_configured_cb_ctx = wpa_s->ap_configured_cb_ctx;
	ap_configured_cb_data = wpa_s->ap_configured_cb_data;
	wpa_supplicant_ap_deinit(wpa_s);

	/* Reselect the GO frequency */
	if (wpas_p2p_init_go_params(wpa_s, &params, 0, 0, 0, 0, 0, 0, 0,
				    NULL)) {
		wpa_dbg(wpa_s, MSG_DEBUG, "P2P: Failed to reselect freq");
		wpas_p2p_group_delete(wpa_s,
				      P2P_GROUP_REMOVAL_GO_LEAVE_CHANNEL);
		return;
	}
	wpa_dbg(wpa_s, MSG_DEBUG, "P2P: New freq selected for the GO (%u MHz)",
		params.freq);

	if (params.freq &&
	    !p2p_supported_freq_go(wpa_s->global->p2p, params.freq)) {
		wpa_printf(MSG_DEBUG,
			   "P2P: Selected freq (%u MHz) is not valid for P2P",
			   params.freq);
		wpas_p2p_group_delete(wpa_s,
				      P2P_GROUP_REMOVAL_GO_LEAVE_CHANNEL);
		return;
	}

	/* Restore preserved callback parameters */
	wpa_s->ap_configured_cb = ap_configured_cb;
	wpa_s->ap_configured_cb_ctx = ap_configured_cb_ctx;
	wpa_s->ap_configured_cb_data = ap_configured_cb_data;

	/* Update the frequency */
	current_ssid->frequency = params.freq;
	wpa_s->connect_without_scan = current_ssid;
	wpa_s->reassociate = 1;
	wpa_s->disconnected = 0;
	wpa_supplicant_req_scan(wpa_s, 0, 0);
}


static void wpas_p2p_move_go(void *eloop_ctx, void *timeout_ctx)
{
	struct wpa_supplicant *wpa_s = eloop_ctx;

	if (!wpa_s->ap_iface || !wpa_s->current_ssid)
		return;

	wpas_p2p_go_update_common_freqs(wpa_s);

	/* Do not move GO in the middle of a CSA */
	if (hostapd_csa_in_progress(wpa_s->ap_iface)) {
		wpa_printf(MSG_DEBUG,
			   "P2P: CSA is in progress - not moving GO");
		return;
	}

	/*
	 * First, try a channel switch flow. If it is not supported or fails,
	 * take down the GO and bring it up again.
	 */
	if (wpas_p2p_move_go_csa(wpa_s) < 0)
		wpas_p2p_move_go_no_csa(wpa_s);
}


static void wpas_p2p_reconsider_moving_go(void *eloop_ctx, void *timeout_ctx)
{
	struct wpa_supplicant *wpa_s = eloop_ctx;
	struct wpa_used_freq_data *freqs = NULL;
	unsigned int num = wpa_s->num_multichan_concurrent;

	freqs = os_calloc(num, sizeof(struct wpa_used_freq_data));
	if (!freqs)
		return;

	num = get_shared_radio_freqs_data(wpa_s, freqs, num);

	/* Previous attempt to move a GO was not possible -- try again. */
	wpas_p2p_consider_moving_gos(wpa_s, freqs, num,
				     WPAS_P2P_CHANNEL_UPDATE_ANY);

	os_free(freqs);
}


/*
 * Consider moving a GO from its currently used frequency:
 * 1. It is possible that due to regulatory consideration the frequency
 *    can no longer be used and there is a need to evacuate the GO.
 * 2. It is possible that due to MCC considerations, it would be preferable
 *    to move the GO to a channel that is currently used by some other
 *    station interface.
 *
 * In case a frequency that became invalid is once again valid, cancel a
 * previously initiated GO frequency change.
 */
static void wpas_p2p_consider_moving_one_go(struct wpa_supplicant *wpa_s,
					    struct wpa_used_freq_data *freqs,
					    unsigned int num)
{
	unsigned int i, invalid_freq = 0, policy_move = 0, flags = 0;
	unsigned int timeout;
	int freq;
	int dfs_offload;

	wpas_p2p_go_update_common_freqs(wpa_s);

	freq = wpa_s->current_ssid->frequency;
	dfs_offload = (wpa_s->drv_flags & WPA_DRIVER_FLAGS_DFS_OFFLOAD) &&
		ieee80211_is_dfs(freq, wpa_s->hw.modes, wpa_s->hw.num_modes);
	for (i = 0, invalid_freq = 0; i < num; i++) {
		if (freqs[i].freq == freq) {
			flags = freqs[i].flags;

			/* The channel is invalid, must change it */
			if (!p2p_supported_freq_go(wpa_s->global->p2p, freq) &&
			    !dfs_offload) {
				wpa_dbg(wpa_s, MSG_DEBUG,
					"P2P: Freq=%d MHz no longer valid for GO",
					freq);
				invalid_freq = 1;
			}
		} else if (freqs[i].flags == 0) {
			/* Freq is not used by any other station interface */
			continue;
		} else if (!p2p_supported_freq(wpa_s->global->p2p,
					       freqs[i].freq) && !dfs_offload) {
			/* Freq is not valid for P2P use cases */
			continue;
		} else if (wpa_s->conf->p2p_go_freq_change_policy ==
			   P2P_GO_FREQ_MOVE_SCM) {
			policy_move = 1;
		} else if (wpa_s->conf->p2p_go_freq_change_policy ==
			   P2P_GO_FREQ_MOVE_SCM_PEER_SUPPORTS &&
			   wpas_p2p_go_is_peer_freq(wpa_s, freqs[i].freq)) {
			policy_move = 1;
		} else if ((wpa_s->conf->p2p_go_freq_change_policy ==
			    P2P_GO_FREQ_MOVE_SCM_ECSA) &&
			   wpas_p2p_go_is_peer_freq(wpa_s, freqs[i].freq)) {
			if (!p2p_get_group_num_members(wpa_s->p2p_group)) {
				policy_move = 1;
			} else if ((wpa_s->drv_flags &
				    WPA_DRIVER_FLAGS_AP_CSA) &&
				   wpas_p2p_go_clients_support_ecsa(wpa_s)) {
				u8 chan;

				/*
				 * We do not support CSA between bands, so move
				 * GO only within the same band.
				 */
				if (wpa_s->ap_iface->current_mode->mode ==
				    ieee80211_freq_to_chan(freqs[i].freq,
							   &chan))
					policy_move = 1;
			}
		}
	}

	wpa_dbg(wpa_s, MSG_DEBUG,
		"P2P: GO move: invalid_freq=%u, policy_move=%u, flags=0x%X",
		invalid_freq, policy_move, flags);

	/*
	 * The channel is valid, or we are going to have a policy move, so
	 * cancel timeout.
	 */
	if (!invalid_freq || policy_move) {
		wpa_dbg(wpa_s, MSG_DEBUG,
			"P2P: Cancel a GO move from freq=%d MHz", freq);
		eloop_cancel_timeout(wpas_p2p_move_go, wpa_s, NULL);

		if (wpas_p2p_in_progress(wpa_s)) {
			wpa_dbg(wpa_s, MSG_DEBUG,
				"P2P: GO move: policy CS is not allowed - setting timeout to re-consider GO move");
			eloop_cancel_timeout(wpas_p2p_reconsider_moving_go,
					     wpa_s, NULL);
			eloop_register_timeout(P2P_RECONSIDER_GO_MOVE_DELAY, 0,
					       wpas_p2p_reconsider_moving_go,
					       wpa_s, NULL);
			return;
		}
	}

	if (!invalid_freq && (!policy_move || flags != 0)) {
		wpa_dbg(wpa_s, MSG_DEBUG,
			"P2P: Not initiating a GO frequency change");
		return;
	}

	/*
	 * Do not consider moving GO if it is in the middle of a CSA. When the
	 * CSA is finished this flow should be retriggered.
	 */
	if (hostapd_csa_in_progress(wpa_s->ap_iface)) {
		wpa_dbg(wpa_s, MSG_DEBUG,
			"P2P: Not initiating a GO frequency change - CSA is in progress");
		return;
	}

	if (invalid_freq && !wpas_p2p_disallowed_freq(wpa_s->global, freq))
		timeout = P2P_GO_FREQ_CHANGE_TIME;
	else
		timeout = 0;

	wpa_dbg(wpa_s, MSG_DEBUG, "P2P: Move GO from freq=%d MHz in %d secs",
		freq, timeout);
	eloop_cancel_timeout(wpas_p2p_move_go, wpa_s, NULL);
	eloop_register_timeout(timeout, 0, wpas_p2p_move_go, wpa_s, NULL);
}


static void wpas_p2p_consider_moving_gos(struct wpa_supplicant *wpa_s,
					 struct wpa_used_freq_data *freqs,
					 unsigned int num,
					 enum wpas_p2p_channel_update_trig trig)
{
	struct wpa_supplicant *ifs;

	eloop_cancel_timeout(wpas_p2p_reconsider_moving_go, ELOOP_ALL_CTX,
			     NULL);

	/*
	 * Travers all the radio interfaces, and for each GO interface, check
	 * if there is a need to move the GO from the frequency it is using,
	 * or in case the frequency is valid again, cancel the evacuation flow.
	 */
	dl_list_for_each(ifs, &wpa_s->radio->ifaces, struct wpa_supplicant,
			 radio_list) {
		if (ifs->current_ssid == NULL ||
		    ifs->current_ssid->mode != WPAS_MODE_P2P_GO)
			continue;

		/*
		 * The GO was just started or completed channel switch, no need
		 * to move it.
		 */
		if (wpa_s == ifs &&
		    (trig == WPAS_P2P_CHANNEL_UPDATE_STATE_CHANGE ||
		     trig == WPAS_P2P_CHANNEL_UPDATE_CS)) {
			wpa_dbg(wpa_s, MSG_DEBUG,
				"P2P: GO move - schedule re-consideration");
			eloop_register_timeout(P2P_RECONSIDER_GO_MOVE_DELAY, 0,
					       wpas_p2p_reconsider_moving_go,
					       wpa_s, NULL);
			continue;
		}

		wpas_p2p_consider_moving_one_go(ifs, freqs, num);
	}
}


void wpas_p2p_indicate_state_change(struct wpa_supplicant *wpa_s)
{
	if (wpa_s->global->p2p_disabled || wpa_s->global->p2p == NULL)
		return;

	wpas_p2p_update_channel_list(wpa_s,
				     WPAS_P2P_CHANNEL_UPDATE_STATE_CHANGE);
}


void wpas_p2p_deinit_iface(struct wpa_supplicant *wpa_s)
{
	if (wpa_s == wpa_s->global->p2p_init_wpa_s && wpa_s->global->p2p) {
		wpa_dbg(wpa_s, MSG_DEBUG, "P2P: Disable P2P since removing "
			"the management interface is being removed");
		wpas_p2p_deinit_global(wpa_s->global);
	}
}


void wpas_p2p_ap_deinit(struct wpa_supplicant *wpa_s)
{
	if (wpa_s->ap_iface->bss)
		wpa_s->ap_iface->bss[0]->p2p_group = NULL;
	wpas_p2p_group_deinit(wpa_s);
}


int wpas_p2p_lo_start(struct wpa_supplicant *wpa_s, unsigned int freq,
		      unsigned int period, unsigned int interval,
		      unsigned int count)
{
	struct p2p_data *p2p = wpa_s->global->p2p;
	u8 *device_types;
	size_t dev_types_len;
	struct wpabuf *buf;
	int ret;

	if (wpa_s->p2p_lo_started) {
		wpa_dbg(wpa_s, MSG_DEBUG,
			"P2P Listen offload is already started");
		return 0;
	}

	if (wpa_s->global->p2p == NULL ||
	    !(wpa_s->drv_flags & WPA_DRIVER_FLAGS_P2P_LISTEN_OFFLOAD)) {
		wpa_printf(MSG_DEBUG, "P2P: Listen offload not supported");
		return -1;
	}

	if (!p2p_supported_freq(wpa_s->global->p2p, freq)) {
		wpa_printf(MSG_ERROR, "P2P: Input channel not supported: %u",
			   freq);
		return -1;
	}

	/* Get device type */
	dev_types_len = (wpa_s->conf->num_sec_device_types + 1) *
		WPS_DEV_TYPE_LEN;
	device_types = os_malloc(dev_types_len);
	if (!device_types)
		return -1;
	os_memcpy(device_types, wpa_s->conf->device_type, WPS_DEV_TYPE_LEN);
	os_memcpy(&device_types[WPS_DEV_TYPE_LEN], wpa_s->conf->sec_device_type,
		  wpa_s->conf->num_sec_device_types * WPS_DEV_TYPE_LEN);

	/* Get Probe Response IE(s) */
	buf = p2p_build_probe_resp_template(p2p, freq);
	if (!buf) {
		os_free(device_types);
		return -1;
	}

	ret = wpa_drv_p2p_lo_start(wpa_s, freq, period, interval, count,
				   device_types, dev_types_len,
				   wpabuf_mhead_u8(buf), wpabuf_len(buf));
	if (ret < 0)
		wpa_dbg(wpa_s, MSG_DEBUG,
			"P2P: Failed to start P2P listen offload");

	os_free(device_types);
	wpabuf_free(buf);

	if (ret == 0) {
		wpa_s->p2p_lo_started = 1;

		/* Stop current P2P listen if any */
		wpas_stop_listen(wpa_s);
	}

	return ret;
}


int wpas_p2p_lo_stop(struct wpa_supplicant *wpa_s)
{
	int ret;

	if (!wpa_s->p2p_lo_started)
		return 0;

	ret = wpa_drv_p2p_lo_stop(wpa_s);
	if (ret < 0)
		wpa_dbg(wpa_s, MSG_DEBUG,
			"P2P: Failed to stop P2P listen offload");

	wpa_s->p2p_lo_started = 0;
	return ret;
}
