18d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt/*
28d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * wpa_supplicant - P2P
38d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * Copyright (c) 2009-2010, Atheros Communications
4fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt * Copyright (c) 2010-2014, Jouni Malinen <j@w1.fi>
58d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt *
6c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt * This software may be distributed under the terms of the BSD license.
7c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt * See README for more details.
88d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */
98d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include "includes.h"
118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include "common.h"
138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include "eloop.h"
148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include "common/ieee802_11_common.h"
158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include "common/ieee802_11_defs.h"
168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include "common/wpa_ctrl.h"
178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include "wps/wps_i.h"
188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include "p2p/p2p.h"
198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include "ap/hostapd.h"
201f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt#include "ap/ap_config.h"
21391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt#include "ap/sta_info.h"
22391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt#include "ap/ap_drv_ops.h"
23cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt#include "ap/wps_hostapd.h"
248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include "ap/p2p_hostapd.h"
25203eadb9eda41a1dde4a583edb4684319e3f399eDmitry Shmidt#include "ap/dfs.h"
2675ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen#include "eapol_supp/eapol_supp_sm.h"
2775ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen#include "rsn_supp/wpa.h"
288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include "wpa_supplicant_i.h"
298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include "driver_i.h"
308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include "ap.h"
318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include "config_ssid.h"
328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include "config.h"
338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include "notify.h"
348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include "scan.h"
358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include "bss.h"
361f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt#include "offchannel.h"
378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include "wps_supplicant.h"
388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include "p2p_supplicant.h"
3904f534e89ed127da4077485376f24debc50d80d5Dmitry Shmidt#include "wifi_display.h"
408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt/*
438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * How many times to try to scan to find the GO before giving up on join
448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * request.
458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */
468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#define P2P_MAX_JOIN_SCAN_ATTEMPTS 10
478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
4804949598a23f501be6eec21697465fd46a28840aDmitry Shmidt#define P2P_AUTO_PD_SCAN_ATTEMPTS 5
4904949598a23f501be6eec21697465fd46a28840aDmitry Shmidt
501f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt#ifndef P2P_MAX_CLIENT_IDLE
511f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt/*
521f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt * How many seconds to try to reconnect to the GO when connection in P2P client
531f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt * role has been lost.
541f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt */
551f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt#define P2P_MAX_CLIENT_IDLE 10
561f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt#endif /* P2P_MAX_CLIENT_IDLE */
571f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt
5804949598a23f501be6eec21697465fd46a28840aDmitry Shmidt#ifndef P2P_MAX_INITIAL_CONN_WAIT
5904949598a23f501be6eec21697465fd46a28840aDmitry Shmidt/*
6004949598a23f501be6eec21697465fd46a28840aDmitry Shmidt * How many seconds to wait for initial 4-way handshake to get completed after
6115907098d1f67c24bb000e593e279af173cf57d7Dmitry Shmidt * WPS provisioning step or after the re-invocation of a persistent group on a
6215907098d1f67c24bb000e593e279af173cf57d7Dmitry Shmidt * P2P Client.
6304949598a23f501be6eec21697465fd46a28840aDmitry Shmidt */
6404949598a23f501be6eec21697465fd46a28840aDmitry Shmidt#define P2P_MAX_INITIAL_CONN_WAIT 10
6504949598a23f501be6eec21697465fd46a28840aDmitry Shmidt#endif /* P2P_MAX_INITIAL_CONN_WAIT */
6604949598a23f501be6eec21697465fd46a28840aDmitry Shmidt
6792c368d56f46a4e648b441085707c1381b5e5f63Dmitry Shmidt#ifndef P2P_MAX_INITIAL_CONN_WAIT_GO
6892c368d56f46a4e648b441085707c1381b5e5f63Dmitry Shmidt/*
6992c368d56f46a4e648b441085707c1381b5e5f63Dmitry Shmidt * How many seconds to wait for initial 4-way handshake to get completed after
7092c368d56f46a4e648b441085707c1381b5e5f63Dmitry Shmidt * WPS provisioning step on the GO. This controls the extra time the P2P
7192c368d56f46a4e648b441085707c1381b5e5f63Dmitry Shmidt * operation is considered to be in progress (e.g., to delay other scans) after
7292c368d56f46a4e648b441085707c1381b5e5f63Dmitry Shmidt * WPS provisioning has been completed on the GO during group formation.
7392c368d56f46a4e648b441085707c1381b5e5f63Dmitry Shmidt */
7492c368d56f46a4e648b441085707c1381b5e5f63Dmitry Shmidt#define P2P_MAX_INITIAL_CONN_WAIT_GO 10
7592c368d56f46a4e648b441085707c1381b5e5f63Dmitry Shmidt#endif /* P2P_MAX_INITIAL_CONN_WAIT_GO */
7692c368d56f46a4e648b441085707c1381b5e5f63Dmitry Shmidt
775605286c30e1701491bd3af974ae423727750eddDmitry Shmidt#ifndef P2P_MAX_INITIAL_CONN_WAIT_GO_REINVOKE
785605286c30e1701491bd3af974ae423727750eddDmitry Shmidt/*
795605286c30e1701491bd3af974ae423727750eddDmitry Shmidt * How many seconds to wait for initial 4-way handshake to get completed after
805605286c30e1701491bd3af974ae423727750eddDmitry Shmidt * re-invocation of a persistent group on the GO when the client is expected
815605286c30e1701491bd3af974ae423727750eddDmitry Shmidt * to connect automatically (no user interaction).
825605286c30e1701491bd3af974ae423727750eddDmitry Shmidt */
835605286c30e1701491bd3af974ae423727750eddDmitry Shmidt#define P2P_MAX_INITIAL_CONN_WAIT_GO_REINVOKE 15
845605286c30e1701491bd3af974ae423727750eddDmitry Shmidt#endif /* P2P_MAX_INITIAL_CONN_WAIT_GO_REINVOKE */
855605286c30e1701491bd3af974ae423727750eddDmitry Shmidt
8634af306c42b7ccf956508e7cd23f0ba90606e360Dmitry Shmidt#define P2P_MGMT_DEVICE_PREFIX		"p2p-dev-"
8734af306c42b7ccf956508e7cd23f0ba90606e360Dmitry Shmidt
8861d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidtenum p2p_group_removal_reason {
8961d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt	P2P_GROUP_REMOVAL_UNKNOWN,
9061d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt	P2P_GROUP_REMOVAL_SILENT,
9161d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt	P2P_GROUP_REMOVAL_FORMATION_FAILED,
9261d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt	P2P_GROUP_REMOVAL_REQUESTED,
9361d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt	P2P_GROUP_REMOVAL_IDLE_TIMEOUT,
9461d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt	P2P_GROUP_REMOVAL_UNAVAILABLE,
9561d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt	P2P_GROUP_REMOVAL_GO_ENDING_SESSION,
9604f534e89ed127da4077485376f24debc50d80d5Dmitry Shmidt	P2P_GROUP_REMOVAL_PSK_FAILURE,
9704f534e89ed127da4077485376f24debc50d80d5Dmitry Shmidt	P2P_GROUP_REMOVAL_FREQ_CONFLICT
9861d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt};
9961d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt
100dc7b71324df9788e194745e8ab9386a4619a623aJouni Malinen
1018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic void wpas_p2p_long_listen_timeout(void *eloop_ctx, void *timeout_ctx);
1028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic struct wpa_supplicant *
1038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtwpas_p2p_get_group_iface(struct wpa_supplicant *wpa_s, int addr_allocated,
1048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			 int go);
105cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidtstatic int wpas_p2p_join_start(struct wpa_supplicant *wpa_s, int freq,
106cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt			       const u8 *ssid, size_t ssid_len);
107344abd362cfe2d03ed956666527352826b67bde5Dmitry Shmidtstatic void wpas_p2p_join_scan_req(struct wpa_supplicant *wpa_s, int freq,
108344abd362cfe2d03ed956666527352826b67bde5Dmitry Shmidt				   const u8 *ssid, size_t ssid_len);
1098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic void wpas_p2p_join_scan(void *eloop_ctx, void *timeout_ctx);
1108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic int wpas_p2p_join(struct wpa_supplicant *wpa_s, const u8 *iface_addr,
11104949598a23f501be6eec21697465fd46a28840aDmitry Shmidt			 const u8 *dev_addr, enum p2p_wps_method wps_method,
112cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt			 int auto_join, int freq,
113cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt			 const u8 *ssid, size_t ssid_len);
1148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic int wpas_p2p_create_iface(struct wpa_supplicant *wpa_s);
1158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic void wpas_p2p_cross_connect_setup(struct wpa_supplicant *wpa_s);
1168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic void wpas_p2p_group_idle_timeout(void *eloop_ctx, void *timeout_ctx);
1178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic void wpas_p2p_set_group_idle_timeout(struct wpa_supplicant *wpa_s);
118f86232838cf712377867cb42417c1613ab5dc425Dmitry Shmidtstatic void wpas_p2p_group_formation_timeout(void *eloop_ctx,
119f86232838cf712377867cb42417c1613ab5dc425Dmitry Shmidt					     void *timeout_ctx);
12004f534e89ed127da4077485376f24debc50d80d5Dmitry Shmidtstatic void wpas_p2p_group_freq_conflict(void *eloop_ctx, void *timeout_ctx);
1217f65602d49069f96a7bb44da8bd79ffe8d4c6a98Dmitry Shmidtstatic int wpas_p2p_fallback_to_go_neg(struct wpa_supplicant *wpa_s,
1227f65602d49069f96a7bb44da8bd79ffe8d4c6a98Dmitry Shmidt				       int group_added);
1236c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidtstatic void wpas_p2p_stop_find_oper(struct wpa_supplicant *wpa_s);
124bd14a57187b024f49f5b9ace55ef457d8d04650aDmitry Shmidtstatic void wpas_stop_listen(void *ctx);
125684785c7f4e58498603a9a5ce26f933cc2557ebdDmitry Shmidtstatic void wpas_p2p_psk_failure_removal(void *eloop_ctx, void *timeout_ctx);
12643cb578dfe2c492257636f6234a24178ed27789eDmitry Shmidtstatic void wpas_p2p_group_deinit(struct wpa_supplicant *wpa_s);
127216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidtstatic int wpas_p2p_add_group_interface(struct wpa_supplicant *wpa_s,
128216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt					enum wpa_driver_if_type type);
129a3dc30964aa24aea2b518246f6812663a1103490Dmitry Shmidtstatic void wpas_p2p_group_formation_failed(struct wpa_supplicant *wpa_s,
130a3dc30964aa24aea2b518246f6812663a1103490Dmitry Shmidt					    int already_deleted);
1318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
1328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
133c2ebb4b85d69b65f552fee71ac68f44e8d87b39eDmitry Shmidt/*
134c2ebb4b85d69b65f552fee71ac68f44e8d87b39eDmitry Shmidt * Get the number of concurrent channels that the HW can operate, but that are
135c2ebb4b85d69b65f552fee71ac68f44e8d87b39eDmitry Shmidt * currently not in use by any of the wpa_supplicant interfaces.
136c2ebb4b85d69b65f552fee71ac68f44e8d87b39eDmitry Shmidt */
137c2ebb4b85d69b65f552fee71ac68f44e8d87b39eDmitry Shmidtstatic int wpas_p2p_num_unused_channels(struct wpa_supplicant *wpa_s)
138c2ebb4b85d69b65f552fee71ac68f44e8d87b39eDmitry Shmidt{
139c2ebb4b85d69b65f552fee71ac68f44e8d87b39eDmitry Shmidt	int *freqs;
140b96dad47218788efffa3db0fe7f1b54a7d19e366Dmitry Shmidt	int num, unused;
141c2ebb4b85d69b65f552fee71ac68f44e8d87b39eDmitry Shmidt
142c2ebb4b85d69b65f552fee71ac68f44e8d87b39eDmitry Shmidt	freqs = os_calloc(wpa_s->num_multichan_concurrent, sizeof(int));
143c2ebb4b85d69b65f552fee71ac68f44e8d87b39eDmitry Shmidt	if (!freqs)
144c2ebb4b85d69b65f552fee71ac68f44e8d87b39eDmitry Shmidt		return -1;
145c2ebb4b85d69b65f552fee71ac68f44e8d87b39eDmitry Shmidt
146c2ebb4b85d69b65f552fee71ac68f44e8d87b39eDmitry Shmidt	num = get_shared_radio_freqs(wpa_s, freqs,
147c2ebb4b85d69b65f552fee71ac68f44e8d87b39eDmitry Shmidt				     wpa_s->num_multichan_concurrent);
148c2ebb4b85d69b65f552fee71ac68f44e8d87b39eDmitry Shmidt	os_free(freqs);
149c2ebb4b85d69b65f552fee71ac68f44e8d87b39eDmitry Shmidt
150b96dad47218788efffa3db0fe7f1b54a7d19e366Dmitry Shmidt	unused = wpa_s->num_multichan_concurrent - num;
151b96dad47218788efffa3db0fe7f1b54a7d19e366Dmitry Shmidt	wpa_dbg(wpa_s, MSG_DEBUG, "P2P: num_unused_channels: %d", unused);
152b96dad47218788efffa3db0fe7f1b54a7d19e366Dmitry Shmidt	return unused;
153c2ebb4b85d69b65f552fee71ac68f44e8d87b39eDmitry Shmidt}
154c2ebb4b85d69b65f552fee71ac68f44e8d87b39eDmitry Shmidt
155c2ebb4b85d69b65f552fee71ac68f44e8d87b39eDmitry Shmidt
156c2ebb4b85d69b65f552fee71ac68f44e8d87b39eDmitry Shmidt/*
157c2ebb4b85d69b65f552fee71ac68f44e8d87b39eDmitry Shmidt * Get the frequencies that are currently in use by one or more of the virtual
158c2ebb4b85d69b65f552fee71ac68f44e8d87b39eDmitry Shmidt * interfaces, and that are also valid for P2P operation.
159c2ebb4b85d69b65f552fee71ac68f44e8d87b39eDmitry Shmidt */
16043cb578dfe2c492257636f6234a24178ed27789eDmitry Shmidtstatic unsigned int
16143cb578dfe2c492257636f6234a24178ed27789eDmitry Shmidtwpas_p2p_valid_oper_freqs(struct wpa_supplicant *wpa_s,
16243cb578dfe2c492257636f6234a24178ed27789eDmitry Shmidt			  struct wpa_used_freq_data *p2p_freqs,
16343cb578dfe2c492257636f6234a24178ed27789eDmitry Shmidt			  unsigned int len)
164c2ebb4b85d69b65f552fee71ac68f44e8d87b39eDmitry Shmidt{
16543cb578dfe2c492257636f6234a24178ed27789eDmitry Shmidt	struct wpa_used_freq_data *freqs;
166c2ebb4b85d69b65f552fee71ac68f44e8d87b39eDmitry Shmidt	unsigned int num, i, j;
167c2ebb4b85d69b65f552fee71ac68f44e8d87b39eDmitry Shmidt
16843cb578dfe2c492257636f6234a24178ed27789eDmitry Shmidt	freqs = os_calloc(wpa_s->num_multichan_concurrent,
16943cb578dfe2c492257636f6234a24178ed27789eDmitry Shmidt			  sizeof(struct wpa_used_freq_data));
170c2ebb4b85d69b65f552fee71ac68f44e8d87b39eDmitry Shmidt	if (!freqs)
17143cb578dfe2c492257636f6234a24178ed27789eDmitry Shmidt		return 0;
172c2ebb4b85d69b65f552fee71ac68f44e8d87b39eDmitry Shmidt
17343cb578dfe2c492257636f6234a24178ed27789eDmitry Shmidt	num = get_shared_radio_freqs_data(wpa_s, freqs,
17443cb578dfe2c492257636f6234a24178ed27789eDmitry Shmidt					  wpa_s->num_multichan_concurrent);
175c2ebb4b85d69b65f552fee71ac68f44e8d87b39eDmitry Shmidt
17643cb578dfe2c492257636f6234a24178ed27789eDmitry Shmidt	os_memset(p2p_freqs, 0, sizeof(struct wpa_used_freq_data) * len);
177c2ebb4b85d69b65f552fee71ac68f44e8d87b39eDmitry Shmidt
178c2ebb4b85d69b65f552fee71ac68f44e8d87b39eDmitry Shmidt	for (i = 0, j = 0; i < num && j < len; i++) {
17943cb578dfe2c492257636f6234a24178ed27789eDmitry Shmidt		if (p2p_supported_freq(wpa_s->global->p2p, freqs[i].freq))
180c2ebb4b85d69b65f552fee71ac68f44e8d87b39eDmitry Shmidt			p2p_freqs[j++] = freqs[i];
181c2ebb4b85d69b65f552fee71ac68f44e8d87b39eDmitry Shmidt	}
182c2ebb4b85d69b65f552fee71ac68f44e8d87b39eDmitry Shmidt
183c2ebb4b85d69b65f552fee71ac68f44e8d87b39eDmitry Shmidt	os_free(freqs);
184c2ebb4b85d69b65f552fee71ac68f44e8d87b39eDmitry Shmidt
18543cb578dfe2c492257636f6234a24178ed27789eDmitry Shmidt	dump_freq_data(wpa_s, "valid for P2P", p2p_freqs, j);
186b96dad47218788efffa3db0fe7f1b54a7d19e366Dmitry Shmidt
187c2ebb4b85d69b65f552fee71ac68f44e8d87b39eDmitry Shmidt	return j;
188c2ebb4b85d69b65f552fee71ac68f44e8d87b39eDmitry Shmidt}
189c2ebb4b85d69b65f552fee71ac68f44e8d87b39eDmitry Shmidt
190c2ebb4b85d69b65f552fee71ac68f44e8d87b39eDmitry Shmidt
191700a137ab366edc72e371da68ba187b4717ee660Dmitry Shmidtstatic void wpas_p2p_set_own_freq_preference(struct wpa_supplicant *wpa_s,
192700a137ab366edc72e371da68ba187b4717ee660Dmitry Shmidt					     int freq)
193700a137ab366edc72e371da68ba187b4717ee660Dmitry Shmidt{
194700a137ab366edc72e371da68ba187b4717ee660Dmitry Shmidt	if (wpa_s->global->p2p_disabled || wpa_s->global->p2p == NULL)
195700a137ab366edc72e371da68ba187b4717ee660Dmitry Shmidt		return;
1968bd70b7d6ba220544ee2f0e201e5df23e277fa1dDmitry Shmidt
1978bd70b7d6ba220544ee2f0e201e5df23e277fa1dDmitry Shmidt	/* Use the wpa_s used to control the P2P Device operation */
1988bd70b7d6ba220544ee2f0e201e5df23e277fa1dDmitry Shmidt	wpa_s = wpa_s->global->p2p_init_wpa_s;
1998bd70b7d6ba220544ee2f0e201e5df23e277fa1dDmitry Shmidt
2008bd70b7d6ba220544ee2f0e201e5df23e277fa1dDmitry Shmidt	if (wpa_s->conf->p2p_ignore_shared_freq &&
201a0d265f81180f341d22511538fa18166e1bbce9fDmitry Shmidt	    freq > 0 && wpa_s->num_multichan_concurrent > 1 &&
202a0d265f81180f341d22511538fa18166e1bbce9fDmitry Shmidt	    wpas_p2p_num_unused_channels(wpa_s) > 0) {
203a0d265f81180f341d22511538fa18166e1bbce9fDmitry Shmidt		wpa_printf(MSG_DEBUG, "P2P: Ignore own channel preference %d MHz due to p2p_ignore_shared_freq=1 configuration",
204a0d265f81180f341d22511538fa18166e1bbce9fDmitry Shmidt			   freq);
205700a137ab366edc72e371da68ba187b4717ee660Dmitry Shmidt		freq = 0;
206a0d265f81180f341d22511538fa18166e1bbce9fDmitry Shmidt	}
207700a137ab366edc72e371da68ba187b4717ee660Dmitry Shmidt	p2p_set_own_freq_preference(wpa_s->global->p2p, freq);
208700a137ab366edc72e371da68ba187b4717ee660Dmitry Shmidt}
209700a137ab366edc72e371da68ba187b4717ee660Dmitry Shmidt
210700a137ab366edc72e371da68ba187b4717ee660Dmitry Shmidt
2118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic void wpas_p2p_scan_res_handler(struct wpa_supplicant *wpa_s,
2128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt				      struct wpa_scan_results *scan_res)
2138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{
2148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	size_t i;
2158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
216fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt	if (wpa_s->p2p_scan_work) {
217fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt		struct wpa_radio_work *work = wpa_s->p2p_scan_work;
218fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt		wpa_s->p2p_scan_work = NULL;
219fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt		radio_work_done(work);
220fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt	}
221fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt
2228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (wpa_s->global->p2p_disabled || wpa_s->global->p2p == NULL)
2238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return;
2248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
2258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	wpa_printf(MSG_DEBUG, "P2P: Scan results received (%d BSS)",
2268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		   (int) scan_res->num);
2278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
2288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	for (i = 0; i < scan_res->num; i++) {
2298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		struct wpa_scan_res *bss = scan_res->res[i];
230fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt		struct os_reltime time_tmp_age, entry_ts;
2319657139ca0bbea9a84e0a3c7e9438d1f53c9ed24Dmitry Shmidt		const u8 *ies;
2329657139ca0bbea9a84e0a3c7e9438d1f53c9ed24Dmitry Shmidt		size_t ies_len;
2339657139ca0bbea9a84e0a3c7e9438d1f53c9ed24Dmitry Shmidt
234f86232838cf712377867cb42417c1613ab5dc425Dmitry Shmidt		time_tmp_age.sec = bss->age / 1000;
235f86232838cf712377867cb42417c1613ab5dc425Dmitry Shmidt		time_tmp_age.usec = (bss->age % 1000) * 1000;
236fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt		os_reltime_sub(&scan_res->fetch_time, &time_tmp_age, &entry_ts);
2379657139ca0bbea9a84e0a3c7e9438d1f53c9ed24Dmitry Shmidt
2389657139ca0bbea9a84e0a3c7e9438d1f53c9ed24Dmitry Shmidt		ies = (const u8 *) (bss + 1);
2399657139ca0bbea9a84e0a3c7e9438d1f53c9ed24Dmitry Shmidt		ies_len = bss->ie_len;
2409657139ca0bbea9a84e0a3c7e9438d1f53c9ed24Dmitry Shmidt		if (bss->beacon_ie_len > 0 &&
2419657139ca0bbea9a84e0a3c7e9438d1f53c9ed24Dmitry Shmidt		    !wpa_scan_get_vendor_ie(bss, P2P_IE_VENDOR_TYPE) &&
2429657139ca0bbea9a84e0a3c7e9438d1f53c9ed24Dmitry Shmidt		    wpa_scan_get_vendor_ie_beacon(bss, P2P_IE_VENDOR_TYPE)) {
2439657139ca0bbea9a84e0a3c7e9438d1f53c9ed24Dmitry Shmidt			wpa_printf(MSG_DEBUG, "P2P: Use P2P IE(s) from Beacon frame since no P2P IE(s) in Probe Response frames received for "
2449657139ca0bbea9a84e0a3c7e9438d1f53c9ed24Dmitry Shmidt				   MACSTR, MAC2STR(bss->bssid));
2459657139ca0bbea9a84e0a3c7e9438d1f53c9ed24Dmitry Shmidt			ies = ies + ies_len;
2469657139ca0bbea9a84e0a3c7e9438d1f53c9ed24Dmitry Shmidt			ies_len = bss->beacon_ie_len;
2479657139ca0bbea9a84e0a3c7e9438d1f53c9ed24Dmitry Shmidt		}
2489657139ca0bbea9a84e0a3c7e9438d1f53c9ed24Dmitry Shmidt
2499657139ca0bbea9a84e0a3c7e9438d1f53c9ed24Dmitry Shmidt
2508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		if (p2p_scan_res_handler(wpa_s->global->p2p, bss->bssid,
251f86232838cf712377867cb42417c1613ab5dc425Dmitry Shmidt					 bss->freq, &entry_ts, bss->level,
2529657139ca0bbea9a84e0a3c7e9438d1f53c9ed24Dmitry Shmidt					 ies, ies_len) > 0)
2538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			break;
2548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
2558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
2568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	p2p_scan_res_handled(wpa_s->global->p2p);
2578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt}
2588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
2598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
260fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidtstatic void wpas_p2p_trigger_scan_cb(struct wpa_radio_work *work, int deinit)
261fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt{
262fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt	struct wpa_supplicant *wpa_s = work->wpa_s;
263fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt	struct wpa_driver_scan_params *params = work->ctx;
264fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt	int ret;
265fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt
266fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt	if (deinit) {
267bd14a57187b024f49f5b9ace55ef457d8d04650aDmitry Shmidt		if (!work->started) {
268bd14a57187b024f49f5b9ace55ef457d8d04650aDmitry Shmidt			wpa_scan_free_params(params);
269bd14a57187b024f49f5b9ace55ef457d8d04650aDmitry Shmidt			return;
270bd14a57187b024f49f5b9ace55ef457d8d04650aDmitry Shmidt		}
271bd14a57187b024f49f5b9ace55ef457d8d04650aDmitry Shmidt
272bd14a57187b024f49f5b9ace55ef457d8d04650aDmitry Shmidt		wpa_s->p2p_scan_work = NULL;
273fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt		return;
274fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt	}
275fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt
276fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt	ret = wpa_drv_scan(wpa_s, params);
277fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt	wpa_scan_free_params(params);
278fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt	work->ctx = NULL;
279fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt	if (ret) {
280fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt		radio_work_done(work);
2816c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt		p2p_notify_scan_trigger_status(wpa_s->global->p2p, ret);
282fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt		return;
283fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt	}
284fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt
2856c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt	p2p_notify_scan_trigger_status(wpa_s->global->p2p, ret);
286fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt	os_get_reltime(&wpa_s->scan_trigger_time);
287fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt	wpa_s->scan_res_handler = wpas_p2p_scan_res_handler;
288fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt	wpa_s->own_scan_requested = 1;
289fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt	wpa_s->p2p_scan_work = work;
290fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt}
291fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt
292fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt
2936c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidtstatic int wpas_p2p_search_social_channel(struct wpa_supplicant *wpa_s,
2946c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt					  int freq)
2956c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt{
2966c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt	if (wpa_s->global->p2p_24ghz_social_channels &&
2976c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt	    (freq == 2412 || freq == 2437 || freq == 2462)) {
2986c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt		/*
2996c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt		 * Search all social channels regardless of whether these have
3006c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt		 * been disabled for P2P operating channel use to avoid missing
3016c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt		 * peers.
3026c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt		 */
3036c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt		return 1;
3046c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt	}
3056c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt	return p2p_supported_freq(wpa_s->global->p2p, freq);
3066c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt}
3076c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt
3086c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt
3098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic int wpas_p2p_scan(void *ctx, enum p2p_scan_type type, int freq,
3108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			 unsigned int num_req_dev_types,
31104949598a23f501be6eec21697465fd46a28840aDmitry Shmidt			 const u8 *req_dev_types, const u8 *dev_id, u16 pw_id)
3128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{
3138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	struct wpa_supplicant *wpa_s = ctx;
314fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt	struct wpa_driver_scan_params *params = NULL;
3158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	struct wpabuf *wps_ie, *ies;
316661b4f78e48c697429dc46154a4125892c001718Dmitry Shmidt	unsigned int num_channels = 0;
317661b4f78e48c697429dc46154a4125892c001718Dmitry Shmidt	int social_channels_freq[] = { 2412, 2437, 2462, 60480 };
3181f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt	size_t ielen;
319661b4f78e48c697429dc46154a4125892c001718Dmitry Shmidt	u8 *n, i;
3208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
3218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (wpa_s->global->p2p_disabled || wpa_s->global->p2p == NULL)
3228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return -1;
3238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
324fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt	if (wpa_s->p2p_scan_work) {
325fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt		wpa_dbg(wpa_s, MSG_INFO, "P2P: Reject scan trigger since one is already pending");
326fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt		return -1;
32761d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt	}
32861d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt
329fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt	params = os_zalloc(sizeof(*params));
330fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt	if (params == NULL)
331fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt		return -1;
3328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
3338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	/* P2P Wildcard SSID */
334fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt	params->num_ssids = 1;
335fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt	n = os_malloc(P2P_WILDCARD_SSID_LEN);
336fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt	if (n == NULL)
337fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt		goto fail;
338fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt	os_memcpy(n, P2P_WILDCARD_SSID, P2P_WILDCARD_SSID_LEN);
339fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt	params->ssids[0].ssid = n;
340fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt	params->ssids[0].ssid_len = P2P_WILDCARD_SSID_LEN;
3418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
3428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	wpa_s->wps->dev.p2p = 1;
34304949598a23f501be6eec21697465fd46a28840aDmitry Shmidt	wps_ie = wps_build_probe_req_ie(pw_id, &wpa_s->wps->dev,
34404949598a23f501be6eec21697465fd46a28840aDmitry Shmidt					wpa_s->wps->uuid, WPS_REQ_ENROLLEE,
3458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt					num_req_dev_types, req_dev_types);
3468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (wps_ie == NULL)
347fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt		goto fail;
3488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
3491f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt	ielen = p2p_scan_ie_buf_len(wpa_s->global->p2p);
3501f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt	ies = wpabuf_alloc(wpabuf_len(wps_ie) + ielen);
3518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (ies == NULL) {
3528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		wpabuf_free(wps_ie);
353fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt		goto fail;
3548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
3558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	wpabuf_put_buf(ies, wps_ie);
3568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	wpabuf_free(wps_ie);
3578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
358c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt	p2p_scan_ie(wpa_s->global->p2p, ies, dev_id);
3598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
360fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt	params->p2p_probe = 1;
361fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt	n = os_malloc(wpabuf_len(ies));
362fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt	if (n == NULL) {
363fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt		wpabuf_free(ies);
364fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt		goto fail;
365fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt	}
366fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt	os_memcpy(n, wpabuf_head(ies), wpabuf_len(ies));
367fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt	params->extra_ies = n;
368fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt	params->extra_ies_len = wpabuf_len(ies);
369fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt	wpabuf_free(ies);
3708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
3718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	switch (type) {
3728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	case P2P_SCAN_SOCIAL:
373661b4f78e48c697429dc46154a4125892c001718Dmitry Shmidt		params->freqs = os_calloc(ARRAY_SIZE(social_channels_freq) + 1,
374661b4f78e48c697429dc46154a4125892c001718Dmitry Shmidt					  sizeof(int));
375fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt		if (params->freqs == NULL)
376fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt			goto fail;
377661b4f78e48c697429dc46154a4125892c001718Dmitry Shmidt		for (i = 0; i < ARRAY_SIZE(social_channels_freq); i++) {
3786c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt			if (wpas_p2p_search_social_channel(
3796c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt				    wpa_s, social_channels_freq[i]))
380661b4f78e48c697429dc46154a4125892c001718Dmitry Shmidt				params->freqs[num_channels++] =
381661b4f78e48c697429dc46154a4125892c001718Dmitry Shmidt					social_channels_freq[i];
382661b4f78e48c697429dc46154a4125892c001718Dmitry Shmidt		}
383661b4f78e48c697429dc46154a4125892c001718Dmitry Shmidt		params->freqs[num_channels++] = 0;
3848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		break;
3858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	case P2P_SCAN_FULL:
3868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		break;
387203eadb9eda41a1dde4a583edb4684319e3f399eDmitry Shmidt	case P2P_SCAN_SPECIFIC:
388203eadb9eda41a1dde4a583edb4684319e3f399eDmitry Shmidt		params->freqs = os_calloc(2, sizeof(int));
389203eadb9eda41a1dde4a583edb4684319e3f399eDmitry Shmidt		if (params->freqs == NULL)
390203eadb9eda41a1dde4a583edb4684319e3f399eDmitry Shmidt			goto fail;
391203eadb9eda41a1dde4a583edb4684319e3f399eDmitry Shmidt		params->freqs[0] = freq;
392203eadb9eda41a1dde4a583edb4684319e3f399eDmitry Shmidt		params->freqs[1] = 0;
393203eadb9eda41a1dde4a583edb4684319e3f399eDmitry Shmidt		break;
3948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	case P2P_SCAN_SOCIAL_PLUS_ONE:
395661b4f78e48c697429dc46154a4125892c001718Dmitry Shmidt		params->freqs = os_calloc(ARRAY_SIZE(social_channels_freq) + 2,
396661b4f78e48c697429dc46154a4125892c001718Dmitry Shmidt					  sizeof(int));
397fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt		if (params->freqs == NULL)
398fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt			goto fail;
399661b4f78e48c697429dc46154a4125892c001718Dmitry Shmidt		for (i = 0; i < ARRAY_SIZE(social_channels_freq); i++) {
4006c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt			if (wpas_p2p_search_social_channel(
4016c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt				    wpa_s, social_channels_freq[i]))
402661b4f78e48c697429dc46154a4125892c001718Dmitry Shmidt				params->freqs[num_channels++] =
403661b4f78e48c697429dc46154a4125892c001718Dmitry Shmidt					social_channels_freq[i];
404661b4f78e48c697429dc46154a4125892c001718Dmitry Shmidt		}
405661b4f78e48c697429dc46154a4125892c001718Dmitry Shmidt		if (p2p_supported_freq(wpa_s->global->p2p, freq))
406661b4f78e48c697429dc46154a4125892c001718Dmitry Shmidt			params->freqs[num_channels++] = freq;
407661b4f78e48c697429dc46154a4125892c001718Dmitry Shmidt		params->freqs[num_channels++] = 0;
4088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		break;
4098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
4108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
411bd14a57187b024f49f5b9ace55ef457d8d04650aDmitry Shmidt	radio_remove_works(wpa_s, "p2p-scan", 0);
412fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt	if (radio_add_work(wpa_s, 0, "p2p-scan", 0, wpas_p2p_trigger_scan_cb,
413fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt			   params) < 0)
414fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt		goto fail;
415fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt	return 0;
4168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
417fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidtfail:
418fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt	wpa_scan_free_params(params);
419fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt	return -1;
4208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt}
4218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
4228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
4238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic enum wpa_driver_if_type wpas_p2p_if_type(int p2p_group_interface)
4248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{
4258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	switch (p2p_group_interface) {
4268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	case P2P_GROUP_INTERFACE_PENDING:
4278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return WPA_IF_P2P_GROUP;
4288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	case P2P_GROUP_INTERFACE_GO:
4298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return WPA_IF_P2P_GO;
4308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	case P2P_GROUP_INTERFACE_CLIENT:
4318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return WPA_IF_P2P_CLIENT;
4328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
4338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
4348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	return WPA_IF_P2P_GROUP;
4358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt}
4368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
4378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
4388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic struct wpa_supplicant * wpas_get_p2p_group(struct wpa_supplicant *wpa_s,
4398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt						  const u8 *ssid,
4408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt						  size_t ssid_len, int *go)
4418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{
4428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	struct wpa_ssid *s;
4438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
4448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	for (wpa_s = wpa_s->global->ifaces; wpa_s; wpa_s = wpa_s->next) {
4458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		for (s = wpa_s->conf->ssid; s; s = s->next) {
4468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			if (s->disabled != 0 || !s->p2p_group ||
4478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			    s->ssid_len != ssid_len ||
4488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			    os_memcmp(ssid, s->ssid, ssid_len) != 0)
4498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt				continue;
4508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			if (s->mode == WPAS_MODE_P2P_GO &&
4518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			    s != wpa_s->current_ssid)
4528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt				continue;
4538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			if (go)
4548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt				*go = s->mode == WPAS_MODE_P2P_GO;
4558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			return wpa_s;
4568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		}
4578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
4588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
4598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	return NULL;
4608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt}
4618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
4628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
4636c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidtstatic void run_wpas_p2p_disconnect(void *eloop_ctx, void *timeout_ctx)
4646c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt{
4656c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt	struct wpa_supplicant *wpa_s = eloop_ctx;
4666c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt	wpa_printf(MSG_DEBUG,
4676c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt		   "P2P: Complete previously requested removal of %s",
4686c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt		   wpa_s->ifname);
4696c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt	wpas_p2p_disconnect(wpa_s);
4706c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt}
4716c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt
4726c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt
4736c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidtstatic int wpas_p2p_disconnect_safely(struct wpa_supplicant *wpa_s,
4746c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt				      struct wpa_supplicant *calling_wpa_s)
4756c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt{
4766c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt	if (calling_wpa_s == wpa_s && wpa_s &&
4776c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt	    wpa_s->p2p_group_interface != NOT_P2P_GROUP_INTERFACE) {
4786c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt		/*
4796c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt		 * The calling wpa_s instance is going to be removed. Do that
4806c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt		 * from an eloop callback to keep the instance available until
4816c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt		 * the caller has returned. This my be needed, e.g., to provide
4826c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt		 * control interface responses on the per-interface socket.
4836c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt		 */
4846c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt		if (eloop_register_timeout(0, 0, run_wpas_p2p_disconnect,
4856c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt					   wpa_s, NULL) < 0)
4866c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt			return -1;
4876c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt		return 0;
4886c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt	}
4896c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt
4906c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt	return wpas_p2p_disconnect(wpa_s);
4916c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt}
4926c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt
4936c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt
494216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt/* Determine total number of clients in active groups where we are the GO */
495216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidtstatic unsigned int p2p_group_go_member_count(struct wpa_supplicant *wpa_s)
496216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt{
497216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt	unsigned int count = 0;
498216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt	struct wpa_ssid *s;
499216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt
500216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt	for (wpa_s = wpa_s->global->ifaces; wpa_s; wpa_s = wpa_s->next) {
501216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt		for (s = wpa_s->conf->ssid; s; s = s->next) {
502216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt			wpa_printf(MSG_DEBUG,
503216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt				   "P2P: sup:%p ssid:%p disabled:%d p2p:%d mode:%d",
504216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt				   wpa_s, s, s->disabled, s->p2p_group,
505216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt				   s->mode);
506216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt			if (!s->disabled && s->p2p_group &&
507216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt			    s->mode == WPAS_MODE_P2P_GO) {
508216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt				count += p2p_get_group_num_members(
509216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt					wpa_s->p2p_group);
510216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt			}
511216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt		}
512216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt	}
513216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt
514216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt	return count;
515216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt}
516216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt
517216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt
518216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt/* Find an interface for a P2P group where we are the GO */
519216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidtstatic struct wpa_supplicant *
520216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidtwpas_p2p_get_go_group(struct wpa_supplicant *wpa_s)
521216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt{
522216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt	struct wpa_supplicant *save = NULL;
523216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt	struct wpa_ssid *s;
524216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt
525216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt	if (!wpa_s)
526216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt		return NULL;
527216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt
528216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt	for (wpa_s = wpa_s->global->ifaces; wpa_s; wpa_s = wpa_s->next) {
529216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt		for (s = wpa_s->conf->ssid; s; s = s->next) {
530216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt			if (s->disabled || !s->p2p_group ||
531216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt			    s->mode != WPAS_MODE_P2P_GO)
532216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt				continue;
533216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt
534216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt			/* Prefer a group with connected clients */
535216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt			if (p2p_get_group_num_members(wpa_s->p2p_group))
536216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt				return wpa_s;
537216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt			save = wpa_s;
538216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt		}
539216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt	}
540216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt
541216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt	/* No group with connected clients, so pick the one without (if any) */
542216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt	return save;
543216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt}
544216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt
545216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt
546216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt/* Find an active P2P group where we are the GO */
547216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidtstatic struct wpa_ssid * wpas_p2p_group_go_ssid(struct wpa_supplicant *wpa_s,
548216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt						u8 *bssid)
549216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt{
550216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt	struct wpa_ssid *s, *empty = NULL;
551216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt
552216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt	if (!wpa_s)
553216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt		return 0;
554216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt
555216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt	for (wpa_s = wpa_s->global->ifaces; wpa_s; wpa_s = wpa_s->next) {
556216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt		for (s = wpa_s->conf->ssid; s; s = s->next) {
557216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt			if (s->disabled || !s->p2p_group ||
558216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt			    s->mode != WPAS_MODE_P2P_GO)
559216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt				continue;
560216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt
561216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt			os_memcpy(bssid, wpa_s->own_addr, ETH_ALEN);
562216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt			if (p2p_get_group_num_members(wpa_s->p2p_group))
563216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt				return s;
564216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt			empty = s;
565216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt		}
566216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt	}
567216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt
568216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt	return empty;
569216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt}
570216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt
571216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt
572216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt/* Find a persistent group where we are the GO */
573216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidtstatic struct wpa_ssid *
574216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidtwpas_p2p_get_persistent_go(struct wpa_supplicant *wpa_s)
575216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt{
576216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt	struct wpa_ssid *s;
577216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt
578216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt	for (s = wpa_s->conf->ssid; s; s = s->next) {
579216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt		if (s->disabled == 2 && s->mode == WPAS_MODE_P2P_GO)
580216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt			return s;
581216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt	}
582216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt
583216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt	return NULL;
584216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt}
585216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt
586216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt
587216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidtstatic u8 p2ps_group_capability(void *ctx, u8 incoming, u8 role)
588216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt{
589216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt	struct wpa_supplicant *wpa_s = ctx, *tmp_wpa_s;
590216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt	struct wpa_ssid *s;
591216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt	u8 conncap = P2PS_SETUP_NONE;
592216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt	unsigned int owned_members = 0;
593216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt	unsigned int owner = 0;
594216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt	unsigned int client = 0;
595216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt	struct wpa_supplicant *go_wpa_s;
596216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt	struct wpa_ssid *persistent_go;
597216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt	int p2p_no_group_iface;
598216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt
599216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt	wpa_printf(MSG_DEBUG, "P2P: Conncap - in:%d role:%d", incoming, role);
600216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt
601216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt	/*
602216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt	 * For non-concurrent capable devices:
603216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt	 * If persistent_go, then no new.
604216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt	 * If GO, then no client.
605216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt	 * If client, then no GO.
606216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt	 */
607216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt	go_wpa_s = wpas_p2p_get_go_group(wpa_s);
608216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt	persistent_go = wpas_p2p_get_persistent_go(wpa_s);
609216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt	p2p_no_group_iface = wpa_s->conf->p2p_no_group_iface;
610216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt
611216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt	wpa_printf(MSG_DEBUG, "P2P: GO(iface)=%p persistent(ssid)=%p",
612216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt		   go_wpa_s, persistent_go);
613216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt
614216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt	for (tmp_wpa_s = wpa_s->global->ifaces; tmp_wpa_s;
615216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt	     tmp_wpa_s = tmp_wpa_s->next) {
616216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt		for (s = tmp_wpa_s->conf->ssid; s; s = s->next) {
617216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt			wpa_printf(MSG_DEBUG,
618216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt				   "P2P: sup:%p ssid:%p disabled:%d p2p:%d mode:%d",
619216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt				   tmp_wpa_s, s, s->disabled,
620216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt				   s->p2p_group, s->mode);
621216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt			if (!s->disabled && s->p2p_group) {
622216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt				if (s->mode == WPAS_MODE_P2P_GO) {
623216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt					owned_members +=
624216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt						p2p_get_group_num_members(
625216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt							tmp_wpa_s->p2p_group);
626216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt					owner++;
627216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt				} else
628216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt					client++;
629216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt			}
630216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt		}
631216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt	}
632216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt
633216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt	/* If not concurrent, restrict our choices */
634216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt	if (p2p_no_group_iface) {
635216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt		wpa_printf(MSG_DEBUG, "P2P: p2p_no_group_iface");
636216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt
637216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt		if (client)
638216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt			return P2PS_SETUP_NONE;
639216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt
640216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt		if (go_wpa_s) {
641216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt			if (role == P2PS_SETUP_CLIENT ||
642216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt			    incoming == P2PS_SETUP_GROUP_OWNER ||
643216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt			    p2p_client_limit_reached(go_wpa_s->p2p_group))
644216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt				return P2PS_SETUP_NONE;
645216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt
646216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt			return P2PS_SETUP_GROUP_OWNER;
647216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt		}
648216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt
649216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt		if (persistent_go) {
650216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt			if (role == P2PS_SETUP_NONE || role == P2PS_SETUP_NEW) {
651216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt				if (!incoming)
652216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt					return P2PS_SETUP_GROUP_OWNER |
653216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt						P2PS_SETUP_CLIENT;
654216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt				if (incoming == P2PS_SETUP_NEW) {
655216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt					u8 r;
656216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt
657216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt					if (os_get_random(&r, sizeof(r)) < 0 ||
658216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt					    (r & 1))
659216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt						return P2PS_SETUP_CLIENT;
660216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt					return P2PS_SETUP_GROUP_OWNER;
661216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt				}
662216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt			}
663216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt		}
664216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt	}
665216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt
666216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt	/* If a required role has been specified, handle it here */
667216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt	if (role && role != P2PS_SETUP_NEW) {
668216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt		switch (incoming) {
669216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt		case P2PS_SETUP_NONE:
670216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt		case P2PS_SETUP_NEW:
671216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt		case P2PS_SETUP_GROUP_OWNER | P2PS_SETUP_CLIENT:
672216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt		case P2PS_SETUP_GROUP_OWNER | P2PS_SETUP_NEW:
673216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt			conncap = role;
674216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt			goto grp_owner;
675216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt
676216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt		case P2PS_SETUP_GROUP_OWNER:
677216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt			/*
678216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt			 * Must be a complimentary role - cannot be a client to
679216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt			 * more than one peer.
680216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt			 */
681216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt			if (incoming == role || client)
682216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt				return P2PS_SETUP_NONE;
683216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt
684216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt			return P2PS_SETUP_CLIENT;
685216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt
686216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt		case P2PS_SETUP_CLIENT:
687216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt			/* Must be a complimentary role */
688216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt			if (incoming != role) {
689216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt				conncap = P2PS_SETUP_GROUP_OWNER;
690216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt				goto grp_owner;
691216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt			}
692216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt
693216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt		default:
694216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt			return P2PS_SETUP_NONE;
695216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt		}
696216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt	}
697216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt
698216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt	/*
699216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt	 * For now, we only will support ownership of one group, and being a
700216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt	 * client of one group. Therefore, if we have either an existing GO
701216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt	 * group, or an existing client group, we will not do a new GO
702216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt	 * negotiation, but rather try to re-use the existing groups.
703216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt	 */
704216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt	switch (incoming) {
705216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt	case P2PS_SETUP_NONE:
706216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt	case P2PS_SETUP_NEW:
707216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt		if (client)
708216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt			conncap = P2PS_SETUP_GROUP_OWNER;
709216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt		else if (!owned_members)
710216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt			conncap = P2PS_SETUP_NEW;
711216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt		else if (incoming == P2PS_SETUP_NONE)
712216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt			conncap = P2PS_SETUP_GROUP_OWNER | P2PS_SETUP_CLIENT;
713216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt		else
714216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt			conncap = P2PS_SETUP_CLIENT;
715216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt		break;
716216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt
717216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt	case P2PS_SETUP_CLIENT:
718216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt		conncap = P2PS_SETUP_GROUP_OWNER;
719216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt		break;
720216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt
721216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt	case P2PS_SETUP_GROUP_OWNER:
722216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt		if (!client)
723216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt			conncap = P2PS_SETUP_CLIENT;
724216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt		break;
725216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt
726216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt	case P2PS_SETUP_GROUP_OWNER | P2PS_SETUP_NEW:
727216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt	case P2PS_SETUP_GROUP_OWNER | P2PS_SETUP_CLIENT:
728216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt		if (client)
729216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt			conncap = P2PS_SETUP_GROUP_OWNER;
730216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt		else {
731216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt			u8 r;
732216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt
733216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt			if (os_get_random(&r, sizeof(r)) < 0 ||
734216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt			    (r & 1))
735216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt				conncap = P2PS_SETUP_CLIENT;
736216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt			else
737216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt				conncap = P2PS_SETUP_GROUP_OWNER;
738216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt		}
739216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt		break;
740216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt
741216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt	default:
742216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt		return P2PS_SETUP_NONE;
743216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt	}
744216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt
745216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidtgrp_owner:
746216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt	if ((conncap & P2PS_SETUP_GROUP_OWNER) ||
747216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt	    (!incoming && (conncap & P2PS_SETUP_NEW))) {
748216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt		if (go_wpa_s && p2p_client_limit_reached(go_wpa_s->p2p_group))
749216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt			conncap &= ~P2PS_SETUP_GROUP_OWNER;
750216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt		wpa_printf(MSG_DEBUG, "P2P: GOs:%d members:%d conncap:%d",
751216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt			   owner, owned_members, conncap);
752216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt
753216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt		s = wpas_p2p_get_persistent_go(wpa_s);
754216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt
755216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt		if (!s && !owner && p2p_no_group_iface) {
756216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt			p2p_set_intended_addr(wpa_s->global->p2p,
757216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt					      wpa_s->own_addr);
758216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt		} else if (!s && !owner) {
759216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt			if (wpas_p2p_add_group_interface(wpa_s,
760216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt							 WPA_IF_P2P_GO) < 0) {
761216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt				wpa_printf(MSG_ERROR,
762216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt					   "P2P: Failed to allocate a new interface for the group");
763216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt				return P2PS_SETUP_NONE;
764216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt			}
765216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt			wpa_s->global->pending_group_iface_for_p2ps = 1;
766216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt			p2p_set_intended_addr(wpa_s->global->p2p,
767216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt					      wpa_s->pending_interface_addr);
768216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt		}
769216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt	}
770216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt
771216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt	return conncap;
772216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt}
773216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt
774216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt
77561d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidtstatic int wpas_p2p_group_delete(struct wpa_supplicant *wpa_s,
77661d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt				 enum p2p_group_removal_reason removal_reason)
7778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{
7788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	struct wpa_ssid *ssid;
7798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	char *gtype;
7808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	const char *reason;
7818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
7828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	ssid = wpa_s->current_ssid;
7838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (ssid == NULL) {
7848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		/*
7858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		 * The current SSID was not known, but there may still be a
786aa532510a7b8c4da2d7d6e2c11dda5db840894e4Dmitry Shmidt		 * pending P2P group interface waiting for provisioning or a
787aa532510a7b8c4da2d7d6e2c11dda5db840894e4Dmitry Shmidt		 * P2P group that is trying to reconnect.
7888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		 */
7898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		ssid = wpa_s->conf->ssid;
7908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		while (ssid) {
7919d71283328fbad680cc74d9b287580e373eb4d6cJouni Malinen			if (ssid->p2p_group && ssid->disabled != 2)
7928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt				break;
7938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			ssid = ssid->next;
7948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		}
7955c44edb00c9384534a1b50981071874436aaecd5Jouni Malinen		if (ssid == NULL &&
7965c44edb00c9384534a1b50981071874436aaecd5Jouni Malinen			wpa_s->p2p_group_interface == NOT_P2P_GROUP_INTERFACE)
7975c44edb00c9384534a1b50981071874436aaecd5Jouni Malinen		{
79861d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt			wpa_printf(MSG_ERROR, "P2P: P2P group interface "
79961d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt				   "not found");
80061d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt			return -1;
80161d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt		}
8028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
8038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (wpa_s->p2p_group_interface == P2P_GROUP_INTERFACE_GO)
8048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		gtype = "GO";
8058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	else if (wpa_s->p2p_group_interface == P2P_GROUP_INTERFACE_CLIENT ||
8068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		 (ssid && ssid->mode == WPAS_MODE_INFRA)) {
8078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		wpa_s->reassociate = 0;
8088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		wpa_s->disconnected = 1;
8098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		gtype = "client";
8108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	} else
8118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		gtype = "GO";
812661b4f78e48c697429dc46154a4125892c001718Dmitry Shmidt
813661b4f78e48c697429dc46154a4125892c001718Dmitry Shmidt	if (removal_reason != P2P_GROUP_REMOVAL_SILENT && ssid)
814661b4f78e48c697429dc46154a4125892c001718Dmitry Shmidt		wpas_notify_p2p_group_removed(wpa_s, ssid, gtype);
815661b4f78e48c697429dc46154a4125892c001718Dmitry Shmidt
8166c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt	if (os_strcmp(gtype, "client") == 0) {
817661b4f78e48c697429dc46154a4125892c001718Dmitry Shmidt		wpa_supplicant_deauthenticate(wpa_s, WLAN_REASON_DEAUTH_LEAVING);
8186c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt		if (eloop_is_timeout_registered(wpas_p2p_psk_failure_removal,
8196c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt						wpa_s, NULL)) {
8206c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt			wpa_printf(MSG_DEBUG,
8216c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt				   "P2P: PSK failure removal was scheduled, so use PSK failure as reason for group removal");
8226c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt			removal_reason = P2P_GROUP_REMOVAL_PSK_FAILURE;
8236c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt			eloop_cancel_timeout(wpas_p2p_psk_failure_removal,
8246c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt					     wpa_s, NULL);
8256c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt		}
8266c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt	}
827661b4f78e48c697429dc46154a4125892c001718Dmitry Shmidt
8288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (wpa_s->cross_connect_in_use) {
8298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		wpa_s->cross_connect_in_use = 0;
830b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt		wpa_msg_global(wpa_s->parent, MSG_INFO,
831b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt			       P2P_EVENT_CROSS_CONNECT_DISABLE "%s %s",
832b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt			       wpa_s->ifname, wpa_s->cross_connect_uplink);
8338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
83461d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt	switch (removal_reason) {
8358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	case P2P_GROUP_REMOVAL_REQUESTED:
8368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		reason = " reason=REQUESTED";
8378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		break;
83861d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt	case P2P_GROUP_REMOVAL_FORMATION_FAILED:
83961d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt		reason = " reason=FORMATION_FAILED";
84061d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt		break;
8418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	case P2P_GROUP_REMOVAL_IDLE_TIMEOUT:
8428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		reason = " reason=IDLE";
8438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		break;
8448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	case P2P_GROUP_REMOVAL_UNAVAILABLE:
8458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		reason = " reason=UNAVAILABLE";
8468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		break;
84704949598a23f501be6eec21697465fd46a28840aDmitry Shmidt	case P2P_GROUP_REMOVAL_GO_ENDING_SESSION:
84804949598a23f501be6eec21697465fd46a28840aDmitry Shmidt		reason = " reason=GO_ENDING_SESSION";
84904949598a23f501be6eec21697465fd46a28840aDmitry Shmidt		break;
850391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt	case P2P_GROUP_REMOVAL_PSK_FAILURE:
851391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt		reason = " reason=PSK_FAILURE";
852391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt		break;
85304f534e89ed127da4077485376f24debc50d80d5Dmitry Shmidt	case P2P_GROUP_REMOVAL_FREQ_CONFLICT:
85404f534e89ed127da4077485376f24debc50d80d5Dmitry Shmidt		reason = " reason=FREQ_CONFLICT";
85504f534e89ed127da4077485376f24debc50d80d5Dmitry Shmidt		break;
8568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	default:
8578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		reason = "";
8588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		break;
8598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
86061d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt	if (removal_reason != P2P_GROUP_REMOVAL_SILENT) {
861b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt		wpa_msg_global(wpa_s->parent, MSG_INFO,
862b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt			       P2P_EVENT_GROUP_REMOVED "%s %s%s",
863b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt			       wpa_s->ifname, gtype, reason);
86404949598a23f501be6eec21697465fd46a28840aDmitry Shmidt	}
8658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
86604f534e89ed127da4077485376f24debc50d80d5Dmitry Shmidt	if (eloop_cancel_timeout(wpas_p2p_group_freq_conflict, wpa_s, NULL) > 0)
86704f534e89ed127da4077485376f24debc50d80d5Dmitry Shmidt		wpa_printf(MSG_DEBUG, "P2P: Cancelled P2P group freq_conflict timeout");
86804949598a23f501be6eec21697465fd46a28840aDmitry Shmidt	if (eloop_cancel_timeout(wpas_p2p_group_idle_timeout, wpa_s, NULL) > 0)
86904949598a23f501be6eec21697465fd46a28840aDmitry Shmidt		wpa_printf(MSG_DEBUG, "P2P: Cancelled P2P group idle timeout");
870f86232838cf712377867cb42417c1613ab5dc425Dmitry Shmidt	if (eloop_cancel_timeout(wpas_p2p_group_formation_timeout,
8712f023193a0fd630eb82ce6381b80911ad5a3462fDmitry Shmidt				 wpa_s->parent, NULL) > 0) {
872f86232838cf712377867cb42417c1613ab5dc425Dmitry Shmidt		wpa_printf(MSG_DEBUG, "P2P: Cancelled P2P group formation "
873f86232838cf712377867cb42417c1613ab5dc425Dmitry Shmidt			   "timeout");
8742f023193a0fd630eb82ce6381b80911ad5a3462fDmitry Shmidt		wpa_s->p2p_in_provisioning = 0;
8752f023193a0fd630eb82ce6381b80911ad5a3462fDmitry Shmidt	}
87604949598a23f501be6eec21697465fd46a28840aDmitry Shmidt
87715907098d1f67c24bb000e593e279af173cf57d7Dmitry Shmidt	wpa_s->p2p_in_invitation = 0;
87815907098d1f67c24bb000e593e279af173cf57d7Dmitry Shmidt
8799657139ca0bbea9a84e0a3c7e9438d1f53c9ed24Dmitry Shmidt	/*
8809657139ca0bbea9a84e0a3c7e9438d1f53c9ed24Dmitry Shmidt	 * Make sure wait for the first client does not remain active after the
8819657139ca0bbea9a84e0a3c7e9438d1f53c9ed24Dmitry Shmidt	 * group has been removed.
8829657139ca0bbea9a84e0a3c7e9438d1f53c9ed24Dmitry Shmidt	 */
8839657139ca0bbea9a84e0a3c7e9438d1f53c9ed24Dmitry Shmidt	wpa_s->global->p2p_go_wait_client.sec = 0;
8849657139ca0bbea9a84e0a3c7e9438d1f53c9ed24Dmitry Shmidt
8858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (wpa_s->p2p_group_interface != NOT_P2P_GROUP_INTERFACE) {
8868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		struct wpa_global *global;
8878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		char *ifname;
8888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		enum wpa_driver_if_type type;
8898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		wpa_printf(MSG_DEBUG, "P2P: Remove group interface %s",
8908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			wpa_s->ifname);
8918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		global = wpa_s->global;
8928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		ifname = os_strdup(wpa_s->ifname);
8938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		type = wpas_p2p_if_type(wpa_s->p2p_group_interface);
8946c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt		eloop_cancel_timeout(run_wpas_p2p_disconnect, wpa_s, NULL);
895e15c7b57cc7a214d5adaa0fc1d7204378eaf62a5Dmitry Shmidt		wpa_supplicant_remove_iface(wpa_s->global, wpa_s, 0);
8968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		wpa_s = global->ifaces;
8978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		if (wpa_s && ifname)
8988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			wpa_drv_if_remove(wpa_s, type, ifname);
8998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		os_free(ifname);
9002b89da85b8cfe9bb862e8dd334855263c3522c00Jouni Malinen		return 1;
9018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
9028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
9039657139ca0bbea9a84e0a3c7e9438d1f53c9ed24Dmitry Shmidt	if (!wpa_s->p2p_go_group_formation_completed) {
9049657139ca0bbea9a84e0a3c7e9438d1f53c9ed24Dmitry Shmidt		wpa_s->global->p2p_group_formation = NULL;
9059657139ca0bbea9a84e0a3c7e9438d1f53c9ed24Dmitry Shmidt		wpa_s->p2p_in_provisioning = 0;
9069657139ca0bbea9a84e0a3c7e9438d1f53c9ed24Dmitry Shmidt	}
9079657139ca0bbea9a84e0a3c7e9438d1f53c9ed24Dmitry Shmidt
908cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt	wpa_s->show_group_started = 0;
909cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt	os_free(wpa_s->go_params);
910cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt	wpa_s->go_params = NULL;
911cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt
9126c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt	os_free(wpa_s->p2p_group_common_freqs);
9136c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt	wpa_s->p2p_group_common_freqs = NULL;
9146c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt	wpa_s->p2p_group_common_freqs_num = 0;
9156c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt
916fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt	wpa_s->waiting_presence_resp = 0;
917fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt
9188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	wpa_printf(MSG_DEBUG, "P2P: Remove temporary group network");
9198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (ssid && (ssid->p2p_group ||
9208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		     ssid->mode == WPAS_MODE_P2P_GROUP_FORMATION ||
9218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		     (ssid->key_mgmt & WPA_KEY_MGMT_WPS))) {
9228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		int id = ssid->id;
92375ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen		if (ssid == wpa_s->current_ssid) {
92475ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen			wpa_sm_set_config(wpa_s->wpa, NULL);
92575ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen			eapol_sm_notify_config(wpa_s->eapol, NULL, NULL);
9268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			wpa_s->current_ssid = NULL;
92775ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen		}
92875ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen		/*
92975ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen		 * Networks objects created during any P2P activities are not
93075ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen		 * exposed out as they might/will confuse certain non-P2P aware
93175ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen		 * applications since these network objects won't behave like
93275ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen		 * regular ones.
93375ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen		 *
93475ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen		 * Likewise, we don't send out network removed signals for such
93575ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen		 * network objects.
93675ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen		 */
9378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		wpa_config_remove_network(wpa_s->conf, id);
9388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		wpa_supplicant_clear_status(wpa_s);
939c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt		wpa_supplicant_cancel_sched_scan(wpa_s);
9408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	} else {
9418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		wpa_printf(MSG_DEBUG, "P2P: Temporary group network not "
9428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			   "found");
9438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
94404949598a23f501be6eec21697465fd46a28840aDmitry Shmidt	if (wpa_s->ap_iface)
94504949598a23f501be6eec21697465fd46a28840aDmitry Shmidt		wpa_supplicant_ap_deinit(wpa_s);
94604949598a23f501be6eec21697465fd46a28840aDmitry Shmidt	else
94704949598a23f501be6eec21697465fd46a28840aDmitry Shmidt		wpa_drv_deinit_p2p_cli(wpa_s);
94861d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt
94961d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt	return 0;
9508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt}
9518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
9528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
9538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic int wpas_p2p_persistent_group(struct wpa_supplicant *wpa_s,
9548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt				     u8 *go_dev_addr,
9558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt				     const u8 *ssid, size_t ssid_len)
9568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{
9578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	struct wpa_bss *bss;
9588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	const u8 *bssid;
9598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	struct wpabuf *p2p;
9608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	u8 group_capab;
9618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	const u8 *addr;
9628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
9638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (wpa_s->go_params)
9648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		bssid = wpa_s->go_params->peer_interface_addr;
9658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	else
9668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		bssid = wpa_s->bssid;
9678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
9688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	bss = wpa_bss_get(wpa_s, bssid, ssid, ssid_len);
969cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt	if (bss == NULL && wpa_s->go_params &&
970cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt	    !is_zero_ether_addr(wpa_s->go_params->peer_device_addr))
971cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt		bss = wpa_bss_get_p2p_dev_addr(
972cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt			wpa_s, wpa_s->go_params->peer_device_addr);
9738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (bss == NULL) {
9748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		u8 iface_addr[ETH_ALEN];
9758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		if (p2p_get_interface_addr(wpa_s->global->p2p, bssid,
9768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt					   iface_addr) == 0)
9778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			bss = wpa_bss_get(wpa_s, iface_addr, ssid, ssid_len);
9788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
9798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (bss == NULL) {
9808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		wpa_printf(MSG_DEBUG, "P2P: Could not figure out whether "
9818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			   "group is persistent - BSS " MACSTR " not found",
9828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			   MAC2STR(bssid));
9838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return 0;
9848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
9858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
9868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	p2p = wpa_bss_get_vendor_ie_multi(bss, P2P_IE_VENDOR_TYPE);
9879657139ca0bbea9a84e0a3c7e9438d1f53c9ed24Dmitry Shmidt	if (p2p == NULL)
9889657139ca0bbea9a84e0a3c7e9438d1f53c9ed24Dmitry Shmidt		p2p = wpa_bss_get_vendor_ie_multi_beacon(bss,
9899657139ca0bbea9a84e0a3c7e9438d1f53c9ed24Dmitry Shmidt							 P2P_IE_VENDOR_TYPE);
9908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (p2p == NULL) {
9918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		wpa_printf(MSG_DEBUG, "P2P: Could not figure out whether "
9928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			   "group is persistent - BSS " MACSTR
9938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			   " did not include P2P IE", MAC2STR(bssid));
9948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		wpa_hexdump(MSG_DEBUG, "P2P: Probe Response IEs",
9958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			    (u8 *) (bss + 1), bss->ie_len);
9968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		wpa_hexdump(MSG_DEBUG, "P2P: Beacon IEs",
9978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			    ((u8 *) bss + 1) + bss->ie_len,
9988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			    bss->beacon_ie_len);
9998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return 0;
10008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
10018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
10028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	group_capab = p2p_get_group_capab(p2p);
10038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	addr = p2p_get_go_dev_addr(p2p);
10048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	wpa_printf(MSG_DEBUG, "P2P: Checking whether group is persistent: "
10058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		   "group_capab=0x%x", group_capab);
10068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (addr) {
10078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		os_memcpy(go_dev_addr, addr, ETH_ALEN);
10088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		wpa_printf(MSG_DEBUG, "P2P: GO Device Address " MACSTR,
10098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			   MAC2STR(addr));
10108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	} else
10118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		os_memset(go_dev_addr, 0, ETH_ALEN);
10128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	wpabuf_free(p2p);
10138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
10148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	wpa_printf(MSG_DEBUG, "P2P: BSS " MACSTR " group_capab=0x%x "
10158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		   "go_dev_addr=" MACSTR,
10168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		   MAC2STR(bssid), group_capab, MAC2STR(go_dev_addr));
10178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
10188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	return group_capab & P2P_GROUP_CAPAB_PERSISTENT_GROUP;
10198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt}
10208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
10218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
102275ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinenstatic int wpas_p2p_store_persistent_group(struct wpa_supplicant *wpa_s,
102375ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen					   struct wpa_ssid *ssid,
102475ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen					   const u8 *go_dev_addr)
10258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{
10268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	struct wpa_ssid *s;
10278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	int changed = 0;
10288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
10298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	wpa_printf(MSG_DEBUG, "P2P: Storing credentials for a persistent "
10308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		   "group (GO Dev Addr " MACSTR ")", MAC2STR(go_dev_addr));
10318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	for (s = wpa_s->conf->ssid; s; s = s->next) {
10328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		if (s->disabled == 2 &&
10338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		    os_memcmp(go_dev_addr, s->bssid, ETH_ALEN) == 0 &&
10348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		    s->ssid_len == ssid->ssid_len &&
10358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		    os_memcmp(ssid->ssid, s->ssid, ssid->ssid_len) == 0)
10368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			break;
10378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
10388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
10398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (s) {
10408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		wpa_printf(MSG_DEBUG, "P2P: Update existing persistent group "
10418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			   "entry");
10428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		if (ssid->passphrase && !s->passphrase)
10438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			changed = 1;
10448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		else if (ssid->passphrase && s->passphrase &&
10458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			 os_strcmp(ssid->passphrase, s->passphrase) != 0)
10468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			changed = 1;
10478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	} else {
10488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		wpa_printf(MSG_DEBUG, "P2P: Create a new persistent group "
10498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			   "entry");
10508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		changed = 1;
10518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		s = wpa_config_add_network(wpa_s->conf);
10528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		if (s == NULL)
105375ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen			return -1;
105475ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen
105575ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen		/*
105675ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen		 * Instead of network_added we emit persistent_group_added
105775ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen		 * notification. Also to keep the defense checks in
105875ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen		 * persistent_group obj registration method, we set the
105975ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen		 * relevant flags in s to designate it as a persistent group.
106075ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen		 */
106175ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen		s->p2p_group = 1;
106275ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen		s->p2p_persistent_group = 1;
106375ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen		wpas_notify_persistent_group_added(wpa_s, s);
10648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		wpa_config_set_network_defaults(s);
10658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
10668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
10678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	s->p2p_group = 1;
10688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	s->p2p_persistent_group = 1;
10698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	s->disabled = 2;
10708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	s->bssid_set = 1;
10718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	os_memcpy(s->bssid, go_dev_addr, ETH_ALEN);
10728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	s->mode = ssid->mode;
10738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	s->auth_alg = WPA_AUTH_ALG_OPEN;
10748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	s->key_mgmt = WPA_KEY_MGMT_PSK;
10758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	s->proto = WPA_PROTO_RSN;
10768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	s->pairwise_cipher = WPA_CIPHER_CCMP;
10778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	s->export_keys = 1;
10788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (ssid->passphrase) {
10798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		os_free(s->passphrase);
10808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		s->passphrase = os_strdup(ssid->passphrase);
10818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
10828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (ssid->psk_set) {
10838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		s->psk_set = 1;
10848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		os_memcpy(s->psk, ssid->psk, 32);
10858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
10868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (s->passphrase && !s->psk_set)
10878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		wpa_config_update_psk(s);
10888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (s->ssid == NULL || s->ssid_len < ssid->ssid_len) {
10898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		os_free(s->ssid);
10908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		s->ssid = os_malloc(ssid->ssid_len);
10918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
10928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (s->ssid) {
10938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		s->ssid_len = ssid->ssid_len;
10948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		os_memcpy(s->ssid, ssid->ssid, s->ssid_len);
10958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
1096391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt	if (ssid->mode == WPAS_MODE_P2P_GO && wpa_s->global->add_psk) {
1097391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt		dl_list_add(&s->psk_list, &wpa_s->global->add_psk->list);
1098391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt		wpa_s->global->add_psk = NULL;
1099391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt		changed = 1;
1100391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt	}
11018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
11028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (changed && wpa_s->conf->update_config &&
11038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	    wpa_config_write(wpa_s->confname, wpa_s->conf)) {
11048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		wpa_printf(MSG_DEBUG, "P2P: Failed to update configuration");
11058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
110675ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen
110775ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen	return s->id;
11088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt}
11098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
11108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
11111f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidtstatic void wpas_p2p_add_persistent_group_client(struct wpa_supplicant *wpa_s,
11121f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt						 const u8 *addr)
11131f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt{
11141f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt	struct wpa_ssid *ssid, *s;
11151f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt	u8 *n;
11161f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt	size_t i;
111761d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt	int found = 0;
11188bd70b7d6ba220544ee2f0e201e5df23e277fa1dDmitry Shmidt	struct wpa_supplicant *p2p_wpa_s = wpa_s->global->p2p_init_wpa_s;
11191f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt
11201f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt	ssid = wpa_s->current_ssid;
11211f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt	if (ssid == NULL || ssid->mode != WPAS_MODE_P2P_GO ||
11221f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt	    !ssid->p2p_persistent_group)
11231f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt		return;
11241f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt
11258bd70b7d6ba220544ee2f0e201e5df23e277fa1dDmitry Shmidt	for (s = p2p_wpa_s->conf->ssid; s; s = s->next) {
11261f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt		if (s->disabled != 2 || s->mode != WPAS_MODE_P2P_GO)
11271f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt			continue;
11281f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt
11291f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt		if (s->ssid_len == ssid->ssid_len &&
11301f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt		    os_memcmp(s->ssid, ssid->ssid, s->ssid_len) == 0)
11311f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt			break;
11321f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt	}
11331f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt
11341f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt	if (s == NULL)
11351f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt		return;
11361f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt
11371f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt	for (i = 0; s->p2p_client_list && i < s->num_p2p_clients; i++) {
1138ff787d557db719adea0fdf2679667500c65cf74dDmitry Shmidt		if (os_memcmp(s->p2p_client_list + i * 2 * ETH_ALEN, addr,
113961d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt			      ETH_ALEN) != 0)
114061d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt			continue;
114161d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt
114261d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt		if (i == s->num_p2p_clients - 1)
114361d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt			return; /* already the most recent entry */
114461d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt
114561d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt		/* move the entry to mark it most recent */
1146ff787d557db719adea0fdf2679667500c65cf74dDmitry Shmidt		os_memmove(s->p2p_client_list + i * 2 * ETH_ALEN,
1147ff787d557db719adea0fdf2679667500c65cf74dDmitry Shmidt			   s->p2p_client_list + (i + 1) * 2 * ETH_ALEN,
1148ff787d557db719adea0fdf2679667500c65cf74dDmitry Shmidt			   (s->num_p2p_clients - i - 1) * 2 * ETH_ALEN);
114961d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt		os_memcpy(s->p2p_client_list +
1150ff787d557db719adea0fdf2679667500c65cf74dDmitry Shmidt			  (s->num_p2p_clients - 1) * 2 * ETH_ALEN, addr,
1151ff787d557db719adea0fdf2679667500c65cf74dDmitry Shmidt			  ETH_ALEN);
1152ff787d557db719adea0fdf2679667500c65cf74dDmitry Shmidt		os_memset(s->p2p_client_list +
1153ff787d557db719adea0fdf2679667500c65cf74dDmitry Shmidt			  (s->num_p2p_clients - 1) * 2 * ETH_ALEN + ETH_ALEN,
1154ff787d557db719adea0fdf2679667500c65cf74dDmitry Shmidt			  0xff, ETH_ALEN);
115561d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt		found = 1;
115661d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt		break;
11571f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt	}
11581f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt
115961d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt	if (!found && s->num_p2p_clients < P2P_MAX_STORED_CLIENTS) {
116061d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt		n = os_realloc_array(s->p2p_client_list,
1161ff787d557db719adea0fdf2679667500c65cf74dDmitry Shmidt				     s->num_p2p_clients + 1, 2 * ETH_ALEN);
116261d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt		if (n == NULL)
116361d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt			return;
1164ff787d557db719adea0fdf2679667500c65cf74dDmitry Shmidt		os_memcpy(n + s->num_p2p_clients * 2 * ETH_ALEN, addr,
1165ff787d557db719adea0fdf2679667500c65cf74dDmitry Shmidt			  ETH_ALEN);
1166ff787d557db719adea0fdf2679667500c65cf74dDmitry Shmidt		os_memset(n + s->num_p2p_clients * 2 * ETH_ALEN + ETH_ALEN,
1167ff787d557db719adea0fdf2679667500c65cf74dDmitry Shmidt			  0xff, ETH_ALEN);
116861d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt		s->p2p_client_list = n;
116961d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt		s->num_p2p_clients++;
11706aa8ae4b6139bdf5593301474277dcdbc2528190Dmitry Shmidt	} else if (!found && s->p2p_client_list) {
117161d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt		/* Not enough room for an additional entry - drop the oldest
117261d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt		 * entry */
117361d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt		os_memmove(s->p2p_client_list,
1174ff787d557db719adea0fdf2679667500c65cf74dDmitry Shmidt			   s->p2p_client_list + 2 * ETH_ALEN,
1175ff787d557db719adea0fdf2679667500c65cf74dDmitry Shmidt			   (s->num_p2p_clients - 1) * 2 * ETH_ALEN);
117661d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt		os_memcpy(s->p2p_client_list +
1177ff787d557db719adea0fdf2679667500c65cf74dDmitry Shmidt			  (s->num_p2p_clients - 1) * 2 * ETH_ALEN,
117861d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt			  addr, ETH_ALEN);
1179ff787d557db719adea0fdf2679667500c65cf74dDmitry Shmidt		os_memset(s->p2p_client_list +
1180ff787d557db719adea0fdf2679667500c65cf74dDmitry Shmidt			  (s->num_p2p_clients - 1) * 2 * ETH_ALEN + ETH_ALEN,
1181ff787d557db719adea0fdf2679667500c65cf74dDmitry Shmidt			  0xff, ETH_ALEN);
118261d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt	}
11831f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt
11848bd70b7d6ba220544ee2f0e201e5df23e277fa1dDmitry Shmidt	if (p2p_wpa_s->conf->update_config &&
11858bd70b7d6ba220544ee2f0e201e5df23e277fa1dDmitry Shmidt	    wpa_config_write(p2p_wpa_s->confname, p2p_wpa_s->conf))
11861f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt		wpa_printf(MSG_DEBUG, "P2P: Failed to update configuration");
11871f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt}
11881f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt
11891f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt
11907f0b69e88015ca077ef7a417fde0a76c10df23a5Dmitry Shmidtstatic void wpas_p2p_group_started(struct wpa_supplicant *wpa_s,
11917f0b69e88015ca077ef7a417fde0a76c10df23a5Dmitry Shmidt				   int go, struct wpa_ssid *ssid, int freq,
11927f0b69e88015ca077ef7a417fde0a76c10df23a5Dmitry Shmidt				   const u8 *psk, const char *passphrase,
11937f0b69e88015ca077ef7a417fde0a76c10df23a5Dmitry Shmidt				   const u8 *go_dev_addr, int persistent,
11947f0b69e88015ca077ef7a417fde0a76c10df23a5Dmitry Shmidt				   const char *extra)
11957f0b69e88015ca077ef7a417fde0a76c10df23a5Dmitry Shmidt{
11967f0b69e88015ca077ef7a417fde0a76c10df23a5Dmitry Shmidt	const char *ssid_txt;
11977f0b69e88015ca077ef7a417fde0a76c10df23a5Dmitry Shmidt	char psk_txt[65];
11987f0b69e88015ca077ef7a417fde0a76c10df23a5Dmitry Shmidt
11997f0b69e88015ca077ef7a417fde0a76c10df23a5Dmitry Shmidt	if (psk)
12007f0b69e88015ca077ef7a417fde0a76c10df23a5Dmitry Shmidt		wpa_snprintf_hex(psk_txt, sizeof(psk_txt), psk, 32);
12017f0b69e88015ca077ef7a417fde0a76c10df23a5Dmitry Shmidt	else
12027f0b69e88015ca077ef7a417fde0a76c10df23a5Dmitry Shmidt		psk_txt[0] = '\0';
12037f0b69e88015ca077ef7a417fde0a76c10df23a5Dmitry Shmidt
12047f0b69e88015ca077ef7a417fde0a76c10df23a5Dmitry Shmidt	if (ssid)
12057f0b69e88015ca077ef7a417fde0a76c10df23a5Dmitry Shmidt		ssid_txt = wpa_ssid_txt(ssid->ssid, ssid->ssid_len);
12067f0b69e88015ca077ef7a417fde0a76c10df23a5Dmitry Shmidt	else
12077f0b69e88015ca077ef7a417fde0a76c10df23a5Dmitry Shmidt		ssid_txt = "";
12087f0b69e88015ca077ef7a417fde0a76c10df23a5Dmitry Shmidt
12097f0b69e88015ca077ef7a417fde0a76c10df23a5Dmitry Shmidt	if (passphrase && passphrase[0] == '\0')
12107f0b69e88015ca077ef7a417fde0a76c10df23a5Dmitry Shmidt		passphrase = NULL;
12117f0b69e88015ca077ef7a417fde0a76c10df23a5Dmitry Shmidt
12127f0b69e88015ca077ef7a417fde0a76c10df23a5Dmitry Shmidt	/*
12137f0b69e88015ca077ef7a417fde0a76c10df23a5Dmitry Shmidt	 * Include PSK/passphrase only in the control interface message and
12147f0b69e88015ca077ef7a417fde0a76c10df23a5Dmitry Shmidt	 * leave it out from the debug log entry.
12157f0b69e88015ca077ef7a417fde0a76c10df23a5Dmitry Shmidt	 */
12167f0b69e88015ca077ef7a417fde0a76c10df23a5Dmitry Shmidt	wpa_msg_global_ctrl(wpa_s->parent, MSG_INFO,
12177f0b69e88015ca077ef7a417fde0a76c10df23a5Dmitry Shmidt			    P2P_EVENT_GROUP_STARTED
12187f0b69e88015ca077ef7a417fde0a76c10df23a5Dmitry Shmidt			    "%s %s ssid=\"%s\" freq=%d%s%s%s%s%s go_dev_addr="
12197f0b69e88015ca077ef7a417fde0a76c10df23a5Dmitry Shmidt			    MACSTR "%s%s",
12207f0b69e88015ca077ef7a417fde0a76c10df23a5Dmitry Shmidt			    wpa_s->ifname, go ? "GO" : "client", ssid_txt, freq,
12217f0b69e88015ca077ef7a417fde0a76c10df23a5Dmitry Shmidt			    psk ? " psk=" : "", psk_txt,
12227f0b69e88015ca077ef7a417fde0a76c10df23a5Dmitry Shmidt			    passphrase ? " passphrase=\"" : "",
12237f0b69e88015ca077ef7a417fde0a76c10df23a5Dmitry Shmidt			    passphrase ? passphrase : "",
12247f0b69e88015ca077ef7a417fde0a76c10df23a5Dmitry Shmidt			    passphrase ? "\"" : "",
12257f0b69e88015ca077ef7a417fde0a76c10df23a5Dmitry Shmidt			    MAC2STR(go_dev_addr),
12267f0b69e88015ca077ef7a417fde0a76c10df23a5Dmitry Shmidt			    persistent ? " [PERSISTENT]" : "", extra);
12277f0b69e88015ca077ef7a417fde0a76c10df23a5Dmitry Shmidt	wpa_printf(MSG_INFO, P2P_EVENT_GROUP_STARTED
12287f0b69e88015ca077ef7a417fde0a76c10df23a5Dmitry Shmidt		   "%s %s ssid=\"%s\" freq=%d go_dev_addr=" MACSTR "%s%s",
12297f0b69e88015ca077ef7a417fde0a76c10df23a5Dmitry Shmidt		   wpa_s->ifname, go ? "GO" : "client", ssid_txt, freq,
12307f0b69e88015ca077ef7a417fde0a76c10df23a5Dmitry Shmidt		   MAC2STR(go_dev_addr), persistent ? " [PERSISTENT]" : "",
12317f0b69e88015ca077ef7a417fde0a76c10df23a5Dmitry Shmidt		   extra);
12327f0b69e88015ca077ef7a417fde0a76c10df23a5Dmitry Shmidt}
12337f0b69e88015ca077ef7a417fde0a76c10df23a5Dmitry Shmidt
12347f0b69e88015ca077ef7a417fde0a76c10df23a5Dmitry Shmidt
12358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic void wpas_group_formation_completed(struct wpa_supplicant *wpa_s,
1236a3dc30964aa24aea2b518246f6812663a1103490Dmitry Shmidt					   int success, int already_deleted)
12378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{
12388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	struct wpa_ssid *ssid;
12398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	int client;
12408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	int persistent;
12418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	u8 go_dev_addr[ETH_ALEN];
124275ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen	int network_id = -1;
12438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
12448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	/*
12458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	 * This callback is likely called for the main interface. Update wpa_s
12468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	 * to use the group interface if a new interface was created for the
12478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	 * group.
12488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	 */
12498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (wpa_s->global->p2p_group_formation)
12508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		wpa_s = wpa_s->global->p2p_group_formation;
12515605286c30e1701491bd3af974ae423727750eddDmitry Shmidt	if (wpa_s->p2p_go_group_formation_completed) {
12525605286c30e1701491bd3af974ae423727750eddDmitry Shmidt		wpa_s->global->p2p_group_formation = NULL;
12535605286c30e1701491bd3af974ae423727750eddDmitry Shmidt		wpa_s->p2p_in_provisioning = 0;
12545605286c30e1701491bd3af974ae423727750eddDmitry Shmidt	}
125521de214b4ba4271ca20843f3b8fba9f1501b2a89Dmitry Shmidt	wpa_s->p2p_in_invitation = 0;
12566c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt	wpa_s->group_formation_reported = 1;
12578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
12588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (!success) {
1259b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt		wpa_msg_global(wpa_s->parent, MSG_INFO,
1260b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt			       P2P_EVENT_GROUP_FORMATION_FAILURE);
1261a3dc30964aa24aea2b518246f6812663a1103490Dmitry Shmidt		if (already_deleted)
1262a3dc30964aa24aea2b518246f6812663a1103490Dmitry Shmidt			return;
126361d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt		wpas_p2p_group_delete(wpa_s,
126461d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt				      P2P_GROUP_REMOVAL_FORMATION_FAILED);
12658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return;
12668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
12678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
1268b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt	wpa_msg_global(wpa_s->parent, MSG_INFO,
1269b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt		       P2P_EVENT_GROUP_FORMATION_SUCCESS);
12708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
12718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	ssid = wpa_s->current_ssid;
12728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (ssid && ssid->mode == WPAS_MODE_P2P_GROUP_FORMATION) {
12738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		ssid->mode = WPAS_MODE_P2P_GO;
12748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		p2p_group_notif_formation_done(wpa_s->p2p_group);
12758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		wpa_supplicant_ap_mac_addr_filter(wpa_s, NULL);
12768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
12778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
12788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	persistent = 0;
12798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (ssid) {
12808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		client = ssid->mode == WPAS_MODE_INFRA;
12818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		if (ssid->mode == WPAS_MODE_P2P_GO) {
12828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			persistent = ssid->p2p_persistent_group;
1283497c1d5e50162d6b3c1cce5dbd9c5fd9da69aaefDmitry Shmidt			os_memcpy(go_dev_addr, wpa_s->global->p2p_dev_addr,
1284497c1d5e50162d6b3c1cce5dbd9c5fd9da69aaefDmitry Shmidt				  ETH_ALEN);
12858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		} else
12868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			persistent = wpas_p2p_persistent_group(wpa_s,
12878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt							       go_dev_addr,
12888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt							       ssid->ssid,
12898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt							       ssid->ssid_len);
12908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	} else {
12918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		client = wpa_s->p2p_group_interface ==
12928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			P2P_GROUP_INTERFACE_CLIENT;
12938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		os_memset(go_dev_addr, 0, ETH_ALEN);
12948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
12958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
12968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	wpa_s->show_group_started = 0;
12978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (client) {
12988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		/*
12998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		 * Indicate event only after successfully completed 4-way
13008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		 * handshake, i.e., when the interface is ready for data
13018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		 * packets.
13028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		 */
13038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		wpa_s->show_group_started = 1;
13048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	} else {
13057f0b69e88015ca077ef7a417fde0a76c10df23a5Dmitry Shmidt		wpas_p2p_group_started(wpa_s, 1, ssid,
13067f0b69e88015ca077ef7a417fde0a76c10df23a5Dmitry Shmidt				       ssid ? ssid->frequency : 0,
13077f0b69e88015ca077ef7a417fde0a76c10df23a5Dmitry Shmidt				       ssid && ssid->passphrase == NULL &&
13087f0b69e88015ca077ef7a417fde0a76c10df23a5Dmitry Shmidt				       ssid->psk_set ? ssid->psk : NULL,
13097f0b69e88015ca077ef7a417fde0a76c10df23a5Dmitry Shmidt				       ssid ? ssid->passphrase : NULL,
13107f0b69e88015ca077ef7a417fde0a76c10df23a5Dmitry Shmidt				       go_dev_addr, persistent, "");
13118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		wpas_p2p_cross_connect_setup(wpa_s);
13128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		wpas_p2p_set_group_idle_timeout(wpa_s);
13138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
13148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
13158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (persistent)
131675ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen		network_id = wpas_p2p_store_persistent_group(wpa_s->parent,
131775ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen							     ssid, go_dev_addr);
1318391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt	else {
1319391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt		os_free(wpa_s->global->add_psk);
1320391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt		wpa_s->global->add_psk = NULL;
1321391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt	}
13221f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt	if (network_id < 0 && ssid)
132375ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen		network_id = ssid->id;
132492c368d56f46a4e648b441085707c1381b5e5f63Dmitry Shmidt	if (!client) {
132575ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen		wpas_notify_p2p_group_started(wpa_s, ssid, network_id, 0);
1326fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt		os_get_reltime(&wpa_s->global->p2p_go_wait_client);
132792c368d56f46a4e648b441085707c1381b5e5f63Dmitry Shmidt	}
13288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt}
13298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
13308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
1331fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidtstruct send_action_work {
1332fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt	unsigned int freq;
1333fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt	u8 dst[ETH_ALEN];
1334fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt	u8 src[ETH_ALEN];
1335fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt	u8 bssid[ETH_ALEN];
1336fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt	size_t len;
1337fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt	unsigned int wait_time;
1338fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt	u8 buf[0];
1339fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt};
1340fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt
1341fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt
1342fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidtstatic void wpas_p2p_send_action_work_timeout(void *eloop_ctx,
1343fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt					      void *timeout_ctx)
1344fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt{
1345fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt	struct wpa_supplicant *wpa_s = eloop_ctx;
1346fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt
1347fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt	if (!wpa_s->p2p_send_action_work)
1348fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt		return;
1349fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt
1350fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt	wpa_printf(MSG_DEBUG, "P2P: Send Action frame radio work timed out");
1351fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt	os_free(wpa_s->p2p_send_action_work->ctx);
1352fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt	radio_work_done(wpa_s->p2p_send_action_work);
1353fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt	wpa_s->p2p_send_action_work = NULL;
1354fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt}
1355fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt
1356fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt
135703658834c33748b9ad86f3d4cdf0c7be9c6887d1Dmitry Shmidtstatic void wpas_p2p_action_tx_clear(struct wpa_supplicant *wpa_s)
13588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{
1359fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt	if (wpa_s->p2p_send_action_work) {
1360fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt		struct send_action_work *awork;
1361fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt		awork = wpa_s->p2p_send_action_work->ctx;
1362fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt		if (awork->wait_time == 0) {
1363fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt			os_free(awork);
1364fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt			radio_work_done(wpa_s->p2p_send_action_work);
1365fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt			wpa_s->p2p_send_action_work = NULL;
1366fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt		} else {
1367fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt			/*
1368fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt			 * In theory, this should not be needed, but number of
1369fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt			 * places in the P2P code is still using non-zero wait
1370fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt			 * time for the last Action frame in the sequence and
1371fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt			 * some of these do not call send_action_done().
1372fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt			 */
1373fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt			eloop_cancel_timeout(wpas_p2p_send_action_work_timeout,
1374fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt					     wpa_s, NULL);
1375fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt			eloop_register_timeout(
1376fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt				0, awork->wait_time * 1000,
1377fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt				wpas_p2p_send_action_work_timeout,
1378fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt				wpa_s, NULL);
1379fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt		}
1380fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt	}
138103658834c33748b9ad86f3d4cdf0c7be9c6887d1Dmitry Shmidt}
138203658834c33748b9ad86f3d4cdf0c7be9c6887d1Dmitry Shmidt
138303658834c33748b9ad86f3d4cdf0c7be9c6887d1Dmitry Shmidt
138403658834c33748b9ad86f3d4cdf0c7be9c6887d1Dmitry Shmidtstatic void wpas_p2p_send_action_tx_status(struct wpa_supplicant *wpa_s,
138503658834c33748b9ad86f3d4cdf0c7be9c6887d1Dmitry Shmidt					   unsigned int freq,
138603658834c33748b9ad86f3d4cdf0c7be9c6887d1Dmitry Shmidt					   const u8 *dst, const u8 *src,
138703658834c33748b9ad86f3d4cdf0c7be9c6887d1Dmitry Shmidt					   const u8 *bssid,
138803658834c33748b9ad86f3d4cdf0c7be9c6887d1Dmitry Shmidt					   const u8 *data, size_t data_len,
138903658834c33748b9ad86f3d4cdf0c7be9c6887d1Dmitry Shmidt					   enum offchannel_send_action_result
139003658834c33748b9ad86f3d4cdf0c7be9c6887d1Dmitry Shmidt					   result)
139103658834c33748b9ad86f3d4cdf0c7be9c6887d1Dmitry Shmidt{
139203658834c33748b9ad86f3d4cdf0c7be9c6887d1Dmitry Shmidt	enum p2p_send_action_result res = P2P_SEND_ACTION_SUCCESS;
139303658834c33748b9ad86f3d4cdf0c7be9c6887d1Dmitry Shmidt
139403658834c33748b9ad86f3d4cdf0c7be9c6887d1Dmitry Shmidt	wpas_p2p_action_tx_clear(wpa_s);
1395fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt
13968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (wpa_s->global->p2p == NULL || wpa_s->global->p2p_disabled)
13978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return;
13988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
13991f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt	switch (result) {
14001f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt	case OFFCHANNEL_SEND_ACTION_SUCCESS:
14011f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt		res = P2P_SEND_ACTION_SUCCESS;
14021f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt		break;
14031f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt	case OFFCHANNEL_SEND_ACTION_NO_ACK:
14041f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt		res = P2P_SEND_ACTION_NO_ACK;
14051f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt		break;
14061f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt	case OFFCHANNEL_SEND_ACTION_FAILED:
14071f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt		res = P2P_SEND_ACTION_FAILED;
14081f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt		break;
14098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
14108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
14111f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt	p2p_send_action_cb(wpa_s->global->p2p, freq, dst, src, bssid, res);
14128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
1413c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt	if (result != OFFCHANNEL_SEND_ACTION_SUCCESS &&
1414c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt	    wpa_s->pending_pd_before_join &&
14151f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt	    (os_memcmp(dst, wpa_s->pending_join_dev_addr, ETH_ALEN) == 0 ||
1416d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt	     os_memcmp(dst, wpa_s->pending_join_iface_addr, ETH_ALEN) == 0) &&
1417d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt	    wpa_s->p2p_fallback_to_go_neg) {
14188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		wpa_s->pending_pd_before_join = 0;
1419d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt		wpa_dbg(wpa_s, MSG_DEBUG, "P2P: No ACK for PD Req "
1420d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt			"during p2p_connect-auto");
14217f65602d49069f96a7bb44da8bd79ffe8d4c6a98Dmitry Shmidt		wpa_msg_global(wpa_s->parent, MSG_INFO,
14227f65602d49069f96a7bb44da8bd79ffe8d4c6a98Dmitry Shmidt			       P2P_EVENT_FALLBACK_TO_GO_NEG
14237f65602d49069f96a7bb44da8bd79ffe8d4c6a98Dmitry Shmidt			       "reason=no-ACK-to-PD-Req");
1424d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt		wpas_p2p_fallback_to_go_neg(wpa_s, 0);
1425d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt		return;
14268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
14278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt}
14288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
14298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
1430fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidtstatic void wpas_send_action_cb(struct wpa_radio_work *work, int deinit)
1431fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt{
1432fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt	struct wpa_supplicant *wpa_s = work->wpa_s;
1433fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt	struct send_action_work *awork = work->ctx;
1434fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt
1435fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt	if (deinit) {
1436bd14a57187b024f49f5b9ace55ef457d8d04650aDmitry Shmidt		if (work->started) {
1437bd14a57187b024f49f5b9ace55ef457d8d04650aDmitry Shmidt			eloop_cancel_timeout(wpas_p2p_send_action_work_timeout,
1438bd14a57187b024f49f5b9ace55ef457d8d04650aDmitry Shmidt					     wpa_s, NULL);
1439bd14a57187b024f49f5b9ace55ef457d8d04650aDmitry Shmidt			wpa_s->p2p_send_action_work = NULL;
1440bd14a57187b024f49f5b9ace55ef457d8d04650aDmitry Shmidt			offchannel_send_action_done(wpa_s);
1441bd14a57187b024f49f5b9ace55ef457d8d04650aDmitry Shmidt		}
1442fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt		os_free(awork);
1443fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt		return;
1444fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt	}
1445fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt
1446fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt	if (offchannel_send_action(wpa_s, awork->freq, awork->dst, awork->src,
1447fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt				   awork->bssid, awork->buf, awork->len,
1448fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt				   awork->wait_time,
1449fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt				   wpas_p2p_send_action_tx_status, 1) < 0) {
1450fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt		os_free(awork);
1451fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt		radio_work_done(work);
1452fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt		return;
1453fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt	}
1454fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt	wpa_s->p2p_send_action_work = work;
1455fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt}
1456fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt
1457fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt
1458fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidtstatic int wpas_send_action_work(struct wpa_supplicant *wpa_s,
1459fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt				 unsigned int freq, const u8 *dst,
1460fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt				 const u8 *src, const u8 *bssid, const u8 *buf,
1461fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt				 size_t len, unsigned int wait_time)
1462fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt{
1463fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt	struct send_action_work *awork;
1464fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt
1465fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt	if (wpa_s->p2p_send_action_work) {
1466fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt		wpa_printf(MSG_DEBUG, "P2P: Cannot schedule new p2p-send-action work since one is already pending");
1467fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt		return -1;
1468fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt	}
1469fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt
1470fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt	awork = os_zalloc(sizeof(*awork) + len);
1471fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt	if (awork == NULL)
1472fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt		return -1;
1473fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt
1474fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt	awork->freq = freq;
1475fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt	os_memcpy(awork->dst, dst, ETH_ALEN);
1476fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt	os_memcpy(awork->src, src, ETH_ALEN);
1477fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt	os_memcpy(awork->bssid, bssid, ETH_ALEN);
1478fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt	awork->len = len;
1479fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt	awork->wait_time = wait_time;
1480fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt	os_memcpy(awork->buf, buf, len);
1481fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt
1482fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt	if (radio_add_work(wpa_s, freq, "p2p-send-action", 0,
1483fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt			   wpas_send_action_cb, awork) < 0) {
1484fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt		os_free(awork);
1485fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt		return -1;
1486fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt	}
1487fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt
1488fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt	return 0;
1489fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt}
1490fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt
1491fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt
14928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic int wpas_send_action(void *ctx, unsigned int freq, const u8 *dst,
14938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			    const u8 *src, const u8 *bssid, const u8 *buf,
14948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			    size_t len, unsigned int wait_time)
14958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{
14968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	struct wpa_supplicant *wpa_s = ctx;
1497fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt	int listen_freq = -1, send_freq = -1;
1498fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt
1499fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt	if (wpa_s->p2p_listen_work)
1500fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt		listen_freq = wpa_s->p2p_listen_work->freq;
1501fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt	if (wpa_s->p2p_send_action_work)
1502fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt		send_freq = wpa_s->p2p_send_action_work->freq;
1503fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt	if (listen_freq != (int) freq && send_freq != (int) freq) {
1504fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt		wpa_printf(MSG_DEBUG, "P2P: Schedule new radio work for Action frame TX (listen_freq=%d send_freq=%d)",
1505fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt			   listen_freq, send_freq);
1506fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt		return wpas_send_action_work(wpa_s, freq, dst, src, bssid, buf,
1507fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt					     len, wait_time);
1508fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt	}
1509fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt
1510fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt	wpa_printf(MSG_DEBUG, "P2P: Use ongoing radio work for Action frame TX");
15111f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt	return offchannel_send_action(wpa_s, freq, dst, src, bssid, buf, len,
15121f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt				      wait_time,
15131f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt				      wpas_p2p_send_action_tx_status, 1);
15148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt}
15158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
15168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
15178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic void wpas_send_action_done(void *ctx)
15188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{
15198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	struct wpa_supplicant *wpa_s = ctx;
1520fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt
1521fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt	if (wpa_s->p2p_send_action_work) {
1522fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt		eloop_cancel_timeout(wpas_p2p_send_action_work_timeout,
1523fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt				     wpa_s, NULL);
1524fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt		os_free(wpa_s->p2p_send_action_work->ctx);
1525fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt		radio_work_done(wpa_s->p2p_send_action_work);
1526fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt		wpa_s->p2p_send_action_work = NULL;
1527fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt	}
1528fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt
15291f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt	offchannel_send_action_done(wpa_s);
15308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt}
15318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
15328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
15338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic int wpas_copy_go_neg_results(struct wpa_supplicant *wpa_s,
15348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt				    struct p2p_go_neg_results *params)
15358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{
15368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (wpa_s->go_params == NULL) {
15378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		wpa_s->go_params = os_malloc(sizeof(*params));
15388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		if (wpa_s->go_params == NULL)
15398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			return -1;
15408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
15418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	os_memcpy(wpa_s->go_params, params, sizeof(*params));
15428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	return 0;
15438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt}
15448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
15458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
15468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic void wpas_start_wps_enrollee(struct wpa_supplicant *wpa_s,
15478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt				    struct p2p_go_neg_results *res)
15488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{
15496c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt	wpa_s->group_formation_reported = 0;
1550cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt	wpa_printf(MSG_DEBUG, "P2P: Start WPS Enrollee for peer " MACSTR
1551cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt		   " dev_addr " MACSTR " wps_method %d",
1552cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt		   MAC2STR(res->peer_interface_addr),
1553cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt		   MAC2STR(res->peer_device_addr), res->wps_method);
15548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	wpa_hexdump_ascii(MSG_DEBUG, "P2P: Start WPS Enrollee for SSID",
15558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			  res->ssid, res->ssid_len);
15568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	wpa_supplicant_ap_deinit(wpa_s);
15578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	wpas_copy_go_neg_results(wpa_s, res);
1558cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt	if (res->wps_method == WPS_PBC) {
15598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		wpas_wps_start_pbc(wpa_s, res->peer_interface_addr, 1);
1560cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt#ifdef CONFIG_WPS_NFC
1561cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt	} else if (res->wps_method == WPS_NFC) {
1562cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt		wpas_wps_start_nfc(wpa_s, res->peer_device_addr,
1563cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt				   res->peer_interface_addr,
1564cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt				   wpa_s->parent->p2p_oob_dev_pw,
1565cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt				   wpa_s->parent->p2p_oob_dev_pw_id, 1,
1566cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt				   wpa_s->parent->p2p_oob_dev_pw_id ==
1567cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt				   DEV_PW_NFC_CONNECTION_HANDOVER ?
1568cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt				   wpa_s->parent->p2p_peer_oob_pubkey_hash :
1569cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt				   NULL,
1570cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt				   NULL, 0, 0);
1571cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt#endif /* CONFIG_WPS_NFC */
1572cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt	} else {
15738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		u16 dev_pw_id = DEV_PW_DEFAULT;
1574216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt		if (wpa_s->p2p_wps_method == WPS_P2PS)
1575216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt			dev_pw_id = DEV_PW_P2PS_DEFAULT;
15768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		if (wpa_s->p2p_wps_method == WPS_PIN_KEYPAD)
15778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			dev_pw_id = DEV_PW_REGISTRAR_SPECIFIED;
15788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		wpas_wps_start_pin(wpa_s, res->peer_interface_addr,
15798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt				   wpa_s->p2p_pin, 1, dev_pw_id);
15808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
15818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt}
15828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
15838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
1584391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidtstatic void wpas_p2p_add_psk_list(struct wpa_supplicant *wpa_s,
1585391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt				  struct wpa_ssid *ssid)
1586391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt{
1587391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt	struct wpa_ssid *persistent;
1588391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt	struct psk_list_entry *psk;
1589391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt	struct hostapd_data *hapd;
1590391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt
1591391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt	if (!wpa_s->ap_iface)
1592391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt		return;
1593391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt
1594391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt	persistent = wpas_p2p_get_persistent(wpa_s->parent, NULL, ssid->ssid,
1595391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt					     ssid->ssid_len);
1596391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt	if (persistent == NULL)
1597391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt		return;
1598391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt
1599391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt	hapd = wpa_s->ap_iface->bss[0];
1600391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt
1601391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt	dl_list_for_each(psk, &persistent->psk_list, struct psk_list_entry,
1602391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt			 list) {
1603391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt		struct hostapd_wpa_psk *hpsk;
1604391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt
1605391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt		wpa_dbg(wpa_s, MSG_DEBUG, "P2P: Add persistent group PSK entry for "
1606391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt			MACSTR " psk=%d",
1607391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt			MAC2STR(psk->addr), psk->p2p);
1608391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt		hpsk = os_zalloc(sizeof(*hpsk));
1609391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt		if (hpsk == NULL)
1610391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt			break;
1611391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt		os_memcpy(hpsk->psk, psk->psk, PMK_LEN);
1612391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt		if (psk->p2p)
1613391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt			os_memcpy(hpsk->p2p_dev_addr, psk->addr, ETH_ALEN);
1614391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt		else
1615391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt			os_memcpy(hpsk->addr, psk->addr, ETH_ALEN);
1616391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt		hpsk->next = hapd->conf->ssid.wpa_psk;
1617391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt		hapd->conf->ssid.wpa_psk = hpsk;
1618391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt	}
1619391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt}
1620391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt
1621391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt
16226c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidtstatic void p2p_go_dump_common_freqs(struct wpa_supplicant *wpa_s)
16236c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt{
16246c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt	unsigned int i;
16256c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt
16266c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt	wpa_dbg(wpa_s, MSG_DEBUG, "P2P: Common group frequencies (len=%u):",
16276c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt		wpa_s->p2p_group_common_freqs_num);
16286c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt
16296c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt	for (i = 0; i < wpa_s->p2p_group_common_freqs_num; i++)
16306c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt		wpa_dbg(wpa_s, MSG_DEBUG, "freq[%u]: %d",
16316c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt			i, wpa_s->p2p_group_common_freqs[i]);
16326c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt}
16336c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt
16346c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt
16356c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidtstatic void p2p_go_save_group_common_freqs(struct wpa_supplicant *wpa_s,
16366c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt					   struct p2p_go_neg_results *params)
16376c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt{
16386c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt	unsigned int i, len = int_array_len(wpa_s->go_params->freq_list);
16396c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt
16406c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt	wpa_s->p2p_group_common_freqs_num = 0;
16416c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt	os_free(wpa_s->p2p_group_common_freqs);
16426c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt	wpa_s->p2p_group_common_freqs = os_calloc(len, sizeof(int));
16436c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt	if (!wpa_s->p2p_group_common_freqs)
16446c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt		return;
16456c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt
16466c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt	for (i = 0; i < len; i++) {
16476c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt		if (!wpa_s->go_params->freq_list[i])
16486c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt			break;
16496c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt		wpa_s->p2p_group_common_freqs[i] =
16506c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt			wpa_s->go_params->freq_list[i];
16516c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt	}
16526c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt	wpa_s->p2p_group_common_freqs_num = i;
16536c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt}
16546c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt
16556c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt
1656216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidtstatic void p2p_config_write(struct wpa_supplicant *wpa_s)
1657216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt{
1658216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt#ifndef CONFIG_NO_CONFIG_WRITE
1659216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt	if (wpa_s->parent->conf->update_config &&
1660216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt	    wpa_config_write(wpa_s->parent->confname, wpa_s->parent->conf))
1661216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt		wpa_printf(MSG_DEBUG, "P2P: Failed to update configuration");
1662216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt#endif /* CONFIG_NO_CONFIG_WRITE */
1663216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt}
1664216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt
1665216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt
16668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic void p2p_go_configured(void *ctx, void *data)
16678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{
16688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	struct wpa_supplicant *wpa_s = ctx;
16698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	struct p2p_go_neg_results *params = data;
16708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	struct wpa_ssid *ssid;
167175ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen	int network_id = -1;
16728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
16736c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt	p2p_go_save_group_common_freqs(wpa_s, params);
16746c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt	p2p_go_dump_common_freqs(wpa_s);
16756c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt
16768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	ssid = wpa_s->current_ssid;
16778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (ssid && ssid->mode == WPAS_MODE_P2P_GO) {
16788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		wpa_printf(MSG_DEBUG, "P2P: Group setup without provisioning");
16798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		if (wpa_s->global->p2p_group_formation == wpa_s)
16808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			wpa_s->global->p2p_group_formation = NULL;
16817f0b69e88015ca077ef7a417fde0a76c10df23a5Dmitry Shmidt		wpas_p2p_group_started(wpa_s, 1, ssid, ssid->frequency,
16827f0b69e88015ca077ef7a417fde0a76c10df23a5Dmitry Shmidt				       params->passphrase[0] == '\0' ?
16837f0b69e88015ca077ef7a417fde0a76c10df23a5Dmitry Shmidt				       params->psk : NULL,
16847f0b69e88015ca077ef7a417fde0a76c10df23a5Dmitry Shmidt				       params->passphrase,
16857f0b69e88015ca077ef7a417fde0a76c10df23a5Dmitry Shmidt				       wpa_s->global->p2p_dev_addr,
16867f0b69e88015ca077ef7a417fde0a76c10df23a5Dmitry Shmidt				       params->persistent_group, "");
16876c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt		wpa_s->group_formation_reported = 1;
16881f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt
1689216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt		if (wpa_s->parent->p2ps_join_addr_valid) {
1690216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt			wpa_dbg(wpa_s, MSG_DEBUG,
1691216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt				"P2PS: Setting default PIN for " MACSTR,
1692216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt				MAC2STR(wpa_s->parent->p2ps_join_addr));
1693216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt			wpa_supplicant_ap_wps_pin(wpa_s,
1694216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt						  wpa_s->parent->p2ps_join_addr,
1695216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt						  "12345670", NULL, 0, 0);
1696216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt			wpa_s->parent->p2ps_join_addr_valid = 0;
1697216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt		}
1698216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt
1699fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt		os_get_reltime(&wpa_s->global->p2p_go_wait_client);
1700391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt		if (params->persistent_group) {
170175ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen			network_id = wpas_p2p_store_persistent_group(
17028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt				wpa_s->parent, ssid,
1703497c1d5e50162d6b3c1cce5dbd9c5fd9da69aaefDmitry Shmidt				wpa_s->global->p2p_dev_addr);
1704391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt			wpas_p2p_add_psk_list(wpa_s, ssid);
1705391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt		}
170675ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen		if (network_id < 0)
170775ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen			network_id = ssid->id;
170875ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen		wpas_notify_p2p_group_started(wpa_s, ssid, network_id, 0);
17098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		wpas_p2p_cross_connect_setup(wpa_s);
17108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		wpas_p2p_set_group_idle_timeout(wpa_s);
17115605286c30e1701491bd3af974ae423727750eddDmitry Shmidt
17125605286c30e1701491bd3af974ae423727750eddDmitry Shmidt		if (wpa_s->p2p_first_connection_timeout) {
17135605286c30e1701491bd3af974ae423727750eddDmitry Shmidt			wpa_dbg(wpa_s, MSG_DEBUG,
17145605286c30e1701491bd3af974ae423727750eddDmitry Shmidt				"P2P: Start group formation timeout of %d seconds until first data connection on GO",
17155605286c30e1701491bd3af974ae423727750eddDmitry Shmidt				wpa_s->p2p_first_connection_timeout);
17165605286c30e1701491bd3af974ae423727750eddDmitry Shmidt			wpa_s->p2p_go_group_formation_completed = 0;
17175605286c30e1701491bd3af974ae423727750eddDmitry Shmidt			wpa_s->global->p2p_group_formation = wpa_s;
17185605286c30e1701491bd3af974ae423727750eddDmitry Shmidt			eloop_cancel_timeout(wpas_p2p_group_formation_timeout,
17195605286c30e1701491bd3af974ae423727750eddDmitry Shmidt					     wpa_s->parent, NULL);
17205605286c30e1701491bd3af974ae423727750eddDmitry Shmidt			eloop_register_timeout(
17215605286c30e1701491bd3af974ae423727750eddDmitry Shmidt				wpa_s->p2p_first_connection_timeout, 0,
17225605286c30e1701491bd3af974ae423727750eddDmitry Shmidt				wpas_p2p_group_formation_timeout,
17235605286c30e1701491bd3af974ae423727750eddDmitry Shmidt				wpa_s->parent, NULL);
17245605286c30e1701491bd3af974ae423727750eddDmitry Shmidt		}
17255605286c30e1701491bd3af974ae423727750eddDmitry Shmidt
17268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return;
17278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
17288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
17298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	wpa_printf(MSG_DEBUG, "P2P: Setting up WPS for GO provisioning");
17308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (wpa_supplicant_ap_mac_addr_filter(wpa_s,
17318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt					      params->peer_interface_addr)) {
17328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		wpa_printf(MSG_DEBUG, "P2P: Failed to setup MAC address "
17338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			   "filtering");
17348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return;
17358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
1736cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt	if (params->wps_method == WPS_PBC) {
17378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		wpa_supplicant_ap_wps_pbc(wpa_s, params->peer_interface_addr,
17381f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt					  params->peer_device_addr);
1739cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt#ifdef CONFIG_WPS_NFC
1740cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt	} else if (params->wps_method == WPS_NFC) {
1741cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt		if (wpa_s->parent->p2p_oob_dev_pw_id !=
1742cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt		    DEV_PW_NFC_CONNECTION_HANDOVER &&
1743cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt		    !wpa_s->parent->p2p_oob_dev_pw) {
1744cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt			wpa_printf(MSG_DEBUG, "P2P: No NFC Dev Pw known");
1745cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt			return;
1746cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt		}
1747cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt		wpas_ap_wps_add_nfc_pw(
1748cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt			wpa_s, wpa_s->parent->p2p_oob_dev_pw_id,
1749cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt			wpa_s->parent->p2p_oob_dev_pw,
1750cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt			wpa_s->parent->p2p_peer_oob_pk_hash_known ?
1751cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt			wpa_s->parent->p2p_peer_oob_pubkey_hash : NULL);
1752cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt#endif /* CONFIG_WPS_NFC */
1753cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt	} else if (wpa_s->p2p_pin[0])
17548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		wpa_supplicant_ap_wps_pin(wpa_s, params->peer_interface_addr,
1755d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt					  wpa_s->p2p_pin, NULL, 0, 0);
17568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	os_free(wpa_s->go_params);
17578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	wpa_s->go_params = NULL;
17588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt}
17598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
17608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
17618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic void wpas_start_wps_go(struct wpa_supplicant *wpa_s,
17628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			      struct p2p_go_neg_results *params,
17638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			      int group_formation)
17648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{
17658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	struct wpa_ssid *ssid;
17668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
1767aa532510a7b8c4da2d7d6e2c11dda5db840894e4Dmitry Shmidt	wpa_dbg(wpa_s, MSG_DEBUG, "P2P: Starting GO");
1768aa532510a7b8c4da2d7d6e2c11dda5db840894e4Dmitry Shmidt	if (wpas_copy_go_neg_results(wpa_s, params) < 0) {
1769aa532510a7b8c4da2d7d6e2c11dda5db840894e4Dmitry Shmidt		wpa_dbg(wpa_s, MSG_DEBUG, "P2P: Could not copy GO Negotiation "
1770aa532510a7b8c4da2d7d6e2c11dda5db840894e4Dmitry Shmidt			"results");
17718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return;
1772aa532510a7b8c4da2d7d6e2c11dda5db840894e4Dmitry Shmidt	}
17738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
17748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	ssid = wpa_config_add_network(wpa_s->conf);
1775aa532510a7b8c4da2d7d6e2c11dda5db840894e4Dmitry Shmidt	if (ssid == NULL) {
1776aa532510a7b8c4da2d7d6e2c11dda5db840894e4Dmitry Shmidt		wpa_dbg(wpa_s, MSG_DEBUG, "P2P: Could not add network for GO");
17778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return;
1778aa532510a7b8c4da2d7d6e2c11dda5db840894e4Dmitry Shmidt	}
17798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
17801f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt	wpa_s->show_group_started = 0;
17816c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt	wpa_s->p2p_go_group_formation_completed = 0;
17826c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt	wpa_s->group_formation_reported = 0;
17831f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt
17848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	wpa_config_set_network_defaults(ssid);
17858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	ssid->temporary = 1;
17868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	ssid->p2p_group = 1;
17878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	ssid->p2p_persistent_group = params->persistent_group;
17888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	ssid->mode = group_formation ? WPAS_MODE_P2P_GROUP_FORMATION :
17898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		WPAS_MODE_P2P_GO;
17908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	ssid->frequency = params->freq;
179161d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt	ssid->ht40 = params->ht40;
179268d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt	ssid->vht = params->vht;
17938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	ssid->ssid = os_zalloc(params->ssid_len + 1);
17948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (ssid->ssid) {
17958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		os_memcpy(ssid->ssid, params->ssid, params->ssid_len);
17968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		ssid->ssid_len = params->ssid_len;
17978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
17988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	ssid->auth_alg = WPA_AUTH_ALG_OPEN;
17998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	ssid->key_mgmt = WPA_KEY_MGMT_PSK;
18008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	ssid->proto = WPA_PROTO_RSN;
18018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	ssid->pairwise_cipher = WPA_CIPHER_CCMP;
18026c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt	ssid->group_cipher = WPA_CIPHER_CCMP;
18036c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt	if (params->freq > 56160) {
18046c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt		/*
18056c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt		 * Enable GCMP instead of CCMP as pairwise_cipher and
18066c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt		 * group_cipher in 60 GHz.
18076c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt		 */
18086c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt		ssid->pairwise_cipher = WPA_CIPHER_GCMP;
18096c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt		ssid->group_cipher = WPA_CIPHER_GCMP;
18106c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt	}
1811a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt	if (os_strlen(params->passphrase) > 0) {
1812a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt		ssid->passphrase = os_strdup(params->passphrase);
1813a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt		if (ssid->passphrase == NULL) {
1814b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt			wpa_msg_global(wpa_s, MSG_ERROR,
1815b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt				       "P2P: Failed to copy passphrase for GO");
1816a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt			wpa_config_remove_network(wpa_s->conf, ssid->id);
1817a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt			return;
1818a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt		}
1819a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt	} else
1820a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt		ssid->passphrase = NULL;
1821d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt	ssid->psk_set = params->psk_set;
1822d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt	if (ssid->psk_set)
1823d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt		os_memcpy(ssid->psk, params->psk, sizeof(ssid->psk));
1824a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt	else if (ssid->passphrase)
1825d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt		wpa_config_update_psk(ssid);
182661d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt	ssid->ap_max_inactivity = wpa_s->parent->conf->p2p_go_max_inactivity;
18278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
18288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	wpa_s->ap_configured_cb = p2p_go_configured;
18298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	wpa_s->ap_configured_cb_ctx = wpa_s;
18308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	wpa_s->ap_configured_cb_data = wpa_s->go_params;
18316dc03bd757d3befd2c03a543a402338db03914d6Dmitry Shmidt	wpa_s->scan_req = NORMAL_SCAN_REQ;
183275ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen	wpa_s->connect_without_scan = ssid;
18338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	wpa_s->reassociate = 1;
18348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	wpa_s->disconnected = 0;
1835aa532510a7b8c4da2d7d6e2c11dda5db840894e4Dmitry Shmidt	wpa_dbg(wpa_s, MSG_DEBUG, "P2P: Request scan (that will be skipped) to "
1836aa532510a7b8c4da2d7d6e2c11dda5db840894e4Dmitry Shmidt		"start GO)");
18378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	wpa_supplicant_req_scan(wpa_s, 0, 0);
18388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt}
18398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
18408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
18418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic void wpas_p2p_clone_config(struct wpa_supplicant *dst,
18428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt				  const struct wpa_supplicant *src)
18438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{
18448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	struct wpa_config *d;
18458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	const struct wpa_config *s;
18468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
18478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	d = dst->conf;
18488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	s = src->conf;
18498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
18508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#define C(n) if (s->n) d->n = os_strdup(s->n)
18518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	C(device_name);
18528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	C(manufacturer);
18538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	C(model_name);
18548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	C(model_number);
18558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	C(serial_number);
18568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	C(config_methods);
18578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#undef C
18588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
18598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	os_memcpy(d->device_type, s->device_type, WPS_DEV_TYPE_LEN);
18608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	os_memcpy(d->sec_device_type, s->sec_device_type,
18618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		  sizeof(d->sec_device_type));
18628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	d->num_sec_device_types = s->num_sec_device_types;
18638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
18648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	d->p2p_group_idle = s->p2p_group_idle;
18658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	d->p2p_intra_bss = s->p2p_intra_bss;
18661f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt	d->persistent_reconnect = s->persistent_reconnect;
186704949598a23f501be6eec21697465fd46a28840aDmitry Shmidt	d->max_num_sta = s->max_num_sta;
186804949598a23f501be6eec21697465fd46a28840aDmitry Shmidt	d->pbc_in_m1 = s->pbc_in_m1;
1869444d567b27731d8572ef37697dd12fd1c37c2f24Dmitry Shmidt	d->ignore_old_scan_res = s->ignore_old_scan_res;
187051b6ea882f234c14cd1fe1332a3840cf61fafccaDmitry Shmidt	d->beacon_int = s->beacon_int;
18711846323989242844f0e857458a8939fa5836429cDmitry Shmidt	d->dtim_period = s->dtim_period;
18727f65602d49069f96a7bb44da8bd79ffe8d4c6a98Dmitry Shmidt	d->p2p_go_ctwindow = s->p2p_go_ctwindow;
1873b7b4d0ec07161a6d76c40ba7ef1306e82fbb7e15Dmitry Shmidt	d->disassoc_low_ack = s->disassoc_low_ack;
18749657139ca0bbea9a84e0a3c7e9438d1f53c9ed24Dmitry Shmidt	d->disable_scan_offload = s->disable_scan_offload;
1875807291d85bf857320aff6a8ade38c5f622ab9df8Dmitry Shmidt	d->passive_scan = s->passive_scan;
1876cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt
1877cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt	if (s->wps_nfc_dh_privkey && s->wps_nfc_dh_pubkey) {
1878cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt		d->wps_nfc_dh_privkey = wpabuf_dup(s->wps_nfc_dh_privkey);
1879cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt		d->wps_nfc_dh_pubkey = wpabuf_dup(s->wps_nfc_dh_pubkey);
1880cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt	}
1881a3dc30964aa24aea2b518246f6812663a1103490Dmitry Shmidt	d->p2p_cli_probe = s->p2p_cli_probe;
18828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt}
18838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
18848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
188534af306c42b7ccf956508e7cd23f0ba90606e360Dmitry Shmidtstatic void wpas_p2p_get_group_ifname(struct wpa_supplicant *wpa_s,
188634af306c42b7ccf956508e7cd23f0ba90606e360Dmitry Shmidt				      char *ifname, size_t len)
188734af306c42b7ccf956508e7cd23f0ba90606e360Dmitry Shmidt{
188834af306c42b7ccf956508e7cd23f0ba90606e360Dmitry Shmidt	char *ifname_ptr = wpa_s->ifname;
188934af306c42b7ccf956508e7cd23f0ba90606e360Dmitry Shmidt
189034af306c42b7ccf956508e7cd23f0ba90606e360Dmitry Shmidt	if (os_strncmp(wpa_s->ifname, P2P_MGMT_DEVICE_PREFIX,
189134af306c42b7ccf956508e7cd23f0ba90606e360Dmitry Shmidt		       os_strlen(P2P_MGMT_DEVICE_PREFIX)) == 0) {
189234af306c42b7ccf956508e7cd23f0ba90606e360Dmitry Shmidt		ifname_ptr = os_strrchr(wpa_s->ifname, '-') + 1;
189334af306c42b7ccf956508e7cd23f0ba90606e360Dmitry Shmidt	}
189434af306c42b7ccf956508e7cd23f0ba90606e360Dmitry Shmidt
189534af306c42b7ccf956508e7cd23f0ba90606e360Dmitry Shmidt	os_snprintf(ifname, len, "p2p-%s-%d", ifname_ptr, wpa_s->p2p_group_idx);
189634af306c42b7ccf956508e7cd23f0ba90606e360Dmitry Shmidt	if (os_strlen(ifname) >= IFNAMSIZ &&
189734af306c42b7ccf956508e7cd23f0ba90606e360Dmitry Shmidt	    os_strlen(wpa_s->ifname) < IFNAMSIZ) {
18986c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt		int res;
18996c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt
190034af306c42b7ccf956508e7cd23f0ba90606e360Dmitry Shmidt		/* Try to avoid going over the IFNAMSIZ length limit */
19016c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt		res = os_snprintf(ifname, len, "p2p-%d", wpa_s->p2p_group_idx);
19026c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt		if (os_snprintf_error(len, res) && len)
19036c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt			ifname[len - 1] = '\0';
190434af306c42b7ccf956508e7cd23f0ba90606e360Dmitry Shmidt	}
190534af306c42b7ccf956508e7cd23f0ba90606e360Dmitry Shmidt}
190634af306c42b7ccf956508e7cd23f0ba90606e360Dmitry Shmidt
190734af306c42b7ccf956508e7cd23f0ba90606e360Dmitry Shmidt
19088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic int wpas_p2p_add_group_interface(struct wpa_supplicant *wpa_s,
19098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt					enum wpa_driver_if_type type)
19108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{
19118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	char ifname[120], force_ifname[120];
19128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
19138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (wpa_s->pending_interface_name[0]) {
19148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		wpa_printf(MSG_DEBUG, "P2P: Pending virtual interface exists "
19158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			   "- skip creation of a new one");
19168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		if (is_zero_ether_addr(wpa_s->pending_interface_addr)) {
19178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			wpa_printf(MSG_DEBUG, "P2P: Pending virtual address "
19188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt				   "unknown?! ifname='%s'",
19198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt				   wpa_s->pending_interface_name);
19208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			return -1;
19218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		}
19228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return 0;
19238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
19248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
192534af306c42b7ccf956508e7cd23f0ba90606e360Dmitry Shmidt	wpas_p2p_get_group_ifname(wpa_s, ifname, sizeof(ifname));
19268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	force_ifname[0] = '\0';
19278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
19288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	wpa_printf(MSG_DEBUG, "P2P: Create a new interface %s for the group",
19298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		   ifname);
19308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	wpa_s->p2p_group_idx++;
19318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
19328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	wpa_s->pending_interface_type = type;
19338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (wpa_drv_if_add(wpa_s, type, ifname, NULL, NULL, force_ifname,
19348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			   wpa_s->pending_interface_addr, NULL) < 0) {
19358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		wpa_printf(MSG_ERROR, "P2P: Failed to create new group "
19368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			   "interface");
19378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return -1;
19388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
19398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
19408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (force_ifname[0]) {
19418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		wpa_printf(MSG_DEBUG, "P2P: Driver forced interface name %s",
19428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			   force_ifname);
19438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		os_strlcpy(wpa_s->pending_interface_name, force_ifname,
19448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			   sizeof(wpa_s->pending_interface_name));
19458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	} else
19468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		os_strlcpy(wpa_s->pending_interface_name, ifname,
19478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			   sizeof(wpa_s->pending_interface_name));
19488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	wpa_printf(MSG_DEBUG, "P2P: Created pending virtual interface %s addr "
19498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		   MACSTR, wpa_s->pending_interface_name,
19508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		   MAC2STR(wpa_s->pending_interface_addr));
19518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
19528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	return 0;
19538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt}
19548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
19558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
19568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic void wpas_p2p_remove_pending_group_interface(
19578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	struct wpa_supplicant *wpa_s)
19588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{
19598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (!wpa_s->pending_interface_name[0] ||
19608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	    is_zero_ether_addr(wpa_s->pending_interface_addr))
19618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return; /* No pending virtual interface */
19628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
19638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	wpa_printf(MSG_DEBUG, "P2P: Removing pending group interface %s",
19648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		   wpa_s->pending_interface_name);
19658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	wpa_drv_if_remove(wpa_s, wpa_s->pending_interface_type,
19668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			  wpa_s->pending_interface_name);
19678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	os_memset(wpa_s->pending_interface_addr, 0, ETH_ALEN);
19688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	wpa_s->pending_interface_name[0] = '\0';
1969216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt	wpa_s->global->pending_group_iface_for_p2ps = 0;
19708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt}
19718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
19728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
19738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic struct wpa_supplicant *
19748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtwpas_p2p_init_group_interface(struct wpa_supplicant *wpa_s, int go)
19758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{
19768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	struct wpa_interface iface;
19778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	struct wpa_supplicant *group_wpa_s;
19788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
19798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (!wpa_s->pending_interface_name[0]) {
19808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		wpa_printf(MSG_ERROR, "P2P: No pending group interface");
19818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		if (!wpas_p2p_create_iface(wpa_s))
19828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			return NULL;
19838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		/*
19848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		 * Something has forced us to remove the pending interface; try
19858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		 * to create a new one and hope for the best that we will get
19868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		 * the same local address.
19878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		 */
19888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		if (wpas_p2p_add_group_interface(wpa_s, go ? WPA_IF_P2P_GO :
19898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt						 WPA_IF_P2P_CLIENT) < 0)
19908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			return NULL;
19918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
19928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
19938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	os_memset(&iface, 0, sizeof(iface));
19948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	iface.ifname = wpa_s->pending_interface_name;
19958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	iface.driver = wpa_s->driver->name;
199634af306c42b7ccf956508e7cd23f0ba90606e360Dmitry Shmidt	if (wpa_s->conf->ctrl_interface == NULL &&
199734af306c42b7ccf956508e7cd23f0ba90606e360Dmitry Shmidt	    wpa_s->parent != wpa_s &&
199834af306c42b7ccf956508e7cd23f0ba90606e360Dmitry Shmidt	    wpa_s->p2p_mgmt &&
199934af306c42b7ccf956508e7cd23f0ba90606e360Dmitry Shmidt	    (wpa_s->drv_flags & WPA_DRIVER_FLAGS_DEDICATED_P2P_DEVICE))
200034af306c42b7ccf956508e7cd23f0ba90606e360Dmitry Shmidt		iface.ctrl_interface = wpa_s->parent->conf->ctrl_interface;
200134af306c42b7ccf956508e7cd23f0ba90606e360Dmitry Shmidt	else
200234af306c42b7ccf956508e7cd23f0ba90606e360Dmitry Shmidt		iface.ctrl_interface = wpa_s->conf->ctrl_interface;
20038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	iface.driver_param = wpa_s->conf->driver_param;
2004203eadb9eda41a1dde4a583edb4684319e3f399eDmitry Shmidt	group_wpa_s = wpa_supplicant_add_iface(wpa_s->global, &iface, wpa_s);
20058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (group_wpa_s == NULL) {
20068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		wpa_printf(MSG_ERROR, "P2P: Failed to create new "
20078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			   "wpa_supplicant interface");
20088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return NULL;
20098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
20108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	wpa_s->pending_interface_name[0] = '\0';
20118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	group_wpa_s->p2p_group_interface = go ? P2P_GROUP_INTERFACE_GO :
20128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		P2P_GROUP_INTERFACE_CLIENT;
20138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	wpa_s->global->p2p_group_formation = group_wpa_s;
2014216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt	wpa_s->global->pending_group_iface_for_p2ps = 0;
20158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
20168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	wpas_p2p_clone_config(group_wpa_s, wpa_s);
20178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
20188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	return group_wpa_s;
20198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt}
20208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
20218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
20228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic void wpas_p2p_group_formation_timeout(void *eloop_ctx,
20238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt					     void *timeout_ctx)
20248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{
20258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	struct wpa_supplicant *wpa_s = eloop_ctx;
20268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	wpa_printf(MSG_DEBUG, "P2P: Group Formation timed out");
2027a3dc30964aa24aea2b518246f6812663a1103490Dmitry Shmidt	wpas_p2p_group_formation_failed(wpa_s, 0);
202834af306c42b7ccf956508e7cd23f0ba90606e360Dmitry Shmidt}
202934af306c42b7ccf956508e7cd23f0ba90606e360Dmitry Shmidt
203034af306c42b7ccf956508e7cd23f0ba90606e360Dmitry Shmidt
2031a3dc30964aa24aea2b518246f6812663a1103490Dmitry Shmidtstatic void wpas_p2p_group_formation_failed(struct wpa_supplicant *wpa_s,
2032a3dc30964aa24aea2b518246f6812663a1103490Dmitry Shmidt					    int already_deleted)
203334af306c42b7ccf956508e7cd23f0ba90606e360Dmitry Shmidt{
203434af306c42b7ccf956508e7cd23f0ba90606e360Dmitry Shmidt	eloop_cancel_timeout(wpas_p2p_group_formation_timeout,
203534af306c42b7ccf956508e7cd23f0ba90606e360Dmitry Shmidt			     wpa_s->parent, NULL);
20368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (wpa_s->global->p2p)
20378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		p2p_group_formation_failed(wpa_s->global->p2p);
2038a3dc30964aa24aea2b518246f6812663a1103490Dmitry Shmidt	wpas_group_formation_completed(wpa_s, 0, already_deleted);
20398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt}
20408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
20418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
2042fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidtstatic void wpas_p2p_grpform_fail_after_wps(struct wpa_supplicant *wpa_s)
2043fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt{
2044fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt	wpa_printf(MSG_DEBUG, "P2P: Reject group formation due to WPS provisioning failure");
2045fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt	eloop_cancel_timeout(wpas_p2p_group_formation_timeout,
2046fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt			     wpa_s->parent, NULL);
2047fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt	eloop_register_timeout(0, 0, wpas_p2p_group_formation_timeout,
2048fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt			       wpa_s->parent, NULL);
2049fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt	wpa_s->global->p2p_fail_on_wps_complete = 0;
2050fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt}
2051fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt
2052fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt
2053391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidtvoid wpas_p2p_ap_setup_failed(struct wpa_supplicant *wpa_s)
2054391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt{
2055391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt	if (wpa_s->global->p2p_group_formation != wpa_s)
2056391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt		return;
2057391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt	/* Speed up group formation timeout since this cannot succeed */
2058391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt	eloop_cancel_timeout(wpas_p2p_group_formation_timeout,
2059391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt			     wpa_s->parent, NULL);
2060391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt	eloop_register_timeout(0, 0, wpas_p2p_group_formation_timeout,
2061391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt			       wpa_s->parent, NULL);
2062391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt}
2063391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt
2064391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt
2065fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidtstatic void wpas_go_neg_completed(void *ctx, struct p2p_go_neg_results *res)
20668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{
20678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	struct wpa_supplicant *wpa_s = ctx;
20688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
20698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (wpa_s->off_channel_freq || wpa_s->roc_waiting_drv_freq) {
20708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		wpa_drv_cancel_remain_on_channel(wpa_s);
20718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		wpa_s->off_channel_freq = 0;
20728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		wpa_s->roc_waiting_drv_freq = 0;
20738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
20748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
20758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (res->status) {
2076b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt		wpa_msg_global(wpa_s, MSG_INFO,
2077b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt			       P2P_EVENT_GO_NEG_FAILURE "status=%d",
2078b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt			       res->status);
20791f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt		wpas_notify_p2p_go_neg_completed(wpa_s, res);
20808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		wpas_p2p_remove_pending_group_interface(wpa_s);
20818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return;
20828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
20838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
208461d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt	if (wpa_s->p2p_go_ht40)
208561d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt		res->ht40 = 1;
208668d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt	if (wpa_s->p2p_go_vht)
208768d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt		res->vht = 1;
208861d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt
2089b7b4d0ec07161a6d76c40ba7ef1306e82fbb7e15Dmitry Shmidt	wpa_msg_global(wpa_s, MSG_INFO, P2P_EVENT_GO_NEG_SUCCESS "role=%s "
2090b7b4d0ec07161a6d76c40ba7ef1306e82fbb7e15Dmitry Shmidt		       "freq=%d ht40=%d peer_dev=" MACSTR " peer_iface=" MACSTR
2091b7b4d0ec07161a6d76c40ba7ef1306e82fbb7e15Dmitry Shmidt		       " wps_method=%s",
2092b7b4d0ec07161a6d76c40ba7ef1306e82fbb7e15Dmitry Shmidt		       res->role_go ? "GO" : "client", res->freq, res->ht40,
2093b7b4d0ec07161a6d76c40ba7ef1306e82fbb7e15Dmitry Shmidt		       MAC2STR(res->peer_device_addr),
2094b7b4d0ec07161a6d76c40ba7ef1306e82fbb7e15Dmitry Shmidt		       MAC2STR(res->peer_interface_addr),
2095b7b4d0ec07161a6d76c40ba7ef1306e82fbb7e15Dmitry Shmidt		       p2p_wps_method_text(res->wps_method));
20961f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt	wpas_notify_p2p_go_neg_completed(wpa_s, res);
20978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
209804949598a23f501be6eec21697465fd46a28840aDmitry Shmidt	if (res->role_go && wpa_s->p2p_persistent_id >= 0) {
209904949598a23f501be6eec21697465fd46a28840aDmitry Shmidt		struct wpa_ssid *ssid;
210004949598a23f501be6eec21697465fd46a28840aDmitry Shmidt		ssid = wpa_config_get_network(wpa_s->conf,
210104949598a23f501be6eec21697465fd46a28840aDmitry Shmidt					      wpa_s->p2p_persistent_id);
210204949598a23f501be6eec21697465fd46a28840aDmitry Shmidt		if (ssid && ssid->disabled == 2 &&
210304949598a23f501be6eec21697465fd46a28840aDmitry Shmidt		    ssid->mode == WPAS_MODE_P2P_GO && ssid->passphrase) {
210404949598a23f501be6eec21697465fd46a28840aDmitry Shmidt			size_t len = os_strlen(ssid->passphrase);
210504949598a23f501be6eec21697465fd46a28840aDmitry Shmidt			wpa_printf(MSG_DEBUG, "P2P: Override passphrase based "
210604949598a23f501be6eec21697465fd46a28840aDmitry Shmidt				   "on requested persistent group");
210704949598a23f501be6eec21697465fd46a28840aDmitry Shmidt			os_memcpy(res->passphrase, ssid->passphrase, len);
210804949598a23f501be6eec21697465fd46a28840aDmitry Shmidt			res->passphrase[len] = '\0';
210904949598a23f501be6eec21697465fd46a28840aDmitry Shmidt		}
211004949598a23f501be6eec21697465fd46a28840aDmitry Shmidt	}
211104949598a23f501be6eec21697465fd46a28840aDmitry Shmidt
21128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (wpa_s->create_p2p_iface) {
21138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		struct wpa_supplicant *group_wpa_s =
21148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			wpas_p2p_init_group_interface(wpa_s, res->role_go);
21158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		if (group_wpa_s == NULL) {
21168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			wpas_p2p_remove_pending_group_interface(wpa_s);
2117d11f019d62a42a8fc4c4d1f2ec17cf35b0763153Dmitry Shmidt			eloop_cancel_timeout(wpas_p2p_long_listen_timeout,
2118d11f019d62a42a8fc4c4d1f2ec17cf35b0763153Dmitry Shmidt					     wpa_s, NULL);
2119a3dc30964aa24aea2b518246f6812663a1103490Dmitry Shmidt			wpas_p2p_group_formation_failed(wpa_s, 1);
21208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			return;
21218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		}
21228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		if (group_wpa_s != wpa_s) {
21238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			os_memcpy(group_wpa_s->p2p_pin, wpa_s->p2p_pin,
21248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt				  sizeof(group_wpa_s->p2p_pin));
21258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			group_wpa_s->p2p_wps_method = wpa_s->p2p_wps_method;
21268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		}
21278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		os_memset(wpa_s->pending_interface_addr, 0, ETH_ALEN);
21288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		wpa_s->pending_interface_name[0] = '\0';
21298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		group_wpa_s->p2p_in_provisioning = 1;
21308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
21318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		if (res->role_go)
21328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			wpas_start_wps_go(group_wpa_s, res, 1);
21338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		else
21348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			wpas_start_wps_enrollee(group_wpa_s, res);
21358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	} else {
21368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		wpa_s->p2p_in_provisioning = 1;
21378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		wpa_s->global->p2p_group_formation = wpa_s;
21388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
21398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		if (res->role_go)
21408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			wpas_start_wps_go(wpa_s, res, 1);
21418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		else
21428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			wpas_start_wps_enrollee(ctx, res);
21438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
21448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
21458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	wpa_s->p2p_long_listen = 0;
21468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	eloop_cancel_timeout(wpas_p2p_long_listen_timeout, wpa_s, NULL);
21478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
21488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	eloop_cancel_timeout(wpas_p2p_group_formation_timeout, wpa_s, NULL);
21498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	eloop_register_timeout(15 + res->peer_config_timeout / 100,
21508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			       (res->peer_config_timeout % 100) * 10000,
21518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			       wpas_p2p_group_formation_timeout, wpa_s, NULL);
21528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt}
21538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
21548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
21557a53dbb56693ee9f55c0cab1a8297436511e8613Dmitry Shmidtstatic void wpas_go_neg_req_rx(void *ctx, const u8 *src, u16 dev_passwd_id,
21567a53dbb56693ee9f55c0cab1a8297436511e8613Dmitry Shmidt			       u8 go_intent)
21578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{
21588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	struct wpa_supplicant *wpa_s = ctx;
2159b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt	wpa_msg_global(wpa_s, MSG_INFO, P2P_EVENT_GO_NEG_REQUEST MACSTR
21607a53dbb56693ee9f55c0cab1a8297436511e8613Dmitry Shmidt		       " dev_passwd_id=%u go_intent=%u", MAC2STR(src),
21617a53dbb56693ee9f55c0cab1a8297436511e8613Dmitry Shmidt		       dev_passwd_id, go_intent);
21628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
21637a53dbb56693ee9f55c0cab1a8297436511e8613Dmitry Shmidt	wpas_notify_p2p_go_neg_req(wpa_s, src, dev_passwd_id, go_intent);
21648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt}
21658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
21668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
2167fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidtstatic void wpas_dev_found(void *ctx, const u8 *addr,
2168fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt			   const struct p2p_peer_info *info,
2169fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt			   int new_device)
21708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{
21711f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt#ifndef CONFIG_NO_STDOUT_DEBUG
21728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	struct wpa_supplicant *wpa_s = ctx;
21738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	char devtype[WPS_DEV_TYPE_BUFSIZE];
217404f534e89ed127da4077485376f24debc50d80d5Dmitry Shmidt	char *wfd_dev_info_hex = NULL;
217504f534e89ed127da4077485376f24debc50d80d5Dmitry Shmidt
21768367dc909f536f600c7474582fe0a96bef7c78fcIrfan Sheriff#ifdef CONFIG_WIFI_DISPLAY
217704f534e89ed127da4077485376f24debc50d80d5Dmitry Shmidt	wfd_dev_info_hex = wifi_display_subelem_hex(info->wfd_subelems,
217804f534e89ed127da4077485376f24debc50d80d5Dmitry Shmidt						    WFD_SUBELEM_DEVICE_INFO);
21798367dc909f536f600c7474582fe0a96bef7c78fcIrfan Sheriff#endif /* CONFIG_WIFI_DISPLAY */
218004f534e89ed127da4077485376f24debc50d80d5Dmitry Shmidt
2181216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt	if (info->p2ps_instance) {
2182216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt		char str[256];
2183216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt		const u8 *buf = wpabuf_head(info->p2ps_instance);
2184216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt		size_t len = wpabuf_len(info->p2ps_instance);
2185216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt
2186216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt		while (len) {
2187216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt			u32 id;
2188216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt			u16 methods;
2189216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt			u8 str_len;
2190216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt
2191216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt			if (len < 4 + 2 + 1)
2192216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt				break;
2193216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt			id = WPA_GET_LE32(buf);
2194216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt			buf += sizeof(u32);
2195216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt			methods = WPA_GET_BE16(buf);
2196216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt			buf += sizeof(u16);
2197216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt			str_len = *buf++;
2198216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt			if (str_len > len - 4 - 2 - 1)
2199216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt				break;
2200216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt			os_memcpy(str, buf, str_len);
2201216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt			str[str_len] = '\0';
2202216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt			buf += str_len;
2203216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt			len -= str_len + sizeof(u32) + sizeof(u16) + sizeof(u8);
2204216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt
2205216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt			wpa_msg_global(wpa_s, MSG_INFO,
2206216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt				       P2P_EVENT_DEVICE_FOUND MACSTR
2207216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt				       " p2p_dev_addr=" MACSTR
2208216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt				       " pri_dev_type=%s name='%s'"
2209216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt				       " config_methods=0x%x"
2210216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt				       " dev_capab=0x%x"
2211216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt				       " group_capab=0x%x"
2212216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt				       " adv_id=%x asp_svc=%s%s",
2213216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt				       MAC2STR(addr),
2214216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt				       MAC2STR(info->p2p_device_addr),
2215216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt				       wps_dev_type_bin2str(
2216216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt					       info->pri_dev_type,
2217216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt					       devtype, sizeof(devtype)),
2218216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt				       info->device_name, methods,
2219216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt				       info->dev_capab, info->group_capab,
2220216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt				       id, str,
2221216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt				       info->vendor_elems ?
2222216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt				       " vendor_elems=1" : "");
2223216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt		}
2224216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt		goto done;
2225216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt	}
2226216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt
2227b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt	wpa_msg_global(wpa_s, MSG_INFO, P2P_EVENT_DEVICE_FOUND MACSTR
2228b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt		       " p2p_dev_addr=" MACSTR
2229b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt		       " pri_dev_type=%s name='%s' config_methods=0x%x "
22306c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt		       "dev_capab=0x%x group_capab=0x%x%s%s%s new=%d",
2231b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt		       MAC2STR(addr), MAC2STR(info->p2p_device_addr),
2232b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt		       wps_dev_type_bin2str(info->pri_dev_type, devtype,
2233b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt					    sizeof(devtype)),
2234b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt		       info->device_name, info->config_methods,
2235b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt		       info->dev_capab, info->group_capab,
223604f534e89ed127da4077485376f24debc50d80d5Dmitry Shmidt		       wfd_dev_info_hex ? " wfd_dev_info=0x" : "",
22372e67f06149ff649fb6f8782bad041d3d9124685eDmitry Shmidt		       wfd_dev_info_hex ? wfd_dev_info_hex : "",
22386c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt		       info->vendor_elems ? " vendor_elems=1" : "",
22396c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt		       new_device);
22408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
2241216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidtdone:
224204f534e89ed127da4077485376f24debc50d80d5Dmitry Shmidt	os_free(wfd_dev_info_hex);
22439767226d8e6a1adaa33beb9f517ef40dddfa460cDmitry Shmidt#endif /* CONFIG_NO_STDOUT_DEBUG */
224404f534e89ed127da4077485376f24debc50d80d5Dmitry Shmidt
22458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	wpas_notify_p2p_device_found(ctx, info->p2p_device_addr, new_device);
22468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt}
22478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
22488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
22498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic void wpas_dev_lost(void *ctx, const u8 *dev_addr)
22508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{
22518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	struct wpa_supplicant *wpa_s = ctx;
22521f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt
2253b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt	wpa_msg_global(wpa_s, MSG_INFO, P2P_EVENT_DEVICE_LOST
2254b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt		       "p2p_dev_addr=" MACSTR, MAC2STR(dev_addr));
22551f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt
22568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	wpas_notify_p2p_device_lost(wpa_s, dev_addr);
22578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt}
22588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
22598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
2260b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidtstatic void wpas_find_stopped(void *ctx)
2261b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt{
2262b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt	struct wpa_supplicant *wpa_s = ctx;
2263b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt	wpa_msg_global(wpa_s, MSG_INFO, P2P_EVENT_FIND_STOPPED);
22648bd70b7d6ba220544ee2f0e201e5df23e277fa1dDmitry Shmidt	wpas_notify_p2p_find_stopped(wpa_s);
2265b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt}
2266b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt
2267b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt
2268fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidtstruct wpas_p2p_listen_work {
2269fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt	unsigned int freq;
2270fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt	unsigned int duration;
2271fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt	struct wpabuf *probe_resp_ie;
2272fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt};
2273fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt
2274fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt
2275fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidtstatic void wpas_p2p_listen_work_free(struct wpas_p2p_listen_work *lwork)
22768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{
2277fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt	if (lwork == NULL)
2278fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt		return;
2279fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt	wpabuf_free(lwork->probe_resp_ie);
2280fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt	os_free(lwork);
2281fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt}
2282fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt
2283fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt
2284fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidtstatic void wpas_p2p_listen_work_done(struct wpa_supplicant *wpa_s)
2285fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt{
2286fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt	struct wpas_p2p_listen_work *lwork;
2287fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt
2288fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt	if (!wpa_s->p2p_listen_work)
2289fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt		return;
2290fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt
2291fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt	lwork = wpa_s->p2p_listen_work->ctx;
2292fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt	wpas_p2p_listen_work_free(lwork);
2293fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt	radio_work_done(wpa_s->p2p_listen_work);
2294fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt	wpa_s->p2p_listen_work = NULL;
2295fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt}
2296fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt
22978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
2298fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidtstatic void wpas_start_listen_cb(struct wpa_radio_work *work, int deinit)
2299fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt{
2300fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt	struct wpa_supplicant *wpa_s = work->wpa_s;
2301fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt	struct wpas_p2p_listen_work *lwork = work->ctx;
23026c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt	unsigned int duration;
2303fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt
2304fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt	if (deinit) {
2305bd14a57187b024f49f5b9ace55ef457d8d04650aDmitry Shmidt		if (work->started) {
2306bd14a57187b024f49f5b9ace55ef457d8d04650aDmitry Shmidt			wpa_s->p2p_listen_work = NULL;
2307bd14a57187b024f49f5b9ace55ef457d8d04650aDmitry Shmidt			wpas_stop_listen(wpa_s);
2308bd14a57187b024f49f5b9ace55ef457d8d04650aDmitry Shmidt		}
2309fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt		wpas_p2p_listen_work_free(lwork);
2310fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt		return;
2311fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt	}
2312fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt
2313fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt	wpa_s->p2p_listen_work = work;
2314fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt
2315fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt	wpa_drv_set_ap_wps_ie(wpa_s, NULL, lwork->probe_resp_ie, NULL);
23168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
23178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (wpa_drv_probe_req_report(wpa_s, 1) < 0) {
23188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		wpa_printf(MSG_DEBUG, "P2P: Failed to request the driver to "
23198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			   "report received Probe Request frames");
2320fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt		wpas_p2p_listen_work_done(wpa_s);
2321fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt		return;
23228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
23238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
2324fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt	wpa_s->pending_listen_freq = lwork->freq;
2325fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt	wpa_s->pending_listen_duration = lwork->duration;
23268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
23276c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt	duration = lwork->duration;
23286c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt#ifdef CONFIG_TESTING_OPTIONS
23296c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt	if (wpa_s->extra_roc_dur) {
23306c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt		wpa_printf(MSG_DEBUG, "TESTING: Increase ROC duration %u -> %u",
23316c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt			   duration, duration + wpa_s->extra_roc_dur);
23326c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt		duration += wpa_s->extra_roc_dur;
23336c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt	}
23346c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt#endif /* CONFIG_TESTING_OPTIONS */
23356c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt
23366c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt	if (wpa_drv_remain_on_channel(wpa_s, lwork->freq, duration) < 0) {
23378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		wpa_printf(MSG_DEBUG, "P2P: Failed to request the driver "
23388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			   "to remain on channel (%u MHz) for Listen "
2339fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt			   "state", lwork->freq);
2340fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt		wpas_p2p_listen_work_done(wpa_s);
23418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		wpa_s->pending_listen_freq = 0;
2342fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt		return;
23438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
23448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	wpa_s->off_channel_freq = 0;
2345fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt	wpa_s->roc_waiting_drv_freq = lwork->freq;
2346fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt}
2347fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt
2348fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt
2349fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidtstatic int wpas_start_listen(void *ctx, unsigned int freq,
2350fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt			     unsigned int duration,
2351fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt			     const struct wpabuf *probe_resp_ie)
2352fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt{
2353fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt	struct wpa_supplicant *wpa_s = ctx;
2354fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt	struct wpas_p2p_listen_work *lwork;
2355fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt
2356fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt	if (wpa_s->p2p_listen_work) {
2357fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt		wpa_printf(MSG_DEBUG, "P2P: Reject start_listen since p2p_listen_work already exists");
2358fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt		return -1;
2359fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt	}
2360fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt
2361fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt	lwork = os_zalloc(sizeof(*lwork));
2362fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt	if (lwork == NULL)
2363fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt		return -1;
2364fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt	lwork->freq = freq;
2365fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt	lwork->duration = duration;
2366fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt	if (probe_resp_ie) {
2367fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt		lwork->probe_resp_ie = wpabuf_dup(probe_resp_ie);
2368fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt		if (lwork->probe_resp_ie == NULL) {
2369fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt			wpas_p2p_listen_work_free(lwork);
2370fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt			return -1;
2371fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt		}
2372fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt	}
2373fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt
2374fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt	if (radio_add_work(wpa_s, freq, "p2p-listen", 0, wpas_start_listen_cb,
2375fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt			   lwork) < 0) {
2376fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt		wpas_p2p_listen_work_free(lwork);
2377fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt		return -1;
2378fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt	}
23798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
23808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	return 0;
23818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt}
23828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
23838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
23848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic void wpas_stop_listen(void *ctx)
23858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{
23868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	struct wpa_supplicant *wpa_s = ctx;
23878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (wpa_s->off_channel_freq || wpa_s->roc_waiting_drv_freq) {
23888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		wpa_drv_cancel_remain_on_channel(wpa_s);
23898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		wpa_s->off_channel_freq = 0;
23908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		wpa_s->roc_waiting_drv_freq = 0;
23918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
23928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	wpa_drv_set_ap_wps_ie(wpa_s, NULL, NULL, NULL);
2393a3dc30964aa24aea2b518246f6812663a1103490Dmitry Shmidt
2394a3dc30964aa24aea2b518246f6812663a1103490Dmitry Shmidt	/*
2395a3dc30964aa24aea2b518246f6812663a1103490Dmitry Shmidt	 * Don't cancel Probe Request RX reporting for a connected P2P Client
2396a3dc30964aa24aea2b518246f6812663a1103490Dmitry Shmidt	 * handling Probe Request frames.
2397a3dc30964aa24aea2b518246f6812663a1103490Dmitry Shmidt	 */
2398a3dc30964aa24aea2b518246f6812663a1103490Dmitry Shmidt	if (!wpa_s->p2p_cli_probe)
2399a3dc30964aa24aea2b518246f6812663a1103490Dmitry Shmidt		wpa_drv_probe_req_report(wpa_s, 0);
2400a3dc30964aa24aea2b518246f6812663a1103490Dmitry Shmidt
2401fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt	wpas_p2p_listen_work_done(wpa_s);
24028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt}
24038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
24048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
2405a3dc30964aa24aea2b518246f6812663a1103490Dmitry Shmidtstatic int wpas_send_probe_resp(void *ctx, const struct wpabuf *buf,
2406a3dc30964aa24aea2b518246f6812663a1103490Dmitry Shmidt				unsigned int freq)
24078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{
24088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	struct wpa_supplicant *wpa_s = ctx;
2409a3dc30964aa24aea2b518246f6812663a1103490Dmitry Shmidt	return wpa_drv_send_mlme(wpa_s, wpabuf_head(buf), wpabuf_len(buf), 1,
2410a3dc30964aa24aea2b518246f6812663a1103490Dmitry Shmidt				 freq);
24118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt}
24128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
24138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
24148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic void wpas_prov_disc_local_display(struct wpa_supplicant *wpa_s,
24158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt					 const u8 *peer, const char *params,
24168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt					 unsigned int generated_pin)
24178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{
2418b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt	wpa_msg_global(wpa_s, MSG_INFO, P2P_EVENT_PROV_DISC_SHOW_PIN MACSTR
2419b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt		       " %08d%s", MAC2STR(peer), generated_pin, params);
24208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt}
24218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
24228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
24238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic void wpas_prov_disc_local_keypad(struct wpa_supplicant *wpa_s,
24248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt					const u8 *peer, const char *params)
24258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{
2426b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt	wpa_msg_global(wpa_s, MSG_INFO, P2P_EVENT_PROV_DISC_ENTER_PIN MACSTR
2427b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt		       "%s", MAC2STR(peer), params);
24288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt}
24298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
24308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
2431fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidtstatic void wpas_prov_disc_req(void *ctx, const u8 *peer, u16 config_methods,
2432fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt			       const u8 *dev_addr, const u8 *pri_dev_type,
2433fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt			       const char *dev_name, u16 supp_config_methods,
2434fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt			       u8 dev_capab, u8 group_capab, const u8 *group_id,
2435fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt			       size_t group_id_len)
24368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{
24378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	struct wpa_supplicant *wpa_s = ctx;
24388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	char devtype[WPS_DEV_TYPE_BUFSIZE];
24391f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt	char params[300];
24408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	u8 empty_dev_type[8];
24418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	unsigned int generated_pin = 0;
24421f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt	struct wpa_supplicant *group = NULL;
24436c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt	int res;
24441f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt
24451f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt	if (group_id) {
24461f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt		for (group = wpa_s->global->ifaces; group; group = group->next)
24471f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt		{
24481f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt			struct wpa_ssid *s = group->current_ssid;
24491f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt			if (s != NULL &&
24501f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt			    s->mode == WPAS_MODE_P2P_GO &&
24511f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt			    group_id_len - ETH_ALEN == s->ssid_len &&
24521f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt			    os_memcmp(group_id + ETH_ALEN, s->ssid,
24531f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt				      s->ssid_len) == 0)
24541f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt				break;
24551f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt		}
24561f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt	}
24578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
24588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (pri_dev_type == NULL) {
24598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		os_memset(empty_dev_type, 0, sizeof(empty_dev_type));
24608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		pri_dev_type = empty_dev_type;
24618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
24626c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt	res = os_snprintf(params, sizeof(params), " p2p_dev_addr=" MACSTR
24636c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt			  " pri_dev_type=%s name='%s' config_methods=0x%x "
24646c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt			  "dev_capab=0x%x group_capab=0x%x%s%s",
24656c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt			  MAC2STR(dev_addr),
24666c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt			  wps_dev_type_bin2str(pri_dev_type, devtype,
24676c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt					       sizeof(devtype)),
24686c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt			  dev_name, supp_config_methods, dev_capab, group_capab,
24696c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt			  group ? " group=" : "",
24706c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt			  group ? group->ifname : "");
24716c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt	if (os_snprintf_error(sizeof(params), res))
24726c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt		wpa_printf(MSG_DEBUG, "P2P: PD Request event truncated");
24738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	params[sizeof(params) - 1] = '\0';
2474c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt
24758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (config_methods & WPS_CONFIG_DISPLAY) {
24768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		generated_pin = wps_generate_pin();
24778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		wpas_prov_disc_local_display(wpa_s, peer, params,
24788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt					     generated_pin);
24798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	} else if (config_methods & WPS_CONFIG_KEYPAD)
24808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		wpas_prov_disc_local_keypad(wpa_s, peer, params);
24818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	else if (config_methods & WPS_CONFIG_PUSHBUTTON)
2482b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt		wpa_msg_global(wpa_s, MSG_INFO, P2P_EVENT_PROV_DISC_PBC_REQ
2483b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt			       MACSTR "%s", MAC2STR(peer), params);
248475ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen
248575ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen	wpas_notify_p2p_provision_discovery(wpa_s, peer, 1 /* request */,
248675ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen					    P2P_PROV_DISC_SUCCESS,
248775ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen					    config_methods, generated_pin);
24888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt}
24898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
24908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
2491fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidtstatic void wpas_prov_disc_resp(void *ctx, const u8 *peer, u16 config_methods)
24928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{
24938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	struct wpa_supplicant *wpa_s = ctx;
24948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	unsigned int generated_pin = 0;
249504949598a23f501be6eec21697465fd46a28840aDmitry Shmidt	char params[20];
24968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
2497c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt	if (wpa_s->pending_pd_before_join &&
2498c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt	    (os_memcmp(peer, wpa_s->pending_join_dev_addr, ETH_ALEN) == 0 ||
2499c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt	     os_memcmp(peer, wpa_s->pending_join_iface_addr, ETH_ALEN) == 0)) {
2500c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt		wpa_s->pending_pd_before_join = 0;
2501c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt		wpa_printf(MSG_DEBUG, "P2P: Starting pending "
2502c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt			   "join-existing-group operation");
2503cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt		wpas_p2p_join_start(wpa_s, 0, NULL, 0);
2504c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt		return;
2505c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt	}
2506c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt
250704949598a23f501be6eec21697465fd46a28840aDmitry Shmidt	if (wpa_s->pending_pd_use == AUTO_PD_JOIN ||
25086c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt	    wpa_s->pending_pd_use == AUTO_PD_GO_NEG) {
25096c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt		int res;
25106c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt
25116c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt		res = os_snprintf(params, sizeof(params), " peer_go=%d",
25126c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt				  wpa_s->pending_pd_use == AUTO_PD_JOIN);
25136c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt		if (os_snprintf_error(sizeof(params), res))
25146c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt			params[sizeof(params) - 1] = '\0';
25156c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt	} else
251604949598a23f501be6eec21697465fd46a28840aDmitry Shmidt		params[0] = '\0';
251704949598a23f501be6eec21697465fd46a28840aDmitry Shmidt
25188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (config_methods & WPS_CONFIG_DISPLAY)
251904949598a23f501be6eec21697465fd46a28840aDmitry Shmidt		wpas_prov_disc_local_keypad(wpa_s, peer, params);
25208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	else if (config_methods & WPS_CONFIG_KEYPAD) {
25218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		generated_pin = wps_generate_pin();
252204949598a23f501be6eec21697465fd46a28840aDmitry Shmidt		wpas_prov_disc_local_display(wpa_s, peer, params,
252304949598a23f501be6eec21697465fd46a28840aDmitry Shmidt					     generated_pin);
25248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	} else if (config_methods & WPS_CONFIG_PUSHBUTTON)
2525b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt		wpa_msg_global(wpa_s, MSG_INFO, P2P_EVENT_PROV_DISC_PBC_RESP
2526b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt			       MACSTR "%s", MAC2STR(peer), params);
25278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
252875ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen	wpas_notify_p2p_provision_discovery(wpa_s, peer, 0 /* response */,
252975ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen					    P2P_PROV_DISC_SUCCESS,
253075ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen					    config_methods, generated_pin);
25318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt}
25328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
25338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
25341f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidtstatic void wpas_prov_disc_fail(void *ctx, const u8 *peer,
2535216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt				enum p2p_prov_disc_status status,
2536216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt				u32 adv_id, const u8 *adv_mac,
2537216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt				const char *deferred_session_resp)
253875ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen{
253975ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen	struct wpa_supplicant *wpa_s = ctx;
254075ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen
254104949598a23f501be6eec21697465fd46a28840aDmitry Shmidt	if (wpa_s->p2p_fallback_to_go_neg) {
254204949598a23f501be6eec21697465fd46a28840aDmitry Shmidt		wpa_dbg(wpa_s, MSG_DEBUG, "P2P: PD for p2p_connect-auto "
254304949598a23f501be6eec21697465fd46a28840aDmitry Shmidt			"failed - fall back to GO Negotiation");
25447f65602d49069f96a7bb44da8bd79ffe8d4c6a98Dmitry Shmidt		wpa_msg_global(wpa_s->parent, MSG_INFO,
25457f65602d49069f96a7bb44da8bd79ffe8d4c6a98Dmitry Shmidt			       P2P_EVENT_FALLBACK_TO_GO_NEG
25467f65602d49069f96a7bb44da8bd79ffe8d4c6a98Dmitry Shmidt			       "reason=PD-failed");
254704949598a23f501be6eec21697465fd46a28840aDmitry Shmidt		wpas_p2p_fallback_to_go_neg(wpa_s, 0);
254804949598a23f501be6eec21697465fd46a28840aDmitry Shmidt		return;
254904949598a23f501be6eec21697465fd46a28840aDmitry Shmidt	}
255004949598a23f501be6eec21697465fd46a28840aDmitry Shmidt
2551d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt	if (status == P2P_PROV_DISC_TIMEOUT_JOIN) {
25522b380488c6b5d21e54e98397c7a8d6a9f16dd8b5Dmitry Shmidt		wpa_s->pending_pd_before_join = 0;
2553d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt		wpa_printf(MSG_DEBUG, "P2P: Starting pending "
2554d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt			   "join-existing-group operation (no ACK for PD "
2555d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt			   "Req attempts)");
2556cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt		wpas_p2p_join_start(wpa_s, 0, NULL, 0);
2557d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt		return;
25582b380488c6b5d21e54e98397c7a8d6a9f16dd8b5Dmitry Shmidt	}
2559d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt
2560216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt	if (adv_id && adv_mac && deferred_session_resp) {
2561216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt		wpa_msg_global(wpa_s, MSG_INFO, P2P_EVENT_PROV_DISC_FAILURE
2562216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt			       " p2p_dev_addr=" MACSTR " status=%d adv_id=%x"
2563216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt			       " deferred_session_resp='%s'",
2564216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt			       MAC2STR(peer), status, adv_id,
2565216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt			       deferred_session_resp);
2566216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt	} else if (adv_id && adv_mac) {
2567216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt		wpa_msg_global(wpa_s, MSG_INFO, P2P_EVENT_PROV_DISC_FAILURE
2568216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt			       " p2p_dev_addr=" MACSTR " status=%d adv_id=%x",
2569216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt			       MAC2STR(peer), status, adv_id);
2570216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt	} else {
2571216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt		wpa_msg_global(wpa_s, MSG_INFO, P2P_EVENT_PROV_DISC_FAILURE
2572216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt			       " p2p_dev_addr=" MACSTR " status=%d",
2573216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt			       MAC2STR(peer), status);
2574216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt	}
257504949598a23f501be6eec21697465fd46a28840aDmitry Shmidt
257675ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen	wpas_notify_p2p_provision_discovery(wpa_s, peer, 0 /* response */,
257775ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen					    status, 0, 0);
257875ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen}
257975ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen
258075ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen
2581f7e0a9905988e62e4f70fed8b795722abeab719bDmitry Shmidtstatic int freq_included(const struct p2p_channels *channels, unsigned int freq)
2582f7e0a9905988e62e4f70fed8b795722abeab719bDmitry Shmidt{
2583f7e0a9905988e62e4f70fed8b795722abeab719bDmitry Shmidt	if (channels == NULL)
2584f7e0a9905988e62e4f70fed8b795722abeab719bDmitry Shmidt		return 1; /* Assume no restrictions */
2585f7e0a9905988e62e4f70fed8b795722abeab719bDmitry Shmidt	return p2p_channels_includes_freq(channels, freq);
2586f7e0a9905988e62e4f70fed8b795722abeab719bDmitry Shmidt
2587f7e0a9905988e62e4f70fed8b795722abeab719bDmitry Shmidt}
2588f7e0a9905988e62e4f70fed8b795722abeab719bDmitry Shmidt
2589f7e0a9905988e62e4f70fed8b795722abeab719bDmitry Shmidt
259043cb578dfe2c492257636f6234a24178ed27789eDmitry Shmidt/**
259143cb578dfe2c492257636f6234a24178ed27789eDmitry Shmidt * Pick the best frequency to use from all the currently used frequencies.
259243cb578dfe2c492257636f6234a24178ed27789eDmitry Shmidt */
259343cb578dfe2c492257636f6234a24178ed27789eDmitry Shmidtstatic int wpas_p2p_pick_best_used_freq(struct wpa_supplicant *wpa_s,
259443cb578dfe2c492257636f6234a24178ed27789eDmitry Shmidt					struct wpa_used_freq_data *freqs,
259543cb578dfe2c492257636f6234a24178ed27789eDmitry Shmidt					unsigned int num)
259643cb578dfe2c492257636f6234a24178ed27789eDmitry Shmidt{
259743cb578dfe2c492257636f6234a24178ed27789eDmitry Shmidt	unsigned int i, c;
259843cb578dfe2c492257636f6234a24178ed27789eDmitry Shmidt
259943cb578dfe2c492257636f6234a24178ed27789eDmitry Shmidt	/* find a candidate freq that is supported by P2P */
260043cb578dfe2c492257636f6234a24178ed27789eDmitry Shmidt	for (c = 0; c < num; c++)
260143cb578dfe2c492257636f6234a24178ed27789eDmitry Shmidt		if (p2p_supported_freq(wpa_s->global->p2p, freqs[c].freq))
260243cb578dfe2c492257636f6234a24178ed27789eDmitry Shmidt			break;
260343cb578dfe2c492257636f6234a24178ed27789eDmitry Shmidt
260443cb578dfe2c492257636f6234a24178ed27789eDmitry Shmidt	if (c == num)
260543cb578dfe2c492257636f6234a24178ed27789eDmitry Shmidt		return 0;
260643cb578dfe2c492257636f6234a24178ed27789eDmitry Shmidt
260743cb578dfe2c492257636f6234a24178ed27789eDmitry Shmidt	/* once we have a candidate, try to find a 'better' one */
260843cb578dfe2c492257636f6234a24178ed27789eDmitry Shmidt	for (i = c + 1; i < num; i++) {
260943cb578dfe2c492257636f6234a24178ed27789eDmitry Shmidt		if (!p2p_supported_freq(wpa_s->global->p2p, freqs[i].freq))
261043cb578dfe2c492257636f6234a24178ed27789eDmitry Shmidt			continue;
261143cb578dfe2c492257636f6234a24178ed27789eDmitry Shmidt
261243cb578dfe2c492257636f6234a24178ed27789eDmitry Shmidt		/*
261343cb578dfe2c492257636f6234a24178ed27789eDmitry Shmidt		 * 1. Infrastructure station interfaces have higher preference.
261443cb578dfe2c492257636f6234a24178ed27789eDmitry Shmidt		 * 2. P2P Clients have higher preference.
261543cb578dfe2c492257636f6234a24178ed27789eDmitry Shmidt		 * 3. All others.
261643cb578dfe2c492257636f6234a24178ed27789eDmitry Shmidt		 */
261743cb578dfe2c492257636f6234a24178ed27789eDmitry Shmidt		if (freqs[i].flags & WPA_FREQ_USED_BY_INFRA_STATION) {
261843cb578dfe2c492257636f6234a24178ed27789eDmitry Shmidt			c = i;
261943cb578dfe2c492257636f6234a24178ed27789eDmitry Shmidt			break;
262043cb578dfe2c492257636f6234a24178ed27789eDmitry Shmidt		}
262143cb578dfe2c492257636f6234a24178ed27789eDmitry Shmidt
262243cb578dfe2c492257636f6234a24178ed27789eDmitry Shmidt		if ((freqs[i].flags & WPA_FREQ_USED_BY_P2P_CLIENT))
262343cb578dfe2c492257636f6234a24178ed27789eDmitry Shmidt			c = i;
262443cb578dfe2c492257636f6234a24178ed27789eDmitry Shmidt	}
262543cb578dfe2c492257636f6234a24178ed27789eDmitry Shmidt	return freqs[c].freq;
262643cb578dfe2c492257636f6234a24178ed27789eDmitry Shmidt}
262743cb578dfe2c492257636f6234a24178ed27789eDmitry Shmidt
262843cb578dfe2c492257636f6234a24178ed27789eDmitry Shmidt
26298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic u8 wpas_invitation_process(void *ctx, const u8 *sa, const u8 *bssid,
26308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt				  const u8 *go_dev_addr, const u8 *ssid,
26318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt				  size_t ssid_len, int *go, u8 *group_bssid,
2632f7e0a9905988e62e4f70fed8b795722abeab719bDmitry Shmidt				  int *force_freq, int persistent_group,
2633cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt				  const struct p2p_channels *channels,
2634cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt				  int dev_pw_id)
26358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{
26368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	struct wpa_supplicant *wpa_s = ctx;
26378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	struct wpa_ssid *s;
263843cb578dfe2c492257636f6234a24178ed27789eDmitry Shmidt	struct wpa_used_freq_data *freqs;
26398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	struct wpa_supplicant *grp;
264043cb578dfe2c492257636f6234a24178ed27789eDmitry Shmidt	int best_freq;
26418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
26428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (!persistent_group) {
26438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		wpa_printf(MSG_DEBUG, "P2P: Invitation from " MACSTR
2644344abd362cfe2d03ed956666527352826b67bde5Dmitry Shmidt			   " to join an active group (SSID: %s)",
2645344abd362cfe2d03ed956666527352826b67bde5Dmitry Shmidt			   MAC2STR(sa), wpa_ssid_txt(ssid, ssid_len));
26468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		if (!is_zero_ether_addr(wpa_s->p2p_auth_invite) &&
26478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		    (os_memcmp(go_dev_addr, wpa_s->p2p_auth_invite, ETH_ALEN)
26488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		     == 0 ||
26498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		     os_memcmp(sa, wpa_s->p2p_auth_invite, ETH_ALEN) == 0)) {
26508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			wpa_printf(MSG_DEBUG, "P2P: Accept previously "
26518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt				   "authorized invitation");
26528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			goto accept_inv;
26538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		}
2654cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt
2655cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt#ifdef CONFIG_WPS_NFC
26562f74e36e84064ffa32f82f3decf36b653c7e4fadDmitry Shmidt		if (dev_pw_id >= 0 && wpa_s->p2p_nfc_tag_enabled &&
26572f74e36e84064ffa32f82f3decf36b653c7e4fadDmitry Shmidt		    dev_pw_id == wpa_s->p2p_oob_dev_pw_id) {
2658cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt			wpa_printf(MSG_DEBUG, "P2P: Accept invitation based on local enabled NFC Tag");
26592f74e36e84064ffa32f82f3decf36b653c7e4fadDmitry Shmidt			wpa_s->p2p_wps_method = WPS_NFC;
26602f74e36e84064ffa32f82f3decf36b653c7e4fadDmitry Shmidt			wpa_s->pending_join_wps_method = WPS_NFC;
26612f74e36e84064ffa32f82f3decf36b653c7e4fadDmitry Shmidt			os_memcpy(wpa_s->pending_join_dev_addr,
2662cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt				  go_dev_addr, ETH_ALEN);
26632f74e36e84064ffa32f82f3decf36b653c7e4fadDmitry Shmidt			os_memcpy(wpa_s->pending_join_iface_addr,
2664cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt				  bssid, ETH_ALEN);
2665cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt			goto accept_inv;
2666cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt		}
2667cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt#endif /* CONFIG_WPS_NFC */
2668cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt
26698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		/*
26708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		 * Do not accept the invitation automatically; notify user and
26718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		 * request approval.
26728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		 */
26738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return P2P_SC_FAIL_INFO_CURRENTLY_UNAVAILABLE;
26748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
26758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
26768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	grp = wpas_get_p2p_group(wpa_s, ssid, ssid_len, go);
26778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (grp) {
26788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		wpa_printf(MSG_DEBUG, "P2P: Accept invitation to already "
26798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			   "running persistent group");
26808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		if (*go)
26818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			os_memcpy(group_bssid, grp->own_addr, ETH_ALEN);
26828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		goto accept_inv;
26838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
26848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
26857a5e50a0554bee77a9da492ea3d86f46147f1671Dmitry Shmidt	if (!is_zero_ether_addr(wpa_s->p2p_auth_invite) &&
26867a5e50a0554bee77a9da492ea3d86f46147f1671Dmitry Shmidt	    os_memcmp(sa, wpa_s->p2p_auth_invite, ETH_ALEN) == 0) {
26877a5e50a0554bee77a9da492ea3d86f46147f1671Dmitry Shmidt		wpa_printf(MSG_DEBUG, "P2P: Accept previously initiated "
26887a5e50a0554bee77a9da492ea3d86f46147f1671Dmitry Shmidt			   "invitation to re-invoke a persistent group");
268976cd2cc44b62e858f1897ce58f4ce7d0174e8839Dmitry Shmidt		os_memset(wpa_s->p2p_auth_invite, 0, ETH_ALEN);
26907a5e50a0554bee77a9da492ea3d86f46147f1671Dmitry Shmidt	} else if (!wpa_s->conf->persistent_reconnect)
26918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return P2P_SC_FAIL_INFO_CURRENTLY_UNAVAILABLE;
26928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
26938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	for (s = wpa_s->conf->ssid; s; s = s->next) {
26948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		if (s->disabled == 2 &&
26958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		    os_memcmp(s->bssid, go_dev_addr, ETH_ALEN) == 0 &&
26968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		    s->ssid_len == ssid_len &&
26978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		    os_memcmp(ssid, s->ssid, ssid_len) == 0)
26988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			break;
26998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
27008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
27018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (!s) {
27028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		wpa_printf(MSG_DEBUG, "P2P: Invitation from " MACSTR
27038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			   " requested reinvocation of an unknown group",
27048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			   MAC2STR(sa));
27058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return P2P_SC_FAIL_UNKNOWN_GROUP;
27068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
27078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
27088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (s->mode == WPAS_MODE_P2P_GO && !wpas_p2p_create_iface(wpa_s)) {
27098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		*go = 1;
27108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		if (wpa_s->wpa_state >= WPA_AUTHENTICATING) {
27118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			wpa_printf(MSG_DEBUG, "P2P: The only available "
27128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt				   "interface is already in use - reject "
27138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt				   "invitation");
27148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			return P2P_SC_FAIL_UNABLE_TO_ACCOMMODATE;
27158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		}
27168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		os_memcpy(group_bssid, wpa_s->own_addr, ETH_ALEN);
27178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	} else if (s->mode == WPAS_MODE_P2P_GO) {
27188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		*go = 1;
27198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		if (wpas_p2p_add_group_interface(wpa_s, WPA_IF_P2P_GO) < 0)
27208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		{
27218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			wpa_printf(MSG_ERROR, "P2P: Failed to allocate a new "
27228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt				   "interface address for the group");
27238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			return P2P_SC_FAIL_UNABLE_TO_ACCOMMODATE;
27248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		}
27258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		os_memcpy(group_bssid, wpa_s->pending_interface_addr,
27268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			  ETH_ALEN);
27278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
27288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
27298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtaccept_inv:
2730700a137ab366edc72e371da68ba187b4717ee660Dmitry Shmidt	wpas_p2p_set_own_freq_preference(wpa_s, 0);
2731700a137ab366edc72e371da68ba187b4717ee660Dmitry Shmidt
273243cb578dfe2c492257636f6234a24178ed27789eDmitry Shmidt	best_freq = 0;
273343cb578dfe2c492257636f6234a24178ed27789eDmitry Shmidt	freqs = os_calloc(wpa_s->num_multichan_concurrent,
273443cb578dfe2c492257636f6234a24178ed27789eDmitry Shmidt			  sizeof(struct wpa_used_freq_data));
273543cb578dfe2c492257636f6234a24178ed27789eDmitry Shmidt	if (freqs) {
273643cb578dfe2c492257636f6234a24178ed27789eDmitry Shmidt		int num_channels = wpa_s->num_multichan_concurrent;
273743cb578dfe2c492257636f6234a24178ed27789eDmitry Shmidt		int num = wpas_p2p_valid_oper_freqs(wpa_s, freqs, num_channels);
273843cb578dfe2c492257636f6234a24178ed27789eDmitry Shmidt		best_freq = wpas_p2p_pick_best_used_freq(wpa_s, freqs, num);
273943cb578dfe2c492257636f6234a24178ed27789eDmitry Shmidt		os_free(freqs);
274043cb578dfe2c492257636f6234a24178ed27789eDmitry Shmidt	}
274143cb578dfe2c492257636f6234a24178ed27789eDmitry Shmidt
2742c2ebb4b85d69b65f552fee71ac68f44e8d87b39eDmitry Shmidt	/* Get one of the frequencies currently in use */
274343cb578dfe2c492257636f6234a24178ed27789eDmitry Shmidt	if (best_freq > 0) {
2744a0d265f81180f341d22511538fa18166e1bbce9fDmitry Shmidt		wpa_printf(MSG_DEBUG, "P2P: Trying to prefer a channel already used by one of the interfaces");
274543cb578dfe2c492257636f6234a24178ed27789eDmitry Shmidt		wpas_p2p_set_own_freq_preference(wpa_s, best_freq);
2746a0d265f81180f341d22511538fa18166e1bbce9fDmitry Shmidt
2747a0d265f81180f341d22511538fa18166e1bbce9fDmitry Shmidt		if (wpa_s->num_multichan_concurrent < 2 ||
2748a0d265f81180f341d22511538fa18166e1bbce9fDmitry Shmidt		    wpas_p2p_num_unused_channels(wpa_s) < 1) {
2749a0d265f81180f341d22511538fa18166e1bbce9fDmitry Shmidt			wpa_printf(MSG_DEBUG, "P2P: No extra channels available - trying to force channel to match a channel already used by one of the interfaces");
275043cb578dfe2c492257636f6234a24178ed27789eDmitry Shmidt			*force_freq = best_freq;
2751a0d265f81180f341d22511538fa18166e1bbce9fDmitry Shmidt		}
27528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
27538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
2754c2ebb4b85d69b65f552fee71ac68f44e8d87b39eDmitry Shmidt	if (*force_freq > 0 && wpa_s->num_multichan_concurrent > 1 &&
2755c2ebb4b85d69b65f552fee71ac68f44e8d87b39eDmitry Shmidt	    wpas_p2p_num_unused_channels(wpa_s) > 0) {
2756f7e0a9905988e62e4f70fed8b795722abeab719bDmitry Shmidt		if (*go == 0) {
2757f7e0a9905988e62e4f70fed8b795722abeab719bDmitry Shmidt			/* We are the client */
2758f7e0a9905988e62e4f70fed8b795722abeab719bDmitry Shmidt			wpa_printf(MSG_DEBUG, "P2P: Peer was found to be "
2759f7e0a9905988e62e4f70fed8b795722abeab719bDmitry Shmidt				   "running a GO but we are capable of MCC, "
2760f7e0a9905988e62e4f70fed8b795722abeab719bDmitry Shmidt				   "figure out the best channel to use");
2761f7e0a9905988e62e4f70fed8b795722abeab719bDmitry Shmidt			*force_freq = 0;
2762f7e0a9905988e62e4f70fed8b795722abeab719bDmitry Shmidt		} else if (!freq_included(channels, *force_freq)) {
2763f7e0a9905988e62e4f70fed8b795722abeab719bDmitry Shmidt			/* We are the GO, and *force_freq is not in the
2764f7e0a9905988e62e4f70fed8b795722abeab719bDmitry Shmidt			 * intersection */
2765f7e0a9905988e62e4f70fed8b795722abeab719bDmitry Shmidt			wpa_printf(MSG_DEBUG, "P2P: Forced GO freq %d MHz not "
2766f7e0a9905988e62e4f70fed8b795722abeab719bDmitry Shmidt				   "in intersection but we are capable of MCC, "
2767f7e0a9905988e62e4f70fed8b795722abeab719bDmitry Shmidt				   "figure out the best channel to use",
2768f7e0a9905988e62e4f70fed8b795722abeab719bDmitry Shmidt				   *force_freq);
2769f7e0a9905988e62e4f70fed8b795722abeab719bDmitry Shmidt			*force_freq = 0;
2770f7e0a9905988e62e4f70fed8b795722abeab719bDmitry Shmidt		}
2771f7e0a9905988e62e4f70fed8b795722abeab719bDmitry Shmidt	}
2772f7e0a9905988e62e4f70fed8b795722abeab719bDmitry Shmidt
27738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	return P2P_SC_SUCCESS;
27748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt}
27758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
27768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
27778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic void wpas_invitation_received(void *ctx, const u8 *sa, const u8 *bssid,
27788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt				     const u8 *ssid, size_t ssid_len,
27798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt				     const u8 *go_dev_addr, u8 status,
27808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt				     int op_freq)
27818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{
27828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	struct wpa_supplicant *wpa_s = ctx;
27838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	struct wpa_ssid *s;
27848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
27858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	for (s = wpa_s->conf->ssid; s; s = s->next) {
27868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		if (s->disabled == 2 &&
27878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		    s->ssid_len == ssid_len &&
27888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		    os_memcmp(ssid, s->ssid, ssid_len) == 0)
27898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			break;
27908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
27918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
27928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (status == P2P_SC_SUCCESS) {
27938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		wpa_printf(MSG_DEBUG, "P2P: Invitation from peer " MACSTR
2794344abd362cfe2d03ed956666527352826b67bde5Dmitry Shmidt			   " was accepted; op_freq=%d MHz, SSID=%s",
2795344abd362cfe2d03ed956666527352826b67bde5Dmitry Shmidt			   MAC2STR(sa), op_freq, wpa_ssid_txt(ssid, ssid_len));
27968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		if (s) {
279791c40cdce17424d9a4718876becf0b7811cf68f2Dmitry Shmidt			int go = s->mode == WPAS_MODE_P2P_GO;
27988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			wpas_p2p_group_add_persistent(
279915907098d1f67c24bb000e593e279af173cf57d7Dmitry Shmidt				wpa_s, s, go, 0, op_freq, 0, 0, NULL,
28005605286c30e1701491bd3af974ae423727750eddDmitry Shmidt				go ? P2P_MAX_INITIAL_CONN_WAIT_GO_REINVOKE : 0);
28018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		} else if (bssid) {
2802d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt			wpa_s->user_initiated_pd = 0;
28038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			wpas_p2p_join(wpa_s, bssid, go_dev_addr,
2804cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt				      wpa_s->p2p_wps_method, 0, op_freq,
2805344abd362cfe2d03ed956666527352826b67bde5Dmitry Shmidt				      ssid, ssid_len);
28068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		}
28078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return;
28088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
28098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
28108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (status != P2P_SC_FAIL_INFO_CURRENTLY_UNAVAILABLE) {
28118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		wpa_printf(MSG_DEBUG, "P2P: Invitation from peer " MACSTR
28128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			   " was rejected (status %u)", MAC2STR(sa), status);
28138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return;
28148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
28158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
28168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (!s) {
28178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		if (bssid) {
2818b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt			wpa_msg_global(wpa_s, MSG_INFO,
2819b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt				       P2P_EVENT_INVITATION_RECEIVED
2820b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt				       "sa=" MACSTR " go_dev_addr=" MACSTR
2821b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt				       " bssid=" MACSTR " unknown-network",
2822b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt				       MAC2STR(sa), MAC2STR(go_dev_addr),
2823b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt				       MAC2STR(bssid));
28248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		} else {
2825b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt			wpa_msg_global(wpa_s, MSG_INFO,
2826b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt				       P2P_EVENT_INVITATION_RECEIVED
2827b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt				       "sa=" MACSTR " go_dev_addr=" MACSTR
2828b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt				       " unknown-network",
2829b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt				       MAC2STR(sa), MAC2STR(go_dev_addr));
28308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		}
28318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return;
28328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
28338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
28347a5e50a0554bee77a9da492ea3d86f46147f1671Dmitry Shmidt	if (s->mode == WPAS_MODE_P2P_GO && op_freq) {
2835b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt		wpa_msg_global(wpa_s, MSG_INFO, P2P_EVENT_INVITATION_RECEIVED
2836b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt			       "sa=" MACSTR " persistent=%d freq=%d",
2837b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt			       MAC2STR(sa), s->id, op_freq);
28387a5e50a0554bee77a9da492ea3d86f46147f1671Dmitry Shmidt	} else {
2839b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt		wpa_msg_global(wpa_s, MSG_INFO, P2P_EVENT_INVITATION_RECEIVED
2840b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt			       "sa=" MACSTR " persistent=%d",
2841b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt			       MAC2STR(sa), s->id);
28427a5e50a0554bee77a9da492ea3d86f46147f1671Dmitry Shmidt	}
28438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt}
28448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
28458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
2846700a137ab366edc72e371da68ba187b4717ee660Dmitry Shmidtstatic void wpas_remove_persistent_peer(struct wpa_supplicant *wpa_s,
2847700a137ab366edc72e371da68ba187b4717ee660Dmitry Shmidt					struct wpa_ssid *ssid,
2848391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt					const u8 *peer, int inv)
2849700a137ab366edc72e371da68ba187b4717ee660Dmitry Shmidt{
2850700a137ab366edc72e371da68ba187b4717ee660Dmitry Shmidt	size_t i;
28518bd70b7d6ba220544ee2f0e201e5df23e277fa1dDmitry Shmidt	struct wpa_supplicant *p2p_wpa_s = wpa_s->global->p2p_init_wpa_s;
2852700a137ab366edc72e371da68ba187b4717ee660Dmitry Shmidt
2853700a137ab366edc72e371da68ba187b4717ee660Dmitry Shmidt	if (ssid == NULL)
2854700a137ab366edc72e371da68ba187b4717ee660Dmitry Shmidt		return;
2855700a137ab366edc72e371da68ba187b4717ee660Dmitry Shmidt
2856700a137ab366edc72e371da68ba187b4717ee660Dmitry Shmidt	for (i = 0; ssid->p2p_client_list && i < ssid->num_p2p_clients; i++) {
2857ff787d557db719adea0fdf2679667500c65cf74dDmitry Shmidt		if (os_memcmp(ssid->p2p_client_list + i * 2 * ETH_ALEN, peer,
2858700a137ab366edc72e371da68ba187b4717ee660Dmitry Shmidt			      ETH_ALEN) == 0)
2859700a137ab366edc72e371da68ba187b4717ee660Dmitry Shmidt			break;
2860700a137ab366edc72e371da68ba187b4717ee660Dmitry Shmidt	}
28616aa8ae4b6139bdf5593301474277dcdbc2528190Dmitry Shmidt	if (i >= ssid->num_p2p_clients || !ssid->p2p_client_list) {
2862700a137ab366edc72e371da68ba187b4717ee660Dmitry Shmidt		if (ssid->mode != WPAS_MODE_P2P_GO &&
2863700a137ab366edc72e371da68ba187b4717ee660Dmitry Shmidt		    os_memcmp(ssid->bssid, peer, ETH_ALEN) == 0) {
2864700a137ab366edc72e371da68ba187b4717ee660Dmitry Shmidt			wpa_printf(MSG_DEBUG, "P2P: Remove persistent group %d "
2865700a137ab366edc72e371da68ba187b4717ee660Dmitry Shmidt				   "due to invitation result", ssid->id);
2866700a137ab366edc72e371da68ba187b4717ee660Dmitry Shmidt			wpas_notify_network_removed(wpa_s, ssid);
2867700a137ab366edc72e371da68ba187b4717ee660Dmitry Shmidt			wpa_config_remove_network(wpa_s->conf, ssid->id);
2868700a137ab366edc72e371da68ba187b4717ee660Dmitry Shmidt			return;
2869700a137ab366edc72e371da68ba187b4717ee660Dmitry Shmidt		}
2870700a137ab366edc72e371da68ba187b4717ee660Dmitry Shmidt		return; /* Peer not found in client list */
2871700a137ab366edc72e371da68ba187b4717ee660Dmitry Shmidt	}
2872700a137ab366edc72e371da68ba187b4717ee660Dmitry Shmidt
2873700a137ab366edc72e371da68ba187b4717ee660Dmitry Shmidt	wpa_printf(MSG_DEBUG, "P2P: Remove peer " MACSTR " from persistent "
2874391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt		   "group %d client list%s",
2875391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt		   MAC2STR(peer), ssid->id,
2876391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt		   inv ? " due to invitation result" : "");
2877ff787d557db719adea0fdf2679667500c65cf74dDmitry Shmidt	os_memmove(ssid->p2p_client_list + i * 2 * ETH_ALEN,
2878ff787d557db719adea0fdf2679667500c65cf74dDmitry Shmidt		   ssid->p2p_client_list + (i + 1) * 2 * ETH_ALEN,
2879ff787d557db719adea0fdf2679667500c65cf74dDmitry Shmidt		   (ssid->num_p2p_clients - i - 1) * 2 * ETH_ALEN);
2880700a137ab366edc72e371da68ba187b4717ee660Dmitry Shmidt	ssid->num_p2p_clients--;
28818bd70b7d6ba220544ee2f0e201e5df23e277fa1dDmitry Shmidt	if (p2p_wpa_s->conf->update_config &&
28828bd70b7d6ba220544ee2f0e201e5df23e277fa1dDmitry Shmidt	    wpa_config_write(p2p_wpa_s->confname, p2p_wpa_s->conf))
2883700a137ab366edc72e371da68ba187b4717ee660Dmitry Shmidt		wpa_printf(MSG_DEBUG, "P2P: Failed to update configuration");
2884700a137ab366edc72e371da68ba187b4717ee660Dmitry Shmidt}
2885700a137ab366edc72e371da68ba187b4717ee660Dmitry Shmidt
2886700a137ab366edc72e371da68ba187b4717ee660Dmitry Shmidt
2887700a137ab366edc72e371da68ba187b4717ee660Dmitry Shmidtstatic void wpas_remove_persistent_client(struct wpa_supplicant *wpa_s,
2888700a137ab366edc72e371da68ba187b4717ee660Dmitry Shmidt					  const u8 *peer)
2889700a137ab366edc72e371da68ba187b4717ee660Dmitry Shmidt{
2890700a137ab366edc72e371da68ba187b4717ee660Dmitry Shmidt	struct wpa_ssid *ssid;
2891700a137ab366edc72e371da68ba187b4717ee660Dmitry Shmidt
2892700a137ab366edc72e371da68ba187b4717ee660Dmitry Shmidt	wpa_s = wpa_s->global->p2p_invite_group;
2893700a137ab366edc72e371da68ba187b4717ee660Dmitry Shmidt	if (wpa_s == NULL)
2894700a137ab366edc72e371da68ba187b4717ee660Dmitry Shmidt		return; /* No known invitation group */
2895700a137ab366edc72e371da68ba187b4717ee660Dmitry Shmidt	ssid = wpa_s->current_ssid;
2896700a137ab366edc72e371da68ba187b4717ee660Dmitry Shmidt	if (ssid == NULL || ssid->mode != WPAS_MODE_P2P_GO ||
2897700a137ab366edc72e371da68ba187b4717ee660Dmitry Shmidt	    !ssid->p2p_persistent_group)
2898700a137ab366edc72e371da68ba187b4717ee660Dmitry Shmidt		return; /* Not operating as a GO in persistent group */
2899700a137ab366edc72e371da68ba187b4717ee660Dmitry Shmidt	ssid = wpas_p2p_get_persistent(wpa_s->parent, peer,
2900700a137ab366edc72e371da68ba187b4717ee660Dmitry Shmidt				       ssid->ssid, ssid->ssid_len);
2901391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt	wpas_remove_persistent_peer(wpa_s, ssid, peer, 1);
2902700a137ab366edc72e371da68ba187b4717ee660Dmitry Shmidt}
2903700a137ab366edc72e371da68ba187b4717ee660Dmitry Shmidt
2904700a137ab366edc72e371da68ba187b4717ee660Dmitry Shmidt
29057a5e50a0554bee77a9da492ea3d86f46147f1671Dmitry Shmidtstatic void wpas_invitation_result(void *ctx, int status, const u8 *bssid,
2906700a137ab366edc72e371da68ba187b4717ee660Dmitry Shmidt				   const struct p2p_channels *channels,
290715907098d1f67c24bb000e593e279af173cf57d7Dmitry Shmidt				   const u8 *peer, int neg_freq,
290815907098d1f67c24bb000e593e279af173cf57d7Dmitry Shmidt				   int peer_oper_freq)
29098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{
29108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	struct wpa_supplicant *wpa_s = ctx;
29118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	struct wpa_ssid *ssid;
291215907098d1f67c24bb000e593e279af173cf57d7Dmitry Shmidt	int freq;
29138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
29148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (bssid) {
2915b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt		wpa_msg_global(wpa_s, MSG_INFO, P2P_EVENT_INVITATION_RESULT
2916b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt			       "status=%d " MACSTR,
2917b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt			       status, MAC2STR(bssid));
29188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	} else {
2919b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt		wpa_msg_global(wpa_s, MSG_INFO, P2P_EVENT_INVITATION_RESULT
2920b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt			       "status=%d ", status);
29218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
29228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	wpas_notify_p2p_invitation_result(wpa_s, status, bssid);
29238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
2924700a137ab366edc72e371da68ba187b4717ee660Dmitry Shmidt	wpa_printf(MSG_DEBUG, "P2P: Invitation result - status=%d peer=" MACSTR,
2925700a137ab366edc72e371da68ba187b4717ee660Dmitry Shmidt		   status, MAC2STR(peer));
2926700a137ab366edc72e371da68ba187b4717ee660Dmitry Shmidt	if (wpa_s->pending_invite_ssid_id == -1) {
2927700a137ab366edc72e371da68ba187b4717ee660Dmitry Shmidt		if (status == P2P_SC_FAIL_UNKNOWN_GROUP)
2928700a137ab366edc72e371da68ba187b4717ee660Dmitry Shmidt			wpas_remove_persistent_client(wpa_s, peer);
29298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return; /* Invitation to active group */
2930700a137ab366edc72e371da68ba187b4717ee660Dmitry Shmidt	}
29318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
29327a5e50a0554bee77a9da492ea3d86f46147f1671Dmitry Shmidt	if (status == P2P_SC_FAIL_INFO_CURRENTLY_UNAVAILABLE) {
29337a5e50a0554bee77a9da492ea3d86f46147f1671Dmitry Shmidt		wpa_printf(MSG_DEBUG, "P2P: Waiting for peer to start another "
29347a5e50a0554bee77a9da492ea3d86f46147f1671Dmitry Shmidt			   "invitation exchange to indicate readiness for "
29357a5e50a0554bee77a9da492ea3d86f46147f1671Dmitry Shmidt			   "re-invocation");
29367a5e50a0554bee77a9da492ea3d86f46147f1671Dmitry Shmidt	}
29377a5e50a0554bee77a9da492ea3d86f46147f1671Dmitry Shmidt
29388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (status != P2P_SC_SUCCESS) {
2939700a137ab366edc72e371da68ba187b4717ee660Dmitry Shmidt		if (status == P2P_SC_FAIL_UNKNOWN_GROUP) {
2940700a137ab366edc72e371da68ba187b4717ee660Dmitry Shmidt			ssid = wpa_config_get_network(
2941700a137ab366edc72e371da68ba187b4717ee660Dmitry Shmidt				wpa_s->conf, wpa_s->pending_invite_ssid_id);
2942391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt			wpas_remove_persistent_peer(wpa_s, ssid, peer, 1);
2943700a137ab366edc72e371da68ba187b4717ee660Dmitry Shmidt		}
29448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		wpas_p2p_remove_pending_group_interface(wpa_s);
29458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return;
29468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
29478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
29488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	ssid = wpa_config_get_network(wpa_s->conf,
29498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt				      wpa_s->pending_invite_ssid_id);
29508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (ssid == NULL) {
29518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		wpa_printf(MSG_ERROR, "P2P: Could not find persistent group "
29528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			   "data matching with invitation");
29538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return;
29548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
29558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
29562c5b17df4c29abdf11a85216c2f6272af796c576Jouni Malinen	/*
29572c5b17df4c29abdf11a85216c2f6272af796c576Jouni Malinen	 * The peer could have missed our ctrl::ack frame for Invitation
29582c5b17df4c29abdf11a85216c2f6272af796c576Jouni Malinen	 * Response and continue retransmitting the frame. To reduce the
29592c5b17df4c29abdf11a85216c2f6272af796c576Jouni Malinen	 * likelihood of the peer not getting successful TX status for the
29602c5b17df4c29abdf11a85216c2f6272af796c576Jouni Malinen	 * Invitation Response frame, wait a short time here before starting
29612c5b17df4c29abdf11a85216c2f6272af796c576Jouni Malinen	 * the persistent group so that we will remain on the current channel to
29622c5b17df4c29abdf11a85216c2f6272af796c576Jouni Malinen	 * acknowledge any possible retransmission from the peer.
29632c5b17df4c29abdf11a85216c2f6272af796c576Jouni Malinen	 */
29642c5b17df4c29abdf11a85216c2f6272af796c576Jouni Malinen	wpa_dbg(wpa_s, MSG_DEBUG, "P2P: 50 ms wait on current channel before "
29652c5b17df4c29abdf11a85216c2f6272af796c576Jouni Malinen		"starting persistent group");
29662c5b17df4c29abdf11a85216c2f6272af796c576Jouni Malinen	os_sleep(0, 50000);
29672c5b17df4c29abdf11a85216c2f6272af796c576Jouni Malinen
296815907098d1f67c24bb000e593e279af173cf57d7Dmitry Shmidt	if (neg_freq > 0 && ssid->mode == WPAS_MODE_P2P_GO &&
296915907098d1f67c24bb000e593e279af173cf57d7Dmitry Shmidt	    freq_included(channels, neg_freq))
297015907098d1f67c24bb000e593e279af173cf57d7Dmitry Shmidt		freq = neg_freq;
297115907098d1f67c24bb000e593e279af173cf57d7Dmitry Shmidt	else if (peer_oper_freq > 0 && ssid->mode != WPAS_MODE_P2P_GO &&
297215907098d1f67c24bb000e593e279af173cf57d7Dmitry Shmidt		 freq_included(channels, peer_oper_freq))
297315907098d1f67c24bb000e593e279af173cf57d7Dmitry Shmidt		freq = peer_oper_freq;
297415907098d1f67c24bb000e593e279af173cf57d7Dmitry Shmidt	else
297515907098d1f67c24bb000e593e279af173cf57d7Dmitry Shmidt		freq = 0;
297615907098d1f67c24bb000e593e279af173cf57d7Dmitry Shmidt
297715907098d1f67c24bb000e593e279af173cf57d7Dmitry Shmidt	wpa_printf(MSG_DEBUG, "P2P: Persistent group invitation success - op_freq=%d MHz SSID=%s",
297815907098d1f67c24bb000e593e279af173cf57d7Dmitry Shmidt		   freq, wpa_ssid_txt(ssid->ssid, ssid->ssid_len));
29798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	wpas_p2p_group_add_persistent(wpa_s, ssid,
298031be0a4b946ecab910c0a9af3837dbccea5d204bJouni Malinen				      ssid->mode == WPAS_MODE_P2P_GO,
298196be6222df414a7dde5c5b1b72df22e67b1a77fcDmitry Shmidt				      wpa_s->p2p_persistent_go_freq,
298215907098d1f67c24bb000e593e279af173cf57d7Dmitry Shmidt				      freq,
298368d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt				      wpa_s->p2p_go_ht40, wpa_s->p2p_go_vht,
298468d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt				      channels,
29855605286c30e1701491bd3af974ae423727750eddDmitry Shmidt				      ssid->mode == WPAS_MODE_P2P_GO ?
29865605286c30e1701491bd3af974ae423727750eddDmitry Shmidt				      P2P_MAX_INITIAL_CONN_WAIT_GO_REINVOKE :
29875605286c30e1701491bd3af974ae423727750eddDmitry Shmidt				      0);
29888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt}
29898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
29908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
299104949598a23f501be6eec21697465fd46a28840aDmitry Shmidtstatic int wpas_p2p_disallowed_freq(struct wpa_global *global,
299204949598a23f501be6eec21697465fd46a28840aDmitry Shmidt				    unsigned int freq)
299304949598a23f501be6eec21697465fd46a28840aDmitry Shmidt{
2994cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt	if (freq_range_list_includes(&global->p2p_go_avoid_freq, freq))
2995cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt		return 1;
29964ce9c87407c036fc83eb5a6044ddf976c86f53fcDmitry Shmidt	return freq_range_list_includes(&global->p2p_disallow_freq, freq);
299704949598a23f501be6eec21697465fd46a28840aDmitry Shmidt}
299804949598a23f501be6eec21697465fd46a28840aDmitry Shmidt
299904949598a23f501be6eec21697465fd46a28840aDmitry Shmidt
300004949598a23f501be6eec21697465fd46a28840aDmitry Shmidtstatic void wpas_p2p_add_chan(struct p2p_reg_class *reg, u8 chan)
300104949598a23f501be6eec21697465fd46a28840aDmitry Shmidt{
300204949598a23f501be6eec21697465fd46a28840aDmitry Shmidt	reg->channel[reg->channels] = chan;
300304949598a23f501be6eec21697465fd46a28840aDmitry Shmidt	reg->channels++;
300404949598a23f501be6eec21697465fd46a28840aDmitry Shmidt}
300504949598a23f501be6eec21697465fd46a28840aDmitry Shmidt
300604949598a23f501be6eec21697465fd46a28840aDmitry Shmidt
30078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic int wpas_p2p_default_channels(struct wpa_supplicant *wpa_s,
300868d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt				     struct p2p_channels *chan,
300968d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt				     struct p2p_channels *cli_chan)
30108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{
30118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	int i, cla = 0;
30128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
30136c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt	wpa_s->global->p2p_24ghz_social_channels = 1;
30146c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt
301568d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt	os_memset(cli_chan, 0, sizeof(*cli_chan));
301668d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt
30178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	wpa_printf(MSG_DEBUG, "P2P: Enable operating classes for 2.4 GHz "
30188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		   "band");
30198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
30208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	/* Operating class 81 - 2.4 GHz band channels 1..13 */
30218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	chan->reg_class[cla].reg_class = 81;
302204949598a23f501be6eec21697465fd46a28840aDmitry Shmidt	chan->reg_class[cla].channels = 0;
302304949598a23f501be6eec21697465fd46a28840aDmitry Shmidt	for (i = 0; i < 11; i++) {
302404949598a23f501be6eec21697465fd46a28840aDmitry Shmidt		if (!wpas_p2p_disallowed_freq(wpa_s->global, 2412 + i * 5))
302504949598a23f501be6eec21697465fd46a28840aDmitry Shmidt			wpas_p2p_add_chan(&chan->reg_class[cla], i + 1);
302604949598a23f501be6eec21697465fd46a28840aDmitry Shmidt	}
302704949598a23f501be6eec21697465fd46a28840aDmitry Shmidt	if (chan->reg_class[cla].channels)
302804949598a23f501be6eec21697465fd46a28840aDmitry Shmidt		cla++;
30298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
30308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	wpa_printf(MSG_DEBUG, "P2P: Enable operating classes for lower 5 GHz "
30318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		   "band");
30328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
30338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	/* Operating class 115 - 5 GHz, channels 36-48 */
30348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	chan->reg_class[cla].reg_class = 115;
303504949598a23f501be6eec21697465fd46a28840aDmitry Shmidt	chan->reg_class[cla].channels = 0;
303604949598a23f501be6eec21697465fd46a28840aDmitry Shmidt	if (!wpas_p2p_disallowed_freq(wpa_s->global, 5000 + 36 * 5))
303704949598a23f501be6eec21697465fd46a28840aDmitry Shmidt		wpas_p2p_add_chan(&chan->reg_class[cla], 36);
303804949598a23f501be6eec21697465fd46a28840aDmitry Shmidt	if (!wpas_p2p_disallowed_freq(wpa_s->global, 5000 + 40 * 5))
303904949598a23f501be6eec21697465fd46a28840aDmitry Shmidt		wpas_p2p_add_chan(&chan->reg_class[cla], 40);
304004949598a23f501be6eec21697465fd46a28840aDmitry Shmidt	if (!wpas_p2p_disallowed_freq(wpa_s->global, 5000 + 44 * 5))
304104949598a23f501be6eec21697465fd46a28840aDmitry Shmidt		wpas_p2p_add_chan(&chan->reg_class[cla], 44);
304204949598a23f501be6eec21697465fd46a28840aDmitry Shmidt	if (!wpas_p2p_disallowed_freq(wpa_s->global, 5000 + 48 * 5))
304304949598a23f501be6eec21697465fd46a28840aDmitry Shmidt		wpas_p2p_add_chan(&chan->reg_class[cla], 48);
304404949598a23f501be6eec21697465fd46a28840aDmitry Shmidt	if (chan->reg_class[cla].channels)
304504949598a23f501be6eec21697465fd46a28840aDmitry Shmidt		cla++;
30468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
30478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	wpa_printf(MSG_DEBUG, "P2P: Enable operating classes for higher 5 GHz "
30488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		   "band");
30498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
30508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	/* Operating class 124 - 5 GHz, channels 149,153,157,161 */
30518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	chan->reg_class[cla].reg_class = 124;
305204949598a23f501be6eec21697465fd46a28840aDmitry Shmidt	chan->reg_class[cla].channels = 0;
305304949598a23f501be6eec21697465fd46a28840aDmitry Shmidt	if (!wpas_p2p_disallowed_freq(wpa_s->global, 5000 + 149 * 5))
305404949598a23f501be6eec21697465fd46a28840aDmitry Shmidt		wpas_p2p_add_chan(&chan->reg_class[cla], 149);
305504949598a23f501be6eec21697465fd46a28840aDmitry Shmidt	if (!wpas_p2p_disallowed_freq(wpa_s->global, 5000 + 153 * 5))
305604949598a23f501be6eec21697465fd46a28840aDmitry Shmidt		wpas_p2p_add_chan(&chan->reg_class[cla], 153);
305704949598a23f501be6eec21697465fd46a28840aDmitry Shmidt	if (!wpas_p2p_disallowed_freq(wpa_s->global, 5000 + 156 * 5))
305804949598a23f501be6eec21697465fd46a28840aDmitry Shmidt		wpas_p2p_add_chan(&chan->reg_class[cla], 157);
305904949598a23f501be6eec21697465fd46a28840aDmitry Shmidt	if (!wpas_p2p_disallowed_freq(wpa_s->global, 5000 + 161 * 5))
306004949598a23f501be6eec21697465fd46a28840aDmitry Shmidt		wpas_p2p_add_chan(&chan->reg_class[cla], 161);
306104949598a23f501be6eec21697465fd46a28840aDmitry Shmidt	if (chan->reg_class[cla].channels)
306204949598a23f501be6eec21697465fd46a28840aDmitry Shmidt		cla++;
30638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
30648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	chan->reg_classes = cla;
30658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	return 0;
30668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt}
30678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
30688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
30698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic struct hostapd_hw_modes * get_mode(struct hostapd_hw_modes *modes,
30708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt					  u16 num_modes,
30718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt					  enum hostapd_hw_mode mode)
30728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{
30738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	u16 i;
30748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
30758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	for (i = 0; i < num_modes; i++) {
30768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		if (modes[i].mode == mode)
30778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			return &modes[i];
30788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
30798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
30808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	return NULL;
30818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt}
30828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
30838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
308468d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidtenum chan_allowed {
30856c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt	NOT_ALLOWED, NO_IR, ALLOWED
308668d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt};
308768d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt
308804949598a23f501be6eec21697465fd46a28840aDmitry Shmidtstatic int has_channel(struct wpa_global *global,
308904949598a23f501be6eec21697465fd46a28840aDmitry Shmidt		       struct hostapd_hw_modes *mode, u8 chan, int *flags)
30908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{
30918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	int i;
309204949598a23f501be6eec21697465fd46a28840aDmitry Shmidt	unsigned int freq;
309304949598a23f501be6eec21697465fd46a28840aDmitry Shmidt
309404949598a23f501be6eec21697465fd46a28840aDmitry Shmidt	freq = (mode->mode == HOSTAPD_MODE_IEEE80211A ? 5000 : 2407) +
309504949598a23f501be6eec21697465fd46a28840aDmitry Shmidt		chan * 5;
309604949598a23f501be6eec21697465fd46a28840aDmitry Shmidt	if (wpas_p2p_disallowed_freq(global, freq))
309768d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt		return NOT_ALLOWED;
30988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
30998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	for (i = 0; i < mode->num_channels; i++) {
31008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		if (mode->channels[i].chan == chan) {
31018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			if (flags)
31028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt				*flags = mode->channels[i].flag;
310368d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt			if (mode->channels[i].flag &
310468d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt			    (HOSTAPD_CHAN_DISABLED |
310568d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt			     HOSTAPD_CHAN_RADAR))
310668d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt				return NOT_ALLOWED;
31076c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt			if (mode->channels[i].flag & HOSTAPD_CHAN_NO_IR)
31086c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt				return NO_IR;
310968d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt			return ALLOWED;
31108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		}
31118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
31128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
311368d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt	return NOT_ALLOWED;
31148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt}
31158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
31168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
31178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstruct p2p_oper_class_map {
31188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	enum hostapd_hw_mode mode;
31198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	u8 op_class;
31208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	u8 min_chan;
31218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	u8 max_chan;
31228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	u8 inc;
3123661b4f78e48c697429dc46154a4125892c001718Dmitry Shmidt	enum { BW20, BW40PLUS, BW40MINUS, BW80, BW2160 } bw;
31248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt};
31258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
31261d755d025b206e22b06aeb322e25a79f98ca7777Dmitry Shmidtstatic const struct p2p_oper_class_map op_class[] = {
312761d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt	{ HOSTAPD_MODE_IEEE80211G, 81, 1, 13, 1, BW20 },
312861d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt#if 0 /* Do not enable HT40 on 2 GHz for now */
312961d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt	{ HOSTAPD_MODE_IEEE80211G, 83, 1, 9, 1, BW40PLUS },
313061d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt	{ HOSTAPD_MODE_IEEE80211G, 84, 5, 13, 1, BW40MINUS },
313161d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt#endif
313261d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt	{ HOSTAPD_MODE_IEEE80211A, 115, 36, 48, 4, BW20 },
313361d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt	{ HOSTAPD_MODE_IEEE80211A, 124, 149, 161, 4, BW20 },
3134a3dc30964aa24aea2b518246f6812663a1103490Dmitry Shmidt	{ HOSTAPD_MODE_IEEE80211A, 125, 149, 169, 4, BW20 },
313561d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt	{ HOSTAPD_MODE_IEEE80211A, 116, 36, 44, 8, BW40PLUS },
313661d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt	{ HOSTAPD_MODE_IEEE80211A, 117, 40, 48, 8, BW40MINUS },
313761d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt	{ HOSTAPD_MODE_IEEE80211A, 126, 149, 157, 8, BW40PLUS },
313861d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt	{ HOSTAPD_MODE_IEEE80211A, 127, 153, 161, 8, BW40MINUS },
313968d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt
314068d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt	/*
314168d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt	 * IEEE P802.11ac/D7.0 Table E-4 actually talks about channel center
314268d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt	 * frequency index 42, 58, 106, 122, 138, 155 with channel spacing of
314368d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt	 * 80 MHz, but currently use the following definition for simplicity
314468d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt	 * (these center frequencies are not actual channels, which makes
314568d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt	 * has_channel() fail). wpas_p2p_verify_80mhz() should take care of
314668d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt	 * removing invalid channels.
314768d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt	 */
314868d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt	{ HOSTAPD_MODE_IEEE80211A, 128, 36, 161, 4, BW80 },
3149661b4f78e48c697429dc46154a4125892c001718Dmitry Shmidt	{ HOSTAPD_MODE_IEEE80211AD, 180, 1, 4, 1, BW2160 },
315061d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt	{ -1, 0, 0, 0, 0, BW20 }
315161d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt};
315261d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt
315361d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt
315468d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidtstatic int wpas_p2p_get_center_80mhz(struct wpa_supplicant *wpa_s,
315568d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt				     struct hostapd_hw_modes *mode,
315668d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt				     u8 channel)
315761d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt{
315868d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt	u8 center_channels[] = { 42, 58, 106, 122, 138, 155 };
315968d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt	unsigned int i;
316061d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt
316168d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt	if (mode->mode != HOSTAPD_MODE_IEEE80211A)
316261d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt		return 0;
316368d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt
316468d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt	for (i = 0; i < ARRAY_SIZE(center_channels); i++)
316568d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt		/*
316668d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt		 * In 80 MHz, the bandwidth "spans" 12 channels (e.g., 36-48),
316768d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt		 * so the center channel is 6 channels away from the start/end.
316868d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt		 */
316968d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt		if (channel >= center_channels[i] - 6 &&
317068d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt		    channel <= center_channels[i] + 6)
317168d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt			return center_channels[i];
317268d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt
317368d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt	return 0;
317468d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt}
317568d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt
317668d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt
317768d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidtstatic enum chan_allowed wpas_p2p_verify_80mhz(struct wpa_supplicant *wpa_s,
317868d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt					       struct hostapd_hw_modes *mode,
317968d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt					       u8 channel, u8 bw)
318068d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt{
318168d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt	u8 center_chan;
318268d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt	int i, flags;
318368d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt	enum chan_allowed res, ret = ALLOWED;
318468d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt
318568d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt	center_chan = wpas_p2p_get_center_80mhz(wpa_s, mode, channel);
318668d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt	if (!center_chan)
318768d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt		return NOT_ALLOWED;
318868d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt	if (center_chan >= 58 && center_chan <= 138)
318968d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt		return NOT_ALLOWED; /* Do not allow DFS channels for P2P */
319068d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt
319168d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt	/* check all the channels are available */
319268d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt	for (i = 0; i < 4; i++) {
319368d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt		int adj_chan = center_chan - 6 + i * 4;
319468d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt
319568d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt		res = has_channel(wpa_s->global, mode, adj_chan, &flags);
319668d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt		if (res == NOT_ALLOWED)
319768d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt			return NOT_ALLOWED;
31986c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt		if (res == NO_IR)
31996c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt			ret = NO_IR;
320068d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt
320168d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt		if (i == 0 && !(flags & HOSTAPD_CHAN_VHT_10_70))
320268d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt			return NOT_ALLOWED;
320368d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt		if (i == 1 && !(flags & HOSTAPD_CHAN_VHT_30_50))
320468d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt			return NOT_ALLOWED;
320568d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt		if (i == 2 && !(flags & HOSTAPD_CHAN_VHT_50_30))
320668d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt			return NOT_ALLOWED;
320768d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt		if (i == 3 && !(flags & HOSTAPD_CHAN_VHT_70_10))
320868d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt			return NOT_ALLOWED;
320968d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt	}
321068d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt
321168d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt	return ret;
321268d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt}
321368d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt
321468d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt
321568d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidtstatic enum chan_allowed wpas_p2p_verify_channel(struct wpa_supplicant *wpa_s,
321668d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt						 struct hostapd_hw_modes *mode,
321768d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt						 u8 channel, u8 bw)
321868d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt{
321996be6222df414a7dde5c5b1b72df22e67b1a77fcDmitry Shmidt	int flag = 0;
322068d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt	enum chan_allowed res, res2;
322168d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt
322268d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt	res2 = res = has_channel(wpa_s->global, mode, channel, &flag);
322368d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt	if (bw == BW40MINUS) {
322468d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt		if (!(flag & HOSTAPD_CHAN_HT40MINUS))
322568d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt			return NOT_ALLOWED;
322668d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt		res2 = has_channel(wpa_s->global, mode, channel - 4, NULL);
322768d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt	} else if (bw == BW40PLUS) {
322868d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt		if (!(flag & HOSTAPD_CHAN_HT40PLUS))
322968d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt			return NOT_ALLOWED;
323068d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt		res2 = has_channel(wpa_s->global, mode, channel + 4, NULL);
323168d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt	} else if (bw == BW80) {
323268d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt		res2 = wpas_p2p_verify_80mhz(wpa_s, mode, channel, bw);
323368d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt	}
323468d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt
323568d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt	if (res == NOT_ALLOWED || res2 == NOT_ALLOWED)
323668d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt		return NOT_ALLOWED;
32376c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt	if (res == NO_IR || res2 == NO_IR)
32386c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt		return NO_IR;
323968d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt	return res;
324061d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt}
324161d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt
324261d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt
32438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic int wpas_p2p_setup_channels(struct wpa_supplicant *wpa_s,
324468d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt				   struct p2p_channels *chan,
324568d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt				   struct p2p_channels *cli_chan)
32468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{
32471f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt	struct hostapd_hw_modes *mode;
324868d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt	int cla, op, cli_cla;
32498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
32501f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt	if (wpa_s->hw.modes == NULL) {
32518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		wpa_printf(MSG_DEBUG, "P2P: Driver did not support fetching "
32528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			   "of all supported channels; assume dualband "
32538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			   "support");
325468d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt		return wpas_p2p_default_channels(wpa_s, chan, cli_chan);
32558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
32568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
325768d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt	cla = cli_cla = 0;
32588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
32598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	for (op = 0; op_class[op].op_class; op++) {
32601d755d025b206e22b06aeb322e25a79f98ca7777Dmitry Shmidt		const struct p2p_oper_class_map *o = &op_class[op];
32618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		u8 ch;
326268d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt		struct p2p_reg_class *reg = NULL, *cli_reg = NULL;
32638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
32641f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt		mode = get_mode(wpa_s->hw.modes, wpa_s->hw.num_modes, o->mode);
32658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		if (mode == NULL)
32668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			continue;
32676c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt		if (mode->mode == HOSTAPD_MODE_IEEE80211G)
32686c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt			wpa_s->global->p2p_24ghz_social_channels = 1;
32698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		for (ch = o->min_chan; ch <= o->max_chan; ch += o->inc) {
327068d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt			enum chan_allowed res;
327168d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt			res = wpas_p2p_verify_channel(wpa_s, mode, ch, o->bw);
327268d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt			if (res == ALLOWED) {
327368d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt				if (reg == NULL) {
327468d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt					wpa_printf(MSG_DEBUG, "P2P: Add operating class %u",
327568d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt						   o->op_class);
327668d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt					reg = &chan->reg_class[cla];
327768d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt					cla++;
327868d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt					reg->reg_class = o->op_class;
327968d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt				}
328068d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt				reg->channel[reg->channels] = ch;
328168d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt				reg->channels++;
32826c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt			} else if (res == NO_IR &&
328368d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt				   wpa_s->conf->p2p_add_cli_chan) {
328468d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt				if (cli_reg == NULL) {
328568d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt					wpa_printf(MSG_DEBUG, "P2P: Add operating class %u (client only)",
328668d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt						   o->op_class);
328768d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt					cli_reg = &cli_chan->reg_class[cli_cla];
328868d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt					cli_cla++;
328968d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt					cli_reg->reg_class = o->op_class;
329068d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt				}
329168d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt				cli_reg->channel[cli_reg->channels] = ch;
329268d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt				cli_reg->channels++;
32938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			}
32948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		}
32958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		if (reg) {
32968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			wpa_hexdump(MSG_DEBUG, "P2P: Channels",
32978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt				    reg->channel, reg->channels);
32988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		}
329968d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt		if (cli_reg) {
330068d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt			wpa_hexdump(MSG_DEBUG, "P2P: Channels (client only)",
330168d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt				    cli_reg->channel, cli_reg->channels);
330268d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt		}
33038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
33048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
33058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	chan->reg_classes = cla;
330668d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt	cli_chan->reg_classes = cli_cla;
33078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
33088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	return 0;
33098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt}
33108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
33118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
331261d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidtint wpas_p2p_get_ht40_mode(struct wpa_supplicant *wpa_s,
331361d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt			   struct hostapd_hw_modes *mode, u8 channel)
331461d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt{
331568d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt	int op;
331668d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt	enum chan_allowed ret;
331761d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt
331861d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt	for (op = 0; op_class[op].op_class; op++) {
33191d755d025b206e22b06aeb322e25a79f98ca7777Dmitry Shmidt		const struct p2p_oper_class_map *o = &op_class[op];
332061d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt		u8 ch;
332161d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt
332261d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt		for (ch = o->min_chan; ch <= o->max_chan; ch += o->inc) {
332361d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt			if (o->mode != HOSTAPD_MODE_IEEE80211A ||
3324a3dc30964aa24aea2b518246f6812663a1103490Dmitry Shmidt			    (o->bw != BW40PLUS && o->bw != BW40MINUS) ||
3325a3dc30964aa24aea2b518246f6812663a1103490Dmitry Shmidt			    ch != channel)
332661d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt				continue;
332761d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt			ret = wpas_p2p_verify_channel(wpa_s, mode, ch, o->bw);
332868d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt			if (ret == ALLOWED)
332961d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt				return (o->bw == BW40MINUS) ? -1 : 1;
333061d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt		}
333161d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt	}
333261d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt	return 0;
333361d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt}
333461d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt
333561d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt
333668d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidtint wpas_p2p_get_vht80_center(struct wpa_supplicant *wpa_s,
333768d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt			      struct hostapd_hw_modes *mode, u8 channel)
333868d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt{
333968d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt	if (!wpas_p2p_verify_channel(wpa_s, mode, channel, BW80))
334068d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt		return 0;
334168d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt
334268d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt	return wpas_p2p_get_center_80mhz(wpa_s, mode, channel);
334368d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt}
334468d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt
334568d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt
33468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic int wpas_get_noa(void *ctx, const u8 *interface_addr, u8 *buf,
33478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			size_t buf_len)
33488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{
33498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	struct wpa_supplicant *wpa_s = ctx;
33508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
33518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	for (wpa_s = wpa_s->global->ifaces; wpa_s; wpa_s = wpa_s->next) {
33528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		if (os_memcmp(wpa_s->own_addr, interface_addr, ETH_ALEN) == 0)
33538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			break;
33548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
33558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (wpa_s == NULL)
33568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return -1;
33578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
33588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	return wpa_drv_get_noa(wpa_s, buf, buf_len);
33598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt}
33608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
33618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
3362d30ac604c9f6da71a0dd7f46d25be05a2a62cfbbDmitry Shmidtstruct wpa_supplicant * wpas_get_p2p_go_iface(struct wpa_supplicant *wpa_s,
3363d30ac604c9f6da71a0dd7f46d25be05a2a62cfbbDmitry Shmidt					      const u8 *ssid, size_t ssid_len)
3364c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt{
3365d30ac604c9f6da71a0dd7f46d25be05a2a62cfbbDmitry Shmidt	for (wpa_s = wpa_s->global->ifaces; wpa_s; wpa_s = wpa_s->next) {
3366d30ac604c9f6da71a0dd7f46d25be05a2a62cfbbDmitry Shmidt		struct wpa_ssid *s = wpa_s->current_ssid;
3367d30ac604c9f6da71a0dd7f46d25be05a2a62cfbbDmitry Shmidt		if (s == NULL)
3368d30ac604c9f6da71a0dd7f46d25be05a2a62cfbbDmitry Shmidt			continue;
3369d30ac604c9f6da71a0dd7f46d25be05a2a62cfbbDmitry Shmidt		if (s->mode != WPAS_MODE_P2P_GO &&
3370d30ac604c9f6da71a0dd7f46d25be05a2a62cfbbDmitry Shmidt		    s->mode != WPAS_MODE_AP &&
3371d30ac604c9f6da71a0dd7f46d25be05a2a62cfbbDmitry Shmidt		    s->mode != WPAS_MODE_P2P_GROUP_FORMATION)
3372d30ac604c9f6da71a0dd7f46d25be05a2a62cfbbDmitry Shmidt			continue;
3373d30ac604c9f6da71a0dd7f46d25be05a2a62cfbbDmitry Shmidt		if (s->ssid_len != ssid_len ||
337403658834c33748b9ad86f3d4cdf0c7be9c6887d1Dmitry Shmidt		    os_memcmp(ssid, s->ssid, ssid_len) != 0)
3375d30ac604c9f6da71a0dd7f46d25be05a2a62cfbbDmitry Shmidt			continue;
3376d30ac604c9f6da71a0dd7f46d25be05a2a62cfbbDmitry Shmidt		return wpa_s;
3377d30ac604c9f6da71a0dd7f46d25be05a2a62cfbbDmitry Shmidt	}
3378d30ac604c9f6da71a0dd7f46d25be05a2a62cfbbDmitry Shmidt
3379d30ac604c9f6da71a0dd7f46d25be05a2a62cfbbDmitry Shmidt	return NULL;
3380d30ac604c9f6da71a0dd7f46d25be05a2a62cfbbDmitry Shmidt
3381d30ac604c9f6da71a0dd7f46d25be05a2a62cfbbDmitry Shmidt}
3382d30ac604c9f6da71a0dd7f46d25be05a2a62cfbbDmitry Shmidt
3383c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt
3384d30ac604c9f6da71a0dd7f46d25be05a2a62cfbbDmitry Shmidtstruct wpa_supplicant * wpas_get_p2p_client_iface(struct wpa_supplicant *wpa_s,
3385d30ac604c9f6da71a0dd7f46d25be05a2a62cfbbDmitry Shmidt						  const u8 *peer_dev_addr)
3386d30ac604c9f6da71a0dd7f46d25be05a2a62cfbbDmitry Shmidt{
3387c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt	for (wpa_s = wpa_s->global->ifaces; wpa_s; wpa_s = wpa_s->next) {
3388c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt		struct wpa_ssid *ssid = wpa_s->current_ssid;
3389c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt		if (ssid == NULL)
3390c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt			continue;
3391c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt		if (ssid->mode != WPAS_MODE_INFRA)
3392c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt			continue;
3393c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt		if (wpa_s->wpa_state != WPA_COMPLETED &&
3394c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt		    wpa_s->wpa_state != WPA_GROUP_HANDSHAKE)
3395c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt			continue;
3396d30ac604c9f6da71a0dd7f46d25be05a2a62cfbbDmitry Shmidt		if (os_memcmp(wpa_s->go_dev_addr, peer_dev_addr, ETH_ALEN) == 0)
3397d30ac604c9f6da71a0dd7f46d25be05a2a62cfbbDmitry Shmidt			return wpa_s;
3398c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt	}
3399c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt
3400d30ac604c9f6da71a0dd7f46d25be05a2a62cfbbDmitry Shmidt	return NULL;
3401d30ac604c9f6da71a0dd7f46d25be05a2a62cfbbDmitry Shmidt}
3402d30ac604c9f6da71a0dd7f46d25be05a2a62cfbbDmitry Shmidt
3403d30ac604c9f6da71a0dd7f46d25be05a2a62cfbbDmitry Shmidt
3404d30ac604c9f6da71a0dd7f46d25be05a2a62cfbbDmitry Shmidtstatic int wpas_go_connected(void *ctx, const u8 *dev_addr)
3405d30ac604c9f6da71a0dd7f46d25be05a2a62cfbbDmitry Shmidt{
3406d30ac604c9f6da71a0dd7f46d25be05a2a62cfbbDmitry Shmidt	struct wpa_supplicant *wpa_s = ctx;
3407d30ac604c9f6da71a0dd7f46d25be05a2a62cfbbDmitry Shmidt
3408d30ac604c9f6da71a0dd7f46d25be05a2a62cfbbDmitry Shmidt	return wpas_get_p2p_client_iface(wpa_s, dev_addr) != NULL;
3409c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt}
3410c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt
3411c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt
34121846323989242844f0e857458a8939fa5836429cDmitry Shmidtstatic int wpas_is_concurrent_session_active(void *ctx)
34131846323989242844f0e857458a8939fa5836429cDmitry Shmidt{
34141846323989242844f0e857458a8939fa5836429cDmitry Shmidt	struct wpa_supplicant *wpa_s = ctx;
34151846323989242844f0e857458a8939fa5836429cDmitry Shmidt	struct wpa_supplicant *ifs;
34161846323989242844f0e857458a8939fa5836429cDmitry Shmidt
34171846323989242844f0e857458a8939fa5836429cDmitry Shmidt	for (ifs = wpa_s->global->ifaces; ifs; ifs = ifs->next) {
34181846323989242844f0e857458a8939fa5836429cDmitry Shmidt		if (ifs == wpa_s)
34191846323989242844f0e857458a8939fa5836429cDmitry Shmidt			continue;
34201846323989242844f0e857458a8939fa5836429cDmitry Shmidt		if (ifs->wpa_state > WPA_ASSOCIATED)
34211846323989242844f0e857458a8939fa5836429cDmitry Shmidt			return 1;
34221846323989242844f0e857458a8939fa5836429cDmitry Shmidt	}
34231846323989242844f0e857458a8939fa5836429cDmitry Shmidt	return 0;
34241846323989242844f0e857458a8939fa5836429cDmitry Shmidt}
34251846323989242844f0e857458a8939fa5836429cDmitry Shmidt
34261846323989242844f0e857458a8939fa5836429cDmitry Shmidt
3427b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidtstatic void wpas_p2p_debug_print(void *ctx, int level, const char *msg)
3428b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt{
3429b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt	struct wpa_supplicant *wpa_s = ctx;
3430b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt	wpa_msg_global(wpa_s, level, "P2P: %s", msg);
3431b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt}
3432b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt
3433b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt
34349ead16e203b81d44a2d84eadc2901ceeb7daf805Dmitry Shmidtint wpas_p2p_add_p2pdev_interface(struct wpa_supplicant *wpa_s,
34359ead16e203b81d44a2d84eadc2901ceeb7daf805Dmitry Shmidt				  const char *conf_p2p_dev)
343634af306c42b7ccf956508e7cd23f0ba90606e360Dmitry Shmidt{
343734af306c42b7ccf956508e7cd23f0ba90606e360Dmitry Shmidt	struct wpa_interface iface;
343834af306c42b7ccf956508e7cd23f0ba90606e360Dmitry Shmidt	struct wpa_supplicant *p2pdev_wpa_s;
343934af306c42b7ccf956508e7cd23f0ba90606e360Dmitry Shmidt	char ifname[100];
344034af306c42b7ccf956508e7cd23f0ba90606e360Dmitry Shmidt	char force_name[100];
344134af306c42b7ccf956508e7cd23f0ba90606e360Dmitry Shmidt	int ret;
344234af306c42b7ccf956508e7cd23f0ba90606e360Dmitry Shmidt
34436c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt	ret = os_snprintf(ifname, sizeof(ifname), P2P_MGMT_DEVICE_PREFIX "%s",
34446c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt			  wpa_s->ifname);
34456c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt	if (os_snprintf_error(sizeof(ifname), ret))
34466c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt		return -1;
344734af306c42b7ccf956508e7cd23f0ba90606e360Dmitry Shmidt	force_name[0] = '\0';
344834af306c42b7ccf956508e7cd23f0ba90606e360Dmitry Shmidt	wpa_s->pending_interface_type = WPA_IF_P2P_DEVICE;
344934af306c42b7ccf956508e7cd23f0ba90606e360Dmitry Shmidt	ret = wpa_drv_if_add(wpa_s, WPA_IF_P2P_DEVICE, ifname, NULL, NULL,
345034af306c42b7ccf956508e7cd23f0ba90606e360Dmitry Shmidt			     force_name, wpa_s->pending_interface_addr, NULL);
345134af306c42b7ccf956508e7cd23f0ba90606e360Dmitry Shmidt	if (ret < 0) {
345234af306c42b7ccf956508e7cd23f0ba90606e360Dmitry Shmidt		wpa_printf(MSG_DEBUG, "P2P: Failed to create P2P Device interface");
345334af306c42b7ccf956508e7cd23f0ba90606e360Dmitry Shmidt		return ret;
345434af306c42b7ccf956508e7cd23f0ba90606e360Dmitry Shmidt	}
345534af306c42b7ccf956508e7cd23f0ba90606e360Dmitry Shmidt	os_strlcpy(wpa_s->pending_interface_name, ifname,
345634af306c42b7ccf956508e7cd23f0ba90606e360Dmitry Shmidt		   sizeof(wpa_s->pending_interface_name));
345734af306c42b7ccf956508e7cd23f0ba90606e360Dmitry Shmidt
345834af306c42b7ccf956508e7cd23f0ba90606e360Dmitry Shmidt	os_memset(&iface, 0, sizeof(iface));
345934af306c42b7ccf956508e7cd23f0ba90606e360Dmitry Shmidt	iface.p2p_mgmt = 1;
346034af306c42b7ccf956508e7cd23f0ba90606e360Dmitry Shmidt	iface.ifname = wpa_s->pending_interface_name;
346134af306c42b7ccf956508e7cd23f0ba90606e360Dmitry Shmidt	iface.driver = wpa_s->driver->name;
346234af306c42b7ccf956508e7cd23f0ba90606e360Dmitry Shmidt	iface.driver_param = wpa_s->conf->driver_param;
34632ac5f6049e74103a8fe8e9c78b330020081d7df4Dmitry Shmidt
34642ac5f6049e74103a8fe8e9c78b330020081d7df4Dmitry Shmidt	/*
34652ac5f6049e74103a8fe8e9c78b330020081d7df4Dmitry Shmidt	 * If a P2P Device configuration file was given, use it as the interface
34662ac5f6049e74103a8fe8e9c78b330020081d7df4Dmitry Shmidt	 * configuration file (instead of using parent's configuration file.
34672ac5f6049e74103a8fe8e9c78b330020081d7df4Dmitry Shmidt	 */
34689ead16e203b81d44a2d84eadc2901ceeb7daf805Dmitry Shmidt	if (conf_p2p_dev) {
34699ead16e203b81d44a2d84eadc2901ceeb7daf805Dmitry Shmidt		iface.confname = conf_p2p_dev;
34702ac5f6049e74103a8fe8e9c78b330020081d7df4Dmitry Shmidt		iface.ctrl_interface = NULL;
34712ac5f6049e74103a8fe8e9c78b330020081d7df4Dmitry Shmidt	} else {
34722ac5f6049e74103a8fe8e9c78b330020081d7df4Dmitry Shmidt		iface.confname = wpa_s->confname;
34732ac5f6049e74103a8fe8e9c78b330020081d7df4Dmitry Shmidt		iface.ctrl_interface = wpa_s->conf->ctrl_interface;
34742ac5f6049e74103a8fe8e9c78b330020081d7df4Dmitry Shmidt	}
34752ac5f6049e74103a8fe8e9c78b330020081d7df4Dmitry Shmidt
3476203eadb9eda41a1dde4a583edb4684319e3f399eDmitry Shmidt	p2pdev_wpa_s = wpa_supplicant_add_iface(wpa_s->global, &iface, wpa_s);
347734af306c42b7ccf956508e7cd23f0ba90606e360Dmitry Shmidt	if (!p2pdev_wpa_s) {
347834af306c42b7ccf956508e7cd23f0ba90606e360Dmitry Shmidt		wpa_printf(MSG_DEBUG, "P2P: Failed to add P2P Device interface");
347934af306c42b7ccf956508e7cd23f0ba90606e360Dmitry Shmidt		return -1;
348034af306c42b7ccf956508e7cd23f0ba90606e360Dmitry Shmidt	}
348134af306c42b7ccf956508e7cd23f0ba90606e360Dmitry Shmidt
348234af306c42b7ccf956508e7cd23f0ba90606e360Dmitry Shmidt	wpa_s->pending_interface_name[0] = '\0';
348334af306c42b7ccf956508e7cd23f0ba90606e360Dmitry Shmidt	return 0;
348434af306c42b7ccf956508e7cd23f0ba90606e360Dmitry Shmidt}
348534af306c42b7ccf956508e7cd23f0ba90606e360Dmitry Shmidt
348634af306c42b7ccf956508e7cd23f0ba90606e360Dmitry Shmidt
3487fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidtstatic void wpas_presence_resp(void *ctx, const u8 *src, u8 status,
3488fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt			       const u8 *noa, size_t noa_len)
3489fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt{
3490fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt	struct wpa_supplicant *wpa_s, *intf = ctx;
3491fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt	char hex[100];
3492fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt
3493fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt	for (wpa_s = intf->global->ifaces; wpa_s; wpa_s = wpa_s->next) {
3494fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt		if (wpa_s->waiting_presence_resp)
3495fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt			break;
3496fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt	}
3497fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt	if (!wpa_s) {
3498fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt		wpa_dbg(wpa_s, MSG_DEBUG, "P2P: No group interface was waiting for presence response");
3499fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt		return;
3500fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt	}
3501fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt	wpa_s->waiting_presence_resp = 0;
3502fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt
3503fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt	wpa_snprintf_hex(hex, sizeof(hex), noa, noa_len);
3504fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt	wpa_msg(wpa_s, MSG_INFO, P2P_EVENT_PRESENCE_RESPONSE "src=" MACSTR
3505fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt		" status=%u noa=%s", MAC2STR(src), status, hex);
3506fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt}
3507fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt
3508fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt
3509216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidtstatic int wpas_get_persistent_group(void *ctx, const u8 *addr, const u8 *ssid,
3510216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt				     size_t ssid_len, u8 *go_dev_addr,
3511216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt				     u8 *ret_ssid, size_t *ret_ssid_len)
3512216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt{
3513216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt	struct wpa_supplicant *wpa_s = ctx;
3514216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt	struct wpa_ssid *s;
3515216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt
3516216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt	s = wpas_p2p_get_persistent(wpa_s, addr, ssid, ssid_len);
3517216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt	if (s) {
3518216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt		os_memcpy(ret_ssid, s->ssid, s->ssid_len);
3519216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt		*ret_ssid_len = s->ssid_len;
3520216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt		os_memcpy(go_dev_addr, s->bssid, ETH_ALEN);
3521216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt		return 1;
3522216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt	}
3523216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt
3524216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt	return 0;
3525216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt}
3526216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt
3527216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt
3528216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidtstatic int wpas_get_go_info(void *ctx, u8 *intended_addr,
3529216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt			    u8 *ssid, size_t *ssid_len, int *group_iface)
3530216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt{
3531216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt	struct wpa_supplicant *wpa_s = ctx;
3532216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt	struct wpa_ssid *s;
3533216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt	u8 bssid[ETH_ALEN];
3534216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt
3535216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt	s = wpas_p2p_group_go_ssid(wpa_s, bssid);
3536216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt	if (!s) {
3537216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt		s = wpas_p2p_get_persistent_go(wpa_s);
3538216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt		if (s)
3539216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt			os_memcpy(bssid, s->bssid, ETH_ALEN);
3540216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt	}
3541216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt
3542216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt	*group_iface = wpas_p2p_create_iface(wpa_s);
3543216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt	if (!s)
3544216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt		return 0;
3545216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt
3546216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt	os_memcpy(intended_addr, bssid, ETH_ALEN);
3547216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt	os_memcpy(ssid, s->ssid, s->ssid_len);
3548216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt	*ssid_len = s->ssid_len;
3549216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt
3550216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt	return 1;
3551216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt}
3552216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt
3553216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt
3554216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidtstatic int wpas_remove_stale_groups(void *ctx, const u8 *peer, const u8 *go,
3555216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt				    const u8 *ssid, size_t ssid_len)
3556216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt{
3557216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt	struct wpa_supplicant *wpa_s = ctx;
3558216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt	struct wpa_ssid *s;
3559216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt	int save_config = 0;
3560216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt	size_t i;
3561216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt
3562216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt	/* Start with our first choice of Persistent Groups */
3563216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt	while ((s = wpas_p2p_get_persistent(wpa_s, peer, NULL, 0))) {
3564216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt		if (go && ssid && ssid_len &&
3565216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt		    s->ssid_len == ssid_len &&
3566216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt		    os_memcmp(go, s->bssid, ETH_ALEN) == 0 &&
3567216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt		    os_memcmp(ssid, s->ssid, ssid_len) == 0)
3568216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt			break;
3569216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt
3570216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt		/* Remove stale persistent group */
3571216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt		if (s->mode != WPAS_MODE_P2P_GO || s->num_p2p_clients <= 1) {
3572216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt			wpa_config_remove_network(wpa_s->conf, s->id);
3573216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt			save_config = 1;
3574216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt			continue;
3575216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt		}
3576216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt
3577216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt		for (i = 0; i < s->num_p2p_clients; i++) {
3578216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt			if (os_memcmp(s->p2p_client_list + i * 2 * ETH_ALEN,
3579216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt				      peer, ETH_ALEN) != 0)
3580216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt				continue;
3581216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt
3582216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt			os_memmove(s->p2p_client_list + i * 2 * ETH_ALEN,
3583216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt				   s->p2p_client_list + (i + 1) * 2 * ETH_ALEN,
3584216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt				   (s->num_p2p_clients - i - 1) * 2 * ETH_ALEN);
3585216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt			break;
3586216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt		}
3587216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt		s->num_p2p_clients--;
3588216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt		save_config = 1;
3589216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt	}
3590216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt
3591216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt	if (save_config)
3592216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt		p2p_config_write(wpa_s);
3593216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt
3594216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt	/* Return TRUE if valid SSID remains */
3595216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt	return s != NULL;
3596216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt}
3597216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt
3598216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt
3599216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidtstatic void wpas_p2ps_prov_complete(void *ctx, u8 status, const u8 *dev,
3600216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt				    const u8 *adv_mac, const u8 *ses_mac,
3601216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt				    const u8 *grp_mac, u32 adv_id, u32 ses_id,
3602216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt				    u8 conncap, int passwd_id,
3603216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt				    const u8 *persist_ssid,
3604216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt				    size_t persist_ssid_size, int response_done,
3605216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt				    int prov_start, const char *session_info)
3606216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt{
3607216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt	struct wpa_supplicant *wpa_s = ctx;
3608216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt	u8 mac[ETH_ALEN];
3609216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt	struct wpa_ssid *persistent_go, *stale, *s;
3610216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt	int save_config = 0;
3611216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt	struct wpa_supplicant *go_wpa_s;
3612216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt
3613216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt	if (!dev)
3614216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt		return;
3615216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt
3616216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt	os_memset(mac, 0, ETH_ALEN);
3617216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt	if (!adv_mac)
3618216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt		adv_mac = mac;
3619216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt	if (!ses_mac)
3620216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt		ses_mac = mac;
3621216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt	if (!grp_mac)
3622216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt		grp_mac = mac;
3623216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt
3624216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt	if (prov_start) {
3625216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt		if (session_info == NULL) {
3626216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt			wpa_msg_global(wpa_s, MSG_INFO,
3627216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt				       P2P_EVENT_P2PS_PROVISION_START MACSTR
3628216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt				       " adv_id=%x conncap=%x"
3629216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt				       " adv_mac=" MACSTR
3630216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt				       " session=%x mac=" MACSTR
3631216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt				       " dev_passwd_id=%d",
3632216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt				       MAC2STR(dev), adv_id, conncap,
3633216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt				       MAC2STR(adv_mac),
3634216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt				       ses_id, MAC2STR(ses_mac),
3635216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt				       passwd_id);
3636216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt		} else {
3637216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt			wpa_msg_global(wpa_s, MSG_INFO,
3638216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt				       P2P_EVENT_P2PS_PROVISION_START MACSTR
3639216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt				       " adv_id=%x conncap=%x"
3640216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt				       " adv_mac=" MACSTR
3641216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt				       " session=%x mac=" MACSTR
3642216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt				       " dev_passwd_id=%d info='%s'",
3643216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt				       MAC2STR(dev), adv_id, conncap,
3644216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt				       MAC2STR(adv_mac),
3645216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt				       ses_id, MAC2STR(ses_mac),
3646216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt				       passwd_id, session_info);
3647216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt		}
3648216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt		return;
3649216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt	}
3650216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt
3651216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt	go_wpa_s = wpas_p2p_get_go_group(wpa_s);
3652216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt	persistent_go = wpas_p2p_get_persistent_go(wpa_s);
3653216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt
3654216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt	if (status && status != P2P_SC_SUCCESS_DEFERRED) {
3655216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt		if (go_wpa_s && !p2p_group_go_member_count(wpa_s))
3656216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt			wpas_p2p_group_remove(wpa_s, go_wpa_s->ifname);
3657216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt
3658216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt		if (persistent_go && !persistent_go->num_p2p_clients) {
3659216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt			/* remove empty persistent GO */
3660216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt			wpa_config_remove_network(wpa_s->conf,
3661216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt						  persistent_go->id);
3662216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt		}
3663216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt
3664216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt		wpa_msg_global(wpa_s, MSG_INFO,
3665216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt			       P2P_EVENT_P2PS_PROVISION_DONE MACSTR
3666216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt			       " status=%d"
3667216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt			       " adv_id=%x adv_mac=" MACSTR
3668216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt			       " session=%x mac=" MACSTR,
3669216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt			       MAC2STR(dev), status,
3670216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt			       adv_id, MAC2STR(adv_mac),
3671216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt			       ses_id, MAC2STR(ses_mac));
3672216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt		return;
3673216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt	}
3674216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt
3675216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt	/* Clean up stale persistent groups with this device */
3676216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt	s = wpas_p2p_get_persistent(wpa_s, dev, persist_ssid,
3677216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt				    persist_ssid_size);
3678216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt	for (;;) {
3679216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt		stale = wpas_p2p_get_persistent(wpa_s, dev, NULL, 0);
3680216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt		if (!stale)
3681216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt			break;
3682216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt
3683216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt		if (s && s->ssid_len == stale->ssid_len &&
3684216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt		    os_memcmp(stale->bssid, s->bssid, ETH_ALEN) == 0 &&
3685216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt		    os_memcmp(stale->ssid, s->ssid, s->ssid_len) == 0)
3686216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt			break;
3687216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt
3688216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt		/* Remove stale persistent group */
3689216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt		if (stale->mode != WPAS_MODE_P2P_GO ||
3690216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt		    stale->num_p2p_clients <= 1) {
3691216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt			wpa_config_remove_network(wpa_s->conf, stale->id);
3692216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt		} else {
3693216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt			size_t i;
3694216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt
3695216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt			for (i = 0; i < stale->num_p2p_clients; i++) {
3696216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt				if (os_memcmp(stale->p2p_client_list +
3697216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt					      i * ETH_ALEN,
3698216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt					      dev, ETH_ALEN) == 0) {
3699216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt					os_memmove(stale->p2p_client_list +
3700216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt						   i * ETH_ALEN,
3701216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt						   stale->p2p_client_list +
3702216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt						   (i + 1) * ETH_ALEN,
3703216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt						   (stale->num_p2p_clients -
3704216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt						    i - 1) * ETH_ALEN);
3705216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt					break;
3706216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt				}
3707216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt			}
3708216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt			stale->num_p2p_clients--;
3709216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt		}
3710216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt		save_config = 1;
3711216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt	}
3712216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt
3713216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt	if (save_config)
3714216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt		p2p_config_write(wpa_s);
3715216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt
3716216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt	if (s) {
3717216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt		if (go_wpa_s && !p2p_group_go_member_count(wpa_s))
3718216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt			wpas_p2p_group_remove(wpa_s, go_wpa_s->ifname);
3719216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt
3720216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt		if (persistent_go && s != persistent_go &&
3721216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt		    !persistent_go->num_p2p_clients) {
3722216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt			/* remove empty persistent GO */
3723216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt			wpa_config_remove_network(wpa_s->conf,
3724216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt						  persistent_go->id);
3725216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt			/* Save config */
3726216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt		}
3727216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt
3728216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt		wpa_msg_global(wpa_s, MSG_INFO,
3729216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt			       P2P_EVENT_P2PS_PROVISION_DONE MACSTR
3730216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt			       " status=%d"
3731216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt			       " adv_id=%x adv_mac=" MACSTR
3732216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt			       " session=%x mac=" MACSTR
3733216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt			       " persist=%d",
3734216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt			       MAC2STR(dev), status,
3735216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt			       adv_id, MAC2STR(adv_mac),
3736216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt			       ses_id, MAC2STR(ses_mac), s->id);
3737216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt		return;
3738216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt	}
3739216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt
3740216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt	if (conncap == P2PS_SETUP_GROUP_OWNER) {
3741216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt		const char *go_ifname = NULL;
3742216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt		if (!go_wpa_s) {
3743216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt			wpa_s->global->pending_p2ps_group = 1;
3744216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt
3745216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt			if (wpa_s->conf->p2p_no_group_iface)
3746216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt				go_ifname = wpa_s->ifname;
3747216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt			else if (wpa_s->pending_interface_name[0])
3748216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt				go_ifname = wpa_s->pending_interface_name;
3749216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt
3750216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt			if (!go_ifname) {
3751216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt				wpas_p2ps_prov_complete(
3752216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt					wpa_s, P2P_SC_FAIL_UNKNOWN_GROUP,
3753216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt					dev, adv_mac, ses_mac,
3754216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt					NULL, adv_id, ses_id, 0, 0,
3755216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt					NULL, 0, 0, 0, NULL);
3756216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt				return;
3757216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt			}
3758216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt
3759216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt			/* If PD Resp complete, start up the GO */
3760216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt			if (response_done && persistent_go) {
3761216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt				wpas_p2p_group_add_persistent(
3762216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt					wpa_s, persistent_go,
3763216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt					0, 0, 0, 0, 0, NULL,
3764216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt					persistent_go->mode ==
3765216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt					WPAS_MODE_P2P_GO ?
3766216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt					P2P_MAX_INITIAL_CONN_WAIT_GO_REINVOKE :
3767216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt					0);
3768216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt			} else if (response_done) {
3769216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt				wpas_p2p_group_add(wpa_s, 1, 0, 0, 0);
3770216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt			}
3771216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt
3772216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt			if (passwd_id == DEV_PW_P2PS_DEFAULT) {
3773216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt				os_memcpy(wpa_s->p2ps_join_addr, dev, ETH_ALEN);
3774216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt				wpa_s->p2ps_join_addr_valid = 1;
3775216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt				wpa_dbg(wpa_s, MSG_DEBUG,
3776216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt					"P2PS: Saving PIN for " MACSTR,
3777216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt					MAC2STR(dev));
3778216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt			}
3779216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt		} else if (passwd_id == DEV_PW_P2PS_DEFAULT) {
3780216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt			go_ifname = go_wpa_s->ifname;
3781216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt
3782216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt			wpa_dbg(go_wpa_s, MSG_DEBUG,
3783216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt				"P2P: Setting PIN-1 For " MACSTR, MAC2STR(dev));
3784216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt			wpa_supplicant_ap_wps_pin(go_wpa_s, dev, "12345670",
3785216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt						  NULL, 0, 0);
3786216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt
3787216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt			os_memcpy(wpa_s->p2ps_join_addr, dev, ETH_ALEN);
3788216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt			wpa_s->p2ps_join_addr_valid = 1;
3789216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt			wpa_dbg(wpa_s, MSG_DEBUG,
3790216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt				"P2PS: Saving PIN for " MACSTR, MAC2STR(dev));
3791216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt		}
3792216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt
3793216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt		wpa_msg_global(wpa_s, MSG_INFO,
3794216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt			       P2P_EVENT_P2PS_PROVISION_DONE MACSTR
3795216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt			       " status=%d conncap=%x"
3796216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt			       " adv_id=%x adv_mac=" MACSTR
3797216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt			       " session=%x mac=" MACSTR
3798216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt			       " dev_passwd_id=%d go=%s",
3799216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt			       MAC2STR(dev), status, conncap,
3800216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt			       adv_id, MAC2STR(adv_mac),
3801216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt			       ses_id, MAC2STR(ses_mac),
3802216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt			       passwd_id, go_ifname);
3803216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt		return;
3804216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt	}
3805216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt
3806216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt	if (go_wpa_s && !p2p_group_go_member_count(wpa_s))
3807216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt		wpas_p2p_group_remove(wpa_s, go_wpa_s->ifname);
3808216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt
3809216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt	if (persistent_go && !persistent_go->num_p2p_clients) {
3810216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt		/* remove empty persistent GO */
3811216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt		wpa_config_remove_network(wpa_s->conf, persistent_go->id);
3812216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt	}
3813216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt
3814216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt	if (conncap == P2PS_SETUP_CLIENT) {
3815216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt		wpa_msg_global(wpa_s, MSG_INFO,
3816216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt			       P2P_EVENT_P2PS_PROVISION_DONE MACSTR
3817216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt			       " status=%d conncap=%x"
3818216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt			       " adv_id=%x adv_mac=" MACSTR
3819216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt			       " session=%x mac=" MACSTR
3820216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt			       " dev_passwd_id=%d join=" MACSTR,
3821216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt			       MAC2STR(dev), status, conncap,
3822216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt			       adv_id, MAC2STR(adv_mac),
3823216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt			       ses_id, MAC2STR(ses_mac),
3824216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt			       passwd_id, MAC2STR(grp_mac));
3825216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt	} else {
3826216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt		wpa_msg_global(wpa_s, MSG_INFO,
3827216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt			       P2P_EVENT_P2PS_PROVISION_DONE MACSTR
3828216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt			       " status=%d conncap=%x"
3829216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt			       " adv_id=%x adv_mac=" MACSTR
3830216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt			       " session=%x mac=" MACSTR
3831216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt			       " dev_passwd_id=%d",
3832216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt			       MAC2STR(dev), status, conncap,
3833216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt			       adv_id, MAC2STR(adv_mac),
3834216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt			       ses_id, MAC2STR(ses_mac),
3835216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt			       passwd_id);
3836216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt	}
3837216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt}
3838216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt
3839216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt
38405a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidtstatic int _wpas_p2p_in_progress(void *ctx)
38415a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt{
38425a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt	struct wpa_supplicant *wpa_s = ctx;
38435a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt	return wpas_p2p_in_progress(wpa_s);
38445a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt}
38455a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt
38465a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt
3847216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidtstatic int wpas_prov_disc_resp_cb(void *ctx)
3848216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt{
3849216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt	struct wpa_supplicant *wpa_s = ctx;
3850216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt	struct wpa_ssid *persistent_go;
3851216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt
3852216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt	if (!wpa_s->global->pending_p2ps_group)
3853216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt		return 0;
3854216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt
3855216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt	wpa_s->global->pending_p2ps_group = 0;
3856216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt
3857216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt	if (wpas_p2p_get_go_group(wpa_s))
3858216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt		return 0;
3859216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt	persistent_go = wpas_p2p_get_persistent_go(wpa_s);
3860216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt
3861216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt	if (persistent_go) {
3862216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt		wpas_p2p_group_add_persistent(
3863216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt			wpa_s, persistent_go, 0, 0, 0, 0, 0, NULL,
3864216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt			persistent_go->mode == WPAS_MODE_P2P_GO ?
3865216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt			P2P_MAX_INITIAL_CONN_WAIT_GO_REINVOKE : 0);
3866216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt	} else {
3867216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt		wpas_p2p_group_add(wpa_s, 1, 0, 0, 0);
3868216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt	}
3869216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt
3870216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt	return 1;
3871216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt}
3872216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt
3873216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt
38748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt/**
38758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * wpas_p2p_init - Initialize P2P module for %wpa_supplicant
38768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @global: Pointer to global data from wpa_supplicant_init()
38778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @wpa_s: Pointer to wpa_supplicant data from wpa_supplicant_add_iface()
38788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * Returns: 0 on success, -1 on failure
38798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */
38808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtint wpas_p2p_init(struct wpa_global *global, struct wpa_supplicant *wpa_s)
38818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{
38828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	struct p2p_config p2p;
38838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	int i;
38848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
3885391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt	if (wpa_s->conf->p2p_disabled)
3886391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt		return 0;
3887391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt
38888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (!(wpa_s->drv_flags & WPA_DRIVER_FLAGS_P2P_CAPABLE))
38898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return 0;
38908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
38918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (global->p2p)
38928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return 0;
38938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
38948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	os_memset(&p2p, 0, sizeof(p2p));
38958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	p2p.cb_ctx = wpa_s;
3896b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt	p2p.debug_print = wpas_p2p_debug_print;
38978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	p2p.p2p_scan = wpas_p2p_scan;
38988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	p2p.send_action = wpas_send_action;
38998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	p2p.send_action_done = wpas_send_action_done;
39008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	p2p.go_neg_completed = wpas_go_neg_completed;
39018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	p2p.go_neg_req_rx = wpas_go_neg_req_rx;
39028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	p2p.dev_found = wpas_dev_found;
39038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	p2p.dev_lost = wpas_dev_lost;
3904b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt	p2p.find_stopped = wpas_find_stopped;
39058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	p2p.start_listen = wpas_start_listen;
39068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	p2p.stop_listen = wpas_stop_listen;
39078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	p2p.send_probe_resp = wpas_send_probe_resp;
39088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	p2p.sd_request = wpas_sd_request;
39098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	p2p.sd_response = wpas_sd_response;
39108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	p2p.prov_disc_req = wpas_prov_disc_req;
39118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	p2p.prov_disc_resp = wpas_prov_disc_resp;
391275ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen	p2p.prov_disc_fail = wpas_prov_disc_fail;
39138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	p2p.invitation_process = wpas_invitation_process;
39148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	p2p.invitation_received = wpas_invitation_received;
39158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	p2p.invitation_result = wpas_invitation_result;
39168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	p2p.get_noa = wpas_get_noa;
3917c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt	p2p.go_connected = wpas_go_connected;
3918fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt	p2p.presence_resp = wpas_presence_resp;
39191846323989242844f0e857458a8939fa5836429cDmitry Shmidt	p2p.is_concurrent_session_active = wpas_is_concurrent_session_active;
39205a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt	p2p.is_p2p_in_progress = _wpas_p2p_in_progress;
3921216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt	p2p.get_persistent_group = wpas_get_persistent_group;
3922216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt	p2p.get_go_info = wpas_get_go_info;
3923216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt	p2p.remove_stale_groups = wpas_remove_stale_groups;
3924216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt	p2p.p2ps_prov_complete = wpas_p2ps_prov_complete;
3925216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt	p2p.prov_disc_resp_cb = wpas_prov_disc_resp_cb;
3926216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt	p2p.p2ps_group_capability = p2ps_group_capability;
39278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
39288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	os_memcpy(wpa_s->global->p2p_dev_addr, wpa_s->own_addr, ETH_ALEN);
39291f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt	os_memcpy(p2p.dev_addr, wpa_s->global->p2p_dev_addr, ETH_ALEN);
39308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	p2p.dev_name = wpa_s->conf->device_name;
39318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	p2p.manufacturer = wpa_s->conf->manufacturer;
39328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	p2p.model_name = wpa_s->conf->model_name;
39338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	p2p.model_number = wpa_s->conf->model_number;
39348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	p2p.serial_number = wpa_s->conf->serial_number;
39358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (wpa_s->wps) {
39368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		os_memcpy(p2p.uuid, wpa_s->wps->uuid, 16);
39378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		p2p.config_methods = wpa_s->wps->config_methods;
39388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
39398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
3940661b4f78e48c697429dc46154a4125892c001718Dmitry Shmidt	if (wpas_p2p_setup_channels(wpa_s, &p2p.channels, &p2p.cli_channels)) {
3941661b4f78e48c697429dc46154a4125892c001718Dmitry Shmidt		wpa_printf(MSG_ERROR,
3942661b4f78e48c697429dc46154a4125892c001718Dmitry Shmidt			   "P2P: Failed to configure supported channel list");
3943661b4f78e48c697429dc46154a4125892c001718Dmitry Shmidt		return -1;
3944661b4f78e48c697429dc46154a4125892c001718Dmitry Shmidt	}
3945661b4f78e48c697429dc46154a4125892c001718Dmitry Shmidt
39468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (wpa_s->conf->p2p_listen_reg_class &&
39478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	    wpa_s->conf->p2p_listen_channel) {
39488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		p2p.reg_class = wpa_s->conf->p2p_listen_reg_class;
39498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		p2p.channel = wpa_s->conf->p2p_listen_channel;
395043cb578dfe2c492257636f6234a24178ed27789eDmitry Shmidt		p2p.channel_forced = 1;
39518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	} else {
39528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		/*
39538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		 * Pick one of the social channels randomly as the listen
39548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		 * channel.
39558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		 */
3956661b4f78e48c697429dc46154a4125892c001718Dmitry Shmidt		if (p2p_config_get_random_social(&p2p, &p2p.reg_class,
3957661b4f78e48c697429dc46154a4125892c001718Dmitry Shmidt						 &p2p.channel) != 0) {
39581d755d025b206e22b06aeb322e25a79f98ca7777Dmitry Shmidt			wpa_printf(MSG_INFO,
39591d755d025b206e22b06aeb322e25a79f98ca7777Dmitry Shmidt				   "P2P: No social channels supported by the driver - do not enable P2P");
39601d755d025b206e22b06aeb322e25a79f98ca7777Dmitry Shmidt			return 0;
3961661b4f78e48c697429dc46154a4125892c001718Dmitry Shmidt		}
396243cb578dfe2c492257636f6234a24178ed27789eDmitry Shmidt		p2p.channel_forced = 0;
39638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
3964661b4f78e48c697429dc46154a4125892c001718Dmitry Shmidt	wpa_printf(MSG_DEBUG, "P2P: Own listen channel: %d:%d",
3965661b4f78e48c697429dc46154a4125892c001718Dmitry Shmidt		   p2p.reg_class, p2p.channel);
39668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
39678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (wpa_s->conf->p2p_oper_reg_class &&
39688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	    wpa_s->conf->p2p_oper_channel) {
39698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		p2p.op_reg_class = wpa_s->conf->p2p_oper_reg_class;
39708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		p2p.op_channel = wpa_s->conf->p2p_oper_channel;
39718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		p2p.cfg_op_channel = 1;
39728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		wpa_printf(MSG_DEBUG, "P2P: Configured operating channel: "
39738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			   "%d:%d", p2p.op_reg_class, p2p.op_channel);
39748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
39758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	} else {
39768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		/*
3977661b4f78e48c697429dc46154a4125892c001718Dmitry Shmidt		 * Use random operation channel from 2.4 GHz band social
3978661b4f78e48c697429dc46154a4125892c001718Dmitry Shmidt		 * channels (1, 6, 11) or band 60 GHz social channel (2) if no
3979661b4f78e48c697429dc46154a4125892c001718Dmitry Shmidt		 * other preference is indicated.
39808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		 */
3981661b4f78e48c697429dc46154a4125892c001718Dmitry Shmidt		if (p2p_config_get_random_social(&p2p, &p2p.op_reg_class,
3982661b4f78e48c697429dc46154a4125892c001718Dmitry Shmidt						 &p2p.op_channel) != 0) {
3983661b4f78e48c697429dc46154a4125892c001718Dmitry Shmidt			wpa_printf(MSG_ERROR,
3984661b4f78e48c697429dc46154a4125892c001718Dmitry Shmidt				   "P2P: Failed to select random social channel as operation channel");
3985661b4f78e48c697429dc46154a4125892c001718Dmitry Shmidt			return -1;
3986661b4f78e48c697429dc46154a4125892c001718Dmitry Shmidt		}
39878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		p2p.cfg_op_channel = 0;
39888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		wpa_printf(MSG_DEBUG, "P2P: Random operating channel: "
39898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			   "%d:%d", p2p.op_reg_class, p2p.op_channel);
39908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
399144c957860ca714a86357591f39aff0bfa904c743Dmitry Shmidt
399244c957860ca714a86357591f39aff0bfa904c743Dmitry Shmidt	if (wpa_s->conf->p2p_pref_chan && wpa_s->conf->num_p2p_pref_chan) {
399344c957860ca714a86357591f39aff0bfa904c743Dmitry Shmidt		p2p.pref_chan = wpa_s->conf->p2p_pref_chan;
399444c957860ca714a86357591f39aff0bfa904c743Dmitry Shmidt		p2p.num_pref_chan = wpa_s->conf->num_p2p_pref_chan;
399544c957860ca714a86357591f39aff0bfa904c743Dmitry Shmidt	}
399644c957860ca714a86357591f39aff0bfa904c743Dmitry Shmidt
39978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (wpa_s->conf->country[0] && wpa_s->conf->country[1]) {
39988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		os_memcpy(p2p.country, wpa_s->conf->country, 2);
39998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		p2p.country[2] = 0x04;
40008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	} else
40018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		os_memcpy(p2p.country, "XX\x04", 3);
40028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
40038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	os_memcpy(p2p.pri_dev_type, wpa_s->conf->device_type,
40048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		  WPS_DEV_TYPE_LEN);
40058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
40068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	p2p.num_sec_dev_types = wpa_s->conf->num_sec_device_types;
40078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	os_memcpy(p2p.sec_dev_type, wpa_s->conf->sec_device_type,
40088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		  p2p.num_sec_dev_types * WPS_DEV_TYPE_LEN);
40098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
40108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	p2p.concurrent_operations = !!(wpa_s->drv_flags &
40118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt				       WPA_DRIVER_FLAGS_P2P_CONCURRENT);
40128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
40138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	p2p.max_peers = 100;
40148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
40158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (wpa_s->conf->p2p_ssid_postfix) {
40168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		p2p.ssid_postfix_len =
40178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			os_strlen(wpa_s->conf->p2p_ssid_postfix);
40188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		if (p2p.ssid_postfix_len > sizeof(p2p.ssid_postfix))
40198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			p2p.ssid_postfix_len = sizeof(p2p.ssid_postfix);
40208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		os_memcpy(p2p.ssid_postfix, wpa_s->conf->p2p_ssid_postfix,
40218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			  p2p.ssid_postfix_len);
40228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
40238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
40248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	p2p.p2p_intra_bss = wpa_s->conf->p2p_intra_bss;
40258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
4026d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt	p2p.max_listen = wpa_s->max_remain_on_chan;
4027d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt
40282271d3fdd5982d0e5e81cf9999a861bba933eacbDmitry Shmidt	if (wpa_s->conf->p2p_passphrase_len >= 8 &&
40292271d3fdd5982d0e5e81cf9999a861bba933eacbDmitry Shmidt	    wpa_s->conf->p2p_passphrase_len <= 63)
40302271d3fdd5982d0e5e81cf9999a861bba933eacbDmitry Shmidt		p2p.passphrase_len = wpa_s->conf->p2p_passphrase_len;
40312271d3fdd5982d0e5e81cf9999a861bba933eacbDmitry Shmidt	else
40322271d3fdd5982d0e5e81cf9999a861bba933eacbDmitry Shmidt		p2p.passphrase_len = 8;
40332271d3fdd5982d0e5e81cf9999a861bba933eacbDmitry Shmidt
40348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	global->p2p = p2p_init(&p2p);
40358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (global->p2p == NULL)
40368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return -1;
403704949598a23f501be6eec21697465fd46a28840aDmitry Shmidt	global->p2p_init_wpa_s = wpa_s;
40388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
40398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	for (i = 0; i < MAX_WPS_VENDOR_EXT; i++) {
40408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		if (wpa_s->conf->wps_vendor_ext[i] == NULL)
40418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			continue;
40428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		p2p_add_wps_vendor_extension(
40438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			global->p2p, wpa_s->conf->wps_vendor_ext[i]);
40448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
40458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
404668d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt	p2p_set_no_go_freq(global->p2p, &wpa_s->conf->p2p_no_go_freq);
404768d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt
40488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	return 0;
40498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt}
40508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
40518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
40528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt/**
40538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * wpas_p2p_deinit - Deinitialize per-interface P2P data
40548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @wpa_s: Pointer to wpa_supplicant data from wpa_supplicant_add_iface()
40558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt *
40568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * This function deinitialize per-interface P2P data.
40578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */
40588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtvoid wpas_p2p_deinit(struct wpa_supplicant *wpa_s)
40598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{
40608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (wpa_s->driver && wpa_s->drv_priv)
40618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		wpa_drv_probe_req_report(wpa_s, 0);
40621f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt
40631f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt	if (wpa_s->go_params) {
40641f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt		/* Clear any stored provisioning info */
40651f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt		p2p_clear_provisioning_info(
40661f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt			wpa_s->global->p2p,
406704949598a23f501be6eec21697465fd46a28840aDmitry Shmidt			wpa_s->go_params->peer_device_addr);
40681f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt	}
40691f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt
40708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	os_free(wpa_s->go_params);
40718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	wpa_s->go_params = NULL;
4072684785c7f4e58498603a9a5ce26f933cc2557ebdDmitry Shmidt	eloop_cancel_timeout(wpas_p2p_psk_failure_removal, wpa_s, NULL);
40738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	eloop_cancel_timeout(wpas_p2p_group_formation_timeout, wpa_s, NULL);
40748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	eloop_cancel_timeout(wpas_p2p_join_scan, wpa_s, NULL);
40758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	wpa_s->p2p_long_listen = 0;
40768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	eloop_cancel_timeout(wpas_p2p_long_listen_timeout, wpa_s, NULL);
40778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	eloop_cancel_timeout(wpas_p2p_group_idle_timeout, wpa_s, NULL);
40788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	wpas_p2p_remove_pending_group_interface(wpa_s);
407904f534e89ed127da4077485376f24debc50d80d5Dmitry Shmidt	eloop_cancel_timeout(wpas_p2p_group_freq_conflict, wpa_s, NULL);
4080fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt	wpas_p2p_listen_work_done(wpa_s);
4081fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt	if (wpa_s->p2p_send_action_work) {
4082fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt		os_free(wpa_s->p2p_send_action_work->ctx);
4083fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt		radio_work_done(wpa_s->p2p_send_action_work);
4084fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt		wpa_s->p2p_send_action_work = NULL;
4085fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt	}
4086fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt	eloop_cancel_timeout(wpas_p2p_send_action_work_timeout, wpa_s, NULL);
40878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
4088cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt	wpabuf_free(wpa_s->p2p_oob_dev_pw);
4089cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt	wpa_s->p2p_oob_dev_pw = NULL;
4090cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt
40916c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt	os_free(wpa_s->p2p_group_common_freqs);
40926c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt	wpa_s->p2p_group_common_freqs = NULL;
40936c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt	wpa_s->p2p_group_common_freqs_num = 0;
40946c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt
40958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	/* TODO: remove group interface from the driver if this wpa_s instance
40968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	 * is on top of a P2P group interface */
40978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt}
40988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
40998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
41008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt/**
41018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * wpas_p2p_deinit_global - Deinitialize global P2P module
41028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @global: Pointer to global data from wpa_supplicant_init()
41038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt *
41048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * This function deinitializes the global (per device) P2P module.
41058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */
410643cb578dfe2c492257636f6234a24178ed27789eDmitry Shmidtstatic void wpas_p2p_deinit_global(struct wpa_global *global)
41078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{
41088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	struct wpa_supplicant *wpa_s, *tmp;
41098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
411061d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt	wpa_s = global->ifaces;
411161d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt
4112661b4f78e48c697429dc46154a4125892c001718Dmitry Shmidt	wpas_p2p_service_flush(global->p2p_init_wpa_s);
41138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
41148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	/* Remove remaining P2P group interfaces */
41158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	while (wpa_s && wpa_s->p2p_group_interface != NOT_P2P_GROUP_INTERFACE)
41168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		wpa_s = wpa_s->next;
41178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	while (wpa_s) {
41188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		tmp = global->ifaces;
41198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		while (tmp &&
41208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		       (tmp == wpa_s ||
41218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			tmp->p2p_group_interface == NOT_P2P_GROUP_INTERFACE)) {
41228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			tmp = tmp->next;
41238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		}
41248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		if (tmp == NULL)
41258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			break;
412604949598a23f501be6eec21697465fd46a28840aDmitry Shmidt		/* Disconnect from the P2P group and deinit the interface */
412704949598a23f501be6eec21697465fd46a28840aDmitry Shmidt		wpas_p2p_disconnect(tmp);
41288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
41298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
41308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	/*
41318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	 * Deinit GO data on any possibly remaining interface (if main
41328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	 * interface is used as GO).
41338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	 */
41348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	for (wpa_s = global->ifaces; wpa_s; wpa_s = wpa_s->next) {
41358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		if (wpa_s->ap_iface)
41368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			wpas_p2p_group_deinit(wpa_s);
41378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
41388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
41398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	p2p_deinit(global->p2p);
41408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	global->p2p = NULL;
414104949598a23f501be6eec21697465fd46a28840aDmitry Shmidt	global->p2p_init_wpa_s = NULL;
41428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt}
41438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
41448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
41458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic int wpas_p2p_create_iface(struct wpa_supplicant *wpa_s)
41468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{
414734af306c42b7ccf956508e7cd23f0ba90606e360Dmitry Shmidt	if (!(wpa_s->drv_flags & WPA_DRIVER_FLAGS_DEDICATED_P2P_DEVICE) &&
414834af306c42b7ccf956508e7cd23f0ba90606e360Dmitry Shmidt	    wpa_s->conf->p2p_no_group_iface)
4149d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt		return 0; /* separate interface disabled per configuration */
41508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (wpa_s->drv_flags &
41518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	    (WPA_DRIVER_FLAGS_P2P_DEDICATED_INTERFACE |
41528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	     WPA_DRIVER_FLAGS_P2P_MGMT_AND_NON_P2P))
41538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return 1; /* P2P group requires a new interface in every case
41548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			   */
41558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (!(wpa_s->drv_flags & WPA_DRIVER_FLAGS_P2P_CONCURRENT))
41568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return 0; /* driver does not support concurrent operations */
41578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (wpa_s->global->ifaces->next)
41588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return 1; /* more that one interface already in use */
41598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (wpa_s->wpa_state >= WPA_AUTHENTICATING)
41608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return 1; /* this interface is already in use */
41618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	return 0;
41628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt}
41638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
41648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
41658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic int wpas_p2p_start_go_neg(struct wpa_supplicant *wpa_s,
41668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt				 const u8 *peer_addr,
41678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt				 enum p2p_wps_method wps_method,
41688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt				 int go_intent, const u8 *own_interface_addr,
416904949598a23f501be6eec21697465fd46a28840aDmitry Shmidt				 unsigned int force_freq, int persistent_group,
4170d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt				 struct wpa_ssid *ssid, unsigned int pref_freq)
41718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{
41721f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt	if (persistent_group && wpa_s->conf->persistent_reconnect)
41731f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt		persistent_group = 2;
41741f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt
417561d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt	/*
417661d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt	 * Increase GO config timeout if HT40 is used since it takes some time
417761d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt	 * to scan channels for coex purposes before the BSS can be started.
417861d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt	 */
417961d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt	p2p_set_config_timeout(wpa_s->global->p2p,
418061d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt			       wpa_s->p2p_go_ht40 ? 255 : 100, 20);
418161d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt
41828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	return p2p_connect(wpa_s->global->p2p, peer_addr, wps_method,
41838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			   go_intent, own_interface_addr, force_freq,
418404949598a23f501be6eec21697465fd46a28840aDmitry Shmidt			   persistent_group, ssid ? ssid->ssid : NULL,
418504949598a23f501be6eec21697465fd46a28840aDmitry Shmidt			   ssid ? ssid->ssid_len : 0,
4186cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt			   wpa_s->p2p_pd_before_go_neg, pref_freq,
4187cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt			   wps_method == WPS_NFC ? wpa_s->p2p_oob_dev_pw_id :
4188cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt			   0);
41898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt}
41908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
41918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
41928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic int wpas_p2p_auth_go_neg(struct wpa_supplicant *wpa_s,
41938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt				const u8 *peer_addr,
41948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt				enum p2p_wps_method wps_method,
41958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt				int go_intent, const u8 *own_interface_addr,
419604949598a23f501be6eec21697465fd46a28840aDmitry Shmidt				unsigned int force_freq, int persistent_group,
4197d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt				struct wpa_ssid *ssid, unsigned int pref_freq)
41988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{
41991f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt	if (persistent_group && wpa_s->conf->persistent_reconnect)
42001f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt		persistent_group = 2;
42011f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt
42028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	return p2p_authorize(wpa_s->global->p2p, peer_addr, wps_method,
42038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			     go_intent, own_interface_addr, force_freq,
420404949598a23f501be6eec21697465fd46a28840aDmitry Shmidt			     persistent_group, ssid ? ssid->ssid : NULL,
4205cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt			     ssid ? ssid->ssid_len : 0, pref_freq,
4206cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt			     wps_method == WPS_NFC ? wpa_s->p2p_oob_dev_pw_id :
4207cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt			     0);
42088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt}
42098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
42108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
42118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic void wpas_p2p_check_join_scan_limit(struct wpa_supplicant *wpa_s)
42128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{
42138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	wpa_s->p2p_join_scan_count++;
42148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	wpa_printf(MSG_DEBUG, "P2P: Join scan attempt %d",
42158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		   wpa_s->p2p_join_scan_count);
42168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (wpa_s->p2p_join_scan_count > P2P_MAX_JOIN_SCAN_ATTEMPTS) {
42178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		wpa_printf(MSG_DEBUG, "P2P: Failed to find GO " MACSTR
42188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			   " for join operationg - stop join attempt",
42198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			   MAC2STR(wpa_s->pending_join_iface_addr));
42208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		eloop_cancel_timeout(wpas_p2p_join_scan, wpa_s, NULL);
422104949598a23f501be6eec21697465fd46a28840aDmitry Shmidt		if (wpa_s->p2p_auto_pd) {
422204949598a23f501be6eec21697465fd46a28840aDmitry Shmidt			wpa_s->p2p_auto_pd = 0;
4223b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt			wpa_msg_global(wpa_s, MSG_INFO,
4224b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt				       P2P_EVENT_PROV_DISC_FAILURE
4225b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt				       " p2p_dev_addr=" MACSTR " status=N/A",
4226b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt				       MAC2STR(wpa_s->pending_join_dev_addr));
422704949598a23f501be6eec21697465fd46a28840aDmitry Shmidt			return;
422804949598a23f501be6eec21697465fd46a28840aDmitry Shmidt		}
4229b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt		wpa_msg_global(wpa_s->parent, MSG_INFO,
4230b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt			       P2P_EVENT_GROUP_FORMATION_FAILURE);
42318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
42328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt}
42338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
42348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
423504949598a23f501be6eec21697465fd46a28840aDmitry Shmidtstatic int wpas_check_freq_conflict(struct wpa_supplicant *wpa_s, int freq)
423604949598a23f501be6eec21697465fd46a28840aDmitry Shmidt{
423743cb578dfe2c492257636f6234a24178ed27789eDmitry Shmidt	int res;
423843cb578dfe2c492257636f6234a24178ed27789eDmitry Shmidt	unsigned int num, i;
423943cb578dfe2c492257636f6234a24178ed27789eDmitry Shmidt	struct wpa_used_freq_data *freqs;
424004949598a23f501be6eec21697465fd46a28840aDmitry Shmidt
4241c2ebb4b85d69b65f552fee71ac68f44e8d87b39eDmitry Shmidt	if (wpas_p2p_num_unused_channels(wpa_s) > 0) {
4242c2ebb4b85d69b65f552fee71ac68f44e8d87b39eDmitry Shmidt		/* Multiple channels are supported and not all are in use */
424304949598a23f501be6eec21697465fd46a28840aDmitry Shmidt		return 0;
4244c2ebb4b85d69b65f552fee71ac68f44e8d87b39eDmitry Shmidt	}
424504949598a23f501be6eec21697465fd46a28840aDmitry Shmidt
424643cb578dfe2c492257636f6234a24178ed27789eDmitry Shmidt	freqs = os_calloc(wpa_s->num_multichan_concurrent,
424743cb578dfe2c492257636f6234a24178ed27789eDmitry Shmidt			  sizeof(struct wpa_used_freq_data));
4248c2ebb4b85d69b65f552fee71ac68f44e8d87b39eDmitry Shmidt	if (!freqs)
4249c2ebb4b85d69b65f552fee71ac68f44e8d87b39eDmitry Shmidt		return 1;
425004949598a23f501be6eec21697465fd46a28840aDmitry Shmidt
4251c2ebb4b85d69b65f552fee71ac68f44e8d87b39eDmitry Shmidt	num = wpas_p2p_valid_oper_freqs(wpa_s, freqs,
4252c2ebb4b85d69b65f552fee71ac68f44e8d87b39eDmitry Shmidt					wpa_s->num_multichan_concurrent);
425304949598a23f501be6eec21697465fd46a28840aDmitry Shmidt
4254c2ebb4b85d69b65f552fee71ac68f44e8d87b39eDmitry Shmidt	for (i = 0; i < num; i++) {
425543cb578dfe2c492257636f6234a24178ed27789eDmitry Shmidt		if (freqs[i].freq == freq) {
4256c2ebb4b85d69b65f552fee71ac68f44e8d87b39eDmitry Shmidt			wpa_printf(MSG_DEBUG, "P2P: Frequency %d MHz in use by another virtual interface and can be used",
4257c2ebb4b85d69b65f552fee71ac68f44e8d87b39eDmitry Shmidt				   freq);
4258c2ebb4b85d69b65f552fee71ac68f44e8d87b39eDmitry Shmidt			res = 0;
4259c2ebb4b85d69b65f552fee71ac68f44e8d87b39eDmitry Shmidt			goto exit_free;
4260c2ebb4b85d69b65f552fee71ac68f44e8d87b39eDmitry Shmidt		}
426104949598a23f501be6eec21697465fd46a28840aDmitry Shmidt	}
426204949598a23f501be6eec21697465fd46a28840aDmitry Shmidt
426343cb578dfe2c492257636f6234a24178ed27789eDmitry Shmidt	wpa_printf(MSG_DEBUG, "P2P: No valid operating frequencies");
4264c2ebb4b85d69b65f552fee71ac68f44e8d87b39eDmitry Shmidt	res = 1;
4265c2ebb4b85d69b65f552fee71ac68f44e8d87b39eDmitry Shmidt
4266c2ebb4b85d69b65f552fee71ac68f44e8d87b39eDmitry Shmidtexit_free:
4267c2ebb4b85d69b65f552fee71ac68f44e8d87b39eDmitry Shmidt	os_free(freqs);
4268c2ebb4b85d69b65f552fee71ac68f44e8d87b39eDmitry Shmidt	return res;
426904949598a23f501be6eec21697465fd46a28840aDmitry Shmidt}
427004949598a23f501be6eec21697465fd46a28840aDmitry Shmidt
427104949598a23f501be6eec21697465fd46a28840aDmitry Shmidt
427204949598a23f501be6eec21697465fd46a28840aDmitry Shmidtstatic int wpas_p2p_peer_go(struct wpa_supplicant *wpa_s,
427304949598a23f501be6eec21697465fd46a28840aDmitry Shmidt			    const u8 *peer_dev_addr)
427404949598a23f501be6eec21697465fd46a28840aDmitry Shmidt{
427504949598a23f501be6eec21697465fd46a28840aDmitry Shmidt	struct wpa_bss *bss;
427604949598a23f501be6eec21697465fd46a28840aDmitry Shmidt	int updated;
427704949598a23f501be6eec21697465fd46a28840aDmitry Shmidt
427804949598a23f501be6eec21697465fd46a28840aDmitry Shmidt	bss = wpa_bss_get_p2p_dev_addr(wpa_s, peer_dev_addr);
427904949598a23f501be6eec21697465fd46a28840aDmitry Shmidt	if (bss == NULL)
428004949598a23f501be6eec21697465fd46a28840aDmitry Shmidt		return -1;
428104949598a23f501be6eec21697465fd46a28840aDmitry Shmidt	if (bss->last_update_idx < wpa_s->bss_update_idx) {
428204949598a23f501be6eec21697465fd46a28840aDmitry Shmidt		wpa_printf(MSG_DEBUG, "P2P: Peer BSS entry not updated in the "
428304949598a23f501be6eec21697465fd46a28840aDmitry Shmidt			   "last scan");
428404949598a23f501be6eec21697465fd46a28840aDmitry Shmidt		return 0;
428504949598a23f501be6eec21697465fd46a28840aDmitry Shmidt	}
428604949598a23f501be6eec21697465fd46a28840aDmitry Shmidt
4287fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt	updated = os_reltime_before(&wpa_s->p2p_auto_started,
4288fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt				    &bss->last_update);
428904949598a23f501be6eec21697465fd46a28840aDmitry Shmidt	wpa_printf(MSG_DEBUG, "P2P: Current BSS entry for peer updated at "
429004949598a23f501be6eec21697465fd46a28840aDmitry Shmidt		   "%ld.%06ld (%supdated in last scan)",
429104949598a23f501be6eec21697465fd46a28840aDmitry Shmidt		   bss->last_update.sec, bss->last_update.usec,
429204949598a23f501be6eec21697465fd46a28840aDmitry Shmidt		   updated ? "": "not ");
429304949598a23f501be6eec21697465fd46a28840aDmitry Shmidt
429404949598a23f501be6eec21697465fd46a28840aDmitry Shmidt	return updated;
429504949598a23f501be6eec21697465fd46a28840aDmitry Shmidt}
429604949598a23f501be6eec21697465fd46a28840aDmitry Shmidt
429704949598a23f501be6eec21697465fd46a28840aDmitry Shmidt
42988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic void wpas_p2p_scan_res_join(struct wpa_supplicant *wpa_s,
42998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt				   struct wpa_scan_results *scan_res)
43008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{
4301344abd362cfe2d03ed956666527352826b67bde5Dmitry Shmidt	struct wpa_bss *bss = NULL;
43028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	int freq;
43038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	u8 iface_addr[ETH_ALEN];
430404949598a23f501be6eec21697465fd46a28840aDmitry Shmidt
43058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	eloop_cancel_timeout(wpas_p2p_join_scan, wpa_s, NULL);
43068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
43078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (wpa_s->global->p2p_disabled)
43088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return;
43098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
431004949598a23f501be6eec21697465fd46a28840aDmitry Shmidt	wpa_printf(MSG_DEBUG, "P2P: Scan results received (%d BSS) for %sjoin",
431104949598a23f501be6eec21697465fd46a28840aDmitry Shmidt		   scan_res ? (int) scan_res->num : -1,
431204949598a23f501be6eec21697465fd46a28840aDmitry Shmidt		   wpa_s->p2p_auto_join ? "auto_" : "");
43138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
43148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (scan_res)
43158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		wpas_p2p_scan_res_handler(wpa_s, scan_res);
43168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
431704949598a23f501be6eec21697465fd46a28840aDmitry Shmidt	if (wpa_s->p2p_auto_pd) {
431804949598a23f501be6eec21697465fd46a28840aDmitry Shmidt		int join = wpas_p2p_peer_go(wpa_s,
431904949598a23f501be6eec21697465fd46a28840aDmitry Shmidt					    wpa_s->pending_join_dev_addr);
432004949598a23f501be6eec21697465fd46a28840aDmitry Shmidt		if (join == 0 &&
432104949598a23f501be6eec21697465fd46a28840aDmitry Shmidt		    wpa_s->auto_pd_scan_retry < P2P_AUTO_PD_SCAN_ATTEMPTS) {
432204949598a23f501be6eec21697465fd46a28840aDmitry Shmidt			wpa_s->auto_pd_scan_retry++;
4323444d567b27731d8572ef37697dd12fd1c37c2f24Dmitry Shmidt			bss = wpa_bss_get_bssid_latest(
4324444d567b27731d8572ef37697dd12fd1c37c2f24Dmitry Shmidt				wpa_s, wpa_s->pending_join_dev_addr);
432504949598a23f501be6eec21697465fd46a28840aDmitry Shmidt			if (bss) {
432604949598a23f501be6eec21697465fd46a28840aDmitry Shmidt				freq = bss->freq;
432704949598a23f501be6eec21697465fd46a28840aDmitry Shmidt				wpa_printf(MSG_DEBUG, "P2P: Scan retry %d for "
432804949598a23f501be6eec21697465fd46a28840aDmitry Shmidt					   "the peer " MACSTR " at %d MHz",
432904949598a23f501be6eec21697465fd46a28840aDmitry Shmidt					   wpa_s->auto_pd_scan_retry,
433004949598a23f501be6eec21697465fd46a28840aDmitry Shmidt					   MAC2STR(wpa_s->
433104949598a23f501be6eec21697465fd46a28840aDmitry Shmidt						   pending_join_dev_addr),
433204949598a23f501be6eec21697465fd46a28840aDmitry Shmidt					   freq);
4333344abd362cfe2d03ed956666527352826b67bde5Dmitry Shmidt				wpas_p2p_join_scan_req(wpa_s, freq, NULL, 0);
433404949598a23f501be6eec21697465fd46a28840aDmitry Shmidt				return;
433504949598a23f501be6eec21697465fd46a28840aDmitry Shmidt			}
433604949598a23f501be6eec21697465fd46a28840aDmitry Shmidt		}
433704949598a23f501be6eec21697465fd46a28840aDmitry Shmidt
433804949598a23f501be6eec21697465fd46a28840aDmitry Shmidt		if (join < 0)
433904949598a23f501be6eec21697465fd46a28840aDmitry Shmidt			join = 0;
434004949598a23f501be6eec21697465fd46a28840aDmitry Shmidt
434104949598a23f501be6eec21697465fd46a28840aDmitry Shmidt		wpa_s->p2p_auto_pd = 0;
434204949598a23f501be6eec21697465fd46a28840aDmitry Shmidt		wpa_s->pending_pd_use = join ? AUTO_PD_JOIN : AUTO_PD_GO_NEG;
434304949598a23f501be6eec21697465fd46a28840aDmitry Shmidt		wpa_printf(MSG_DEBUG, "P2P: Auto PD with " MACSTR " join=%d",
434404949598a23f501be6eec21697465fd46a28840aDmitry Shmidt			   MAC2STR(wpa_s->pending_join_dev_addr), join);
434504949598a23f501be6eec21697465fd46a28840aDmitry Shmidt		if (p2p_prov_disc_req(wpa_s->global->p2p,
4346216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt				      wpa_s->pending_join_dev_addr, NULL,
434704949598a23f501be6eec21697465fd46a28840aDmitry Shmidt				      wpa_s->pending_pd_config_methods, join,
4348d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt				      0, wpa_s->user_initiated_pd) < 0) {
434904949598a23f501be6eec21697465fd46a28840aDmitry Shmidt			wpa_s->p2p_auto_pd = 0;
4350b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt			wpa_msg_global(wpa_s, MSG_INFO,
4351b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt				       P2P_EVENT_PROV_DISC_FAILURE
4352b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt				       " p2p_dev_addr=" MACSTR " status=N/A",
4353b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt				       MAC2STR(wpa_s->pending_join_dev_addr));
435404949598a23f501be6eec21697465fd46a28840aDmitry Shmidt		}
435504949598a23f501be6eec21697465fd46a28840aDmitry Shmidt		return;
435604949598a23f501be6eec21697465fd46a28840aDmitry Shmidt	}
435704949598a23f501be6eec21697465fd46a28840aDmitry Shmidt
435804949598a23f501be6eec21697465fd46a28840aDmitry Shmidt	if (wpa_s->p2p_auto_join) {
435904949598a23f501be6eec21697465fd46a28840aDmitry Shmidt		int join = wpas_p2p_peer_go(wpa_s,
436004949598a23f501be6eec21697465fd46a28840aDmitry Shmidt					    wpa_s->pending_join_dev_addr);
436104949598a23f501be6eec21697465fd46a28840aDmitry Shmidt		if (join < 0) {
436204949598a23f501be6eec21697465fd46a28840aDmitry Shmidt			wpa_printf(MSG_DEBUG, "P2P: Peer was not found to be "
436304949598a23f501be6eec21697465fd46a28840aDmitry Shmidt				   "running a GO -> use GO Negotiation");
43647f65602d49069f96a7bb44da8bd79ffe8d4c6a98Dmitry Shmidt			wpa_msg_global(wpa_s->parent, MSG_INFO,
43657f65602d49069f96a7bb44da8bd79ffe8d4c6a98Dmitry Shmidt				       P2P_EVENT_FALLBACK_TO_GO_NEG
43667f65602d49069f96a7bb44da8bd79ffe8d4c6a98Dmitry Shmidt				       "reason=peer-not-running-GO");
436704949598a23f501be6eec21697465fd46a28840aDmitry Shmidt			wpas_p2p_connect(wpa_s, wpa_s->pending_join_dev_addr,
436804949598a23f501be6eec21697465fd46a28840aDmitry Shmidt					 wpa_s->p2p_pin, wpa_s->p2p_wps_method,
436904949598a23f501be6eec21697465fd46a28840aDmitry Shmidt					 wpa_s->p2p_persistent_group, 0, 0, 0,
437004949598a23f501be6eec21697465fd46a28840aDmitry Shmidt					 wpa_s->p2p_go_intent,
437104949598a23f501be6eec21697465fd46a28840aDmitry Shmidt					 wpa_s->p2p_connect_freq,
437204949598a23f501be6eec21697465fd46a28840aDmitry Shmidt					 wpa_s->p2p_persistent_id,
437361d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt					 wpa_s->p2p_pd_before_go_neg,
437468d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt					 wpa_s->p2p_go_ht40,
437568d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt					 wpa_s->p2p_go_vht);
437604949598a23f501be6eec21697465fd46a28840aDmitry Shmidt			return;
437704949598a23f501be6eec21697465fd46a28840aDmitry Shmidt		}
437804949598a23f501be6eec21697465fd46a28840aDmitry Shmidt
437904949598a23f501be6eec21697465fd46a28840aDmitry Shmidt		wpa_printf(MSG_DEBUG, "P2P: Peer was found running GO%s -> "
438004949598a23f501be6eec21697465fd46a28840aDmitry Shmidt			   "try to join the group", join ? "" :
438104949598a23f501be6eec21697465fd46a28840aDmitry Shmidt			   " in older scan");
43827f65602d49069f96a7bb44da8bd79ffe8d4c6a98Dmitry Shmidt		if (!join) {
43837f65602d49069f96a7bb44da8bd79ffe8d4c6a98Dmitry Shmidt			wpa_msg_global(wpa_s->parent, MSG_INFO,
43847f65602d49069f96a7bb44da8bd79ffe8d4c6a98Dmitry Shmidt				       P2P_EVENT_FALLBACK_TO_GO_NEG_ENABLED);
438504949598a23f501be6eec21697465fd46a28840aDmitry Shmidt			wpa_s->p2p_fallback_to_go_neg = 1;
43867f65602d49069f96a7bb44da8bd79ffe8d4c6a98Dmitry Shmidt		}
438704949598a23f501be6eec21697465fd46a28840aDmitry Shmidt	}
438804949598a23f501be6eec21697465fd46a28840aDmitry Shmidt
43898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	freq = p2p_get_oper_freq(wpa_s->global->p2p,
43908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt				 wpa_s->pending_join_iface_addr);
43918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (freq < 0 &&
43928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	    p2p_get_interface_addr(wpa_s->global->p2p,
43938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt				   wpa_s->pending_join_dev_addr,
43948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt				   iface_addr) == 0 &&
4395661b4f78e48c697429dc46154a4125892c001718Dmitry Shmidt	    os_memcmp(iface_addr, wpa_s->pending_join_dev_addr, ETH_ALEN) != 0
4396661b4f78e48c697429dc46154a4125892c001718Dmitry Shmidt	    && !wpa_bss_get_bssid(wpa_s, wpa_s->pending_join_iface_addr)) {
43978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		wpa_printf(MSG_DEBUG, "P2P: Overwrite pending interface "
43988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			   "address for join from " MACSTR " to " MACSTR
43998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			   " based on newly discovered P2P peer entry",
44008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			   MAC2STR(wpa_s->pending_join_iface_addr),
44018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			   MAC2STR(iface_addr));
44028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		os_memcpy(wpa_s->pending_join_iface_addr, iface_addr,
44038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			  ETH_ALEN);
44048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
44058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		freq = p2p_get_oper_freq(wpa_s->global->p2p,
44068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt					 wpa_s->pending_join_iface_addr);
44078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
44088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (freq >= 0) {
44098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		wpa_printf(MSG_DEBUG, "P2P: Target GO operating frequency "
44108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			   "from P2P peer table: %d MHz", freq);
44118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
4412344abd362cfe2d03ed956666527352826b67bde5Dmitry Shmidt	if (wpa_s->p2p_join_ssid_len) {
4413344abd362cfe2d03ed956666527352826b67bde5Dmitry Shmidt		wpa_printf(MSG_DEBUG, "P2P: Trying to find target GO BSS entry based on BSSID "
4414344abd362cfe2d03ed956666527352826b67bde5Dmitry Shmidt			   MACSTR " and SSID %s",
4415344abd362cfe2d03ed956666527352826b67bde5Dmitry Shmidt			   MAC2STR(wpa_s->pending_join_iface_addr),
4416344abd362cfe2d03ed956666527352826b67bde5Dmitry Shmidt			   wpa_ssid_txt(wpa_s->p2p_join_ssid,
4417344abd362cfe2d03ed956666527352826b67bde5Dmitry Shmidt					wpa_s->p2p_join_ssid_len));
4418344abd362cfe2d03ed956666527352826b67bde5Dmitry Shmidt		bss = wpa_bss_get(wpa_s, wpa_s->pending_join_iface_addr,
4419344abd362cfe2d03ed956666527352826b67bde5Dmitry Shmidt				  wpa_s->p2p_join_ssid,
4420344abd362cfe2d03ed956666527352826b67bde5Dmitry Shmidt				  wpa_s->p2p_join_ssid_len);
4421344abd362cfe2d03ed956666527352826b67bde5Dmitry Shmidt	}
4422344abd362cfe2d03ed956666527352826b67bde5Dmitry Shmidt	if (!bss) {
4423344abd362cfe2d03ed956666527352826b67bde5Dmitry Shmidt		wpa_printf(MSG_DEBUG, "P2P: Trying to find target GO BSS entry based on BSSID "
4424344abd362cfe2d03ed956666527352826b67bde5Dmitry Shmidt			   MACSTR, MAC2STR(wpa_s->pending_join_iface_addr));
4425344abd362cfe2d03ed956666527352826b67bde5Dmitry Shmidt		bss = wpa_bss_get_bssid_latest(wpa_s,
4426344abd362cfe2d03ed956666527352826b67bde5Dmitry Shmidt					       wpa_s->pending_join_iface_addr);
4427344abd362cfe2d03ed956666527352826b67bde5Dmitry Shmidt	}
44288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (bss) {
4429a3dc30964aa24aea2b518246f6812663a1103490Dmitry Shmidt		u8 dev_addr[ETH_ALEN];
4430a3dc30964aa24aea2b518246f6812663a1103490Dmitry Shmidt
44318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		freq = bss->freq;
44328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		wpa_printf(MSG_DEBUG, "P2P: Target GO operating frequency "
4433051af73b8f8014eff33330aead0f36944b3403e6Dmitry Shmidt			   "from BSS table: %d MHz (SSID %s)", freq,
4434051af73b8f8014eff33330aead0f36944b3403e6Dmitry Shmidt			   wpa_ssid_txt(bss->ssid, bss->ssid_len));
4435a3dc30964aa24aea2b518246f6812663a1103490Dmitry Shmidt		if (p2p_parse_dev_addr((const u8 *) (bss + 1), bss->ie_len,
4436a3dc30964aa24aea2b518246f6812663a1103490Dmitry Shmidt				       dev_addr) == 0 &&
4437a3dc30964aa24aea2b518246f6812663a1103490Dmitry Shmidt		    os_memcmp(wpa_s->pending_join_dev_addr,
4438a3dc30964aa24aea2b518246f6812663a1103490Dmitry Shmidt			      wpa_s->pending_join_iface_addr, ETH_ALEN) == 0 &&
4439a3dc30964aa24aea2b518246f6812663a1103490Dmitry Shmidt		    os_memcmp(dev_addr, wpa_s->pending_join_dev_addr,
4440a3dc30964aa24aea2b518246f6812663a1103490Dmitry Shmidt			      ETH_ALEN) != 0) {
4441a3dc30964aa24aea2b518246f6812663a1103490Dmitry Shmidt			wpa_printf(MSG_DEBUG,
4442a3dc30964aa24aea2b518246f6812663a1103490Dmitry Shmidt				   "P2P: Update target GO device address based on BSS entry: " MACSTR " (was " MACSTR ")",
4443a3dc30964aa24aea2b518246f6812663a1103490Dmitry Shmidt				   MAC2STR(dev_addr),
4444a3dc30964aa24aea2b518246f6812663a1103490Dmitry Shmidt				   MAC2STR(wpa_s->pending_join_dev_addr));
4445a3dc30964aa24aea2b518246f6812663a1103490Dmitry Shmidt			os_memcpy(wpa_s->pending_join_dev_addr, dev_addr,
4446a3dc30964aa24aea2b518246f6812663a1103490Dmitry Shmidt				  ETH_ALEN);
4447a3dc30964aa24aea2b518246f6812663a1103490Dmitry Shmidt		}
44488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
44498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (freq > 0) {
44508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		u16 method;
44518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
445204949598a23f501be6eec21697465fd46a28840aDmitry Shmidt		if (wpas_check_freq_conflict(wpa_s, freq) > 0) {
4453b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt			wpa_msg_global(wpa_s->parent, MSG_INFO,
4454b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt				       P2P_EVENT_GROUP_FORMATION_FAILURE
4455b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt				       "reason=FREQ_CONFLICT");
445604949598a23f501be6eec21697465fd46a28840aDmitry Shmidt			return;
445704949598a23f501be6eec21697465fd46a28840aDmitry Shmidt		}
445804949598a23f501be6eec21697465fd46a28840aDmitry Shmidt
44598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		wpa_printf(MSG_DEBUG, "P2P: Send Provision Discovery Request "
44608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			   "prior to joining an existing group (GO " MACSTR
44618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			   " freq=%u MHz)",
44628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			   MAC2STR(wpa_s->pending_join_dev_addr), freq);
44638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		wpa_s->pending_pd_before_join = 1;
44648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
44658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		switch (wpa_s->pending_join_wps_method) {
44668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		case WPS_PIN_DISPLAY:
44678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			method = WPS_CONFIG_KEYPAD;
44688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			break;
44698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		case WPS_PIN_KEYPAD:
44708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			method = WPS_CONFIG_DISPLAY;
44718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			break;
44728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		case WPS_PBC:
44738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			method = WPS_CONFIG_PUSHBUTTON;
44748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			break;
44758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		default:
44768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			method = 0;
44778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			break;
44788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		}
44798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
44801f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt		if ((p2p_get_provisioning_info(wpa_s->global->p2p,
44811f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt					       wpa_s->pending_join_dev_addr) ==
44821f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt		     method)) {
44831f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt			/*
44841f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt			 * We have already performed provision discovery for
44851f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt			 * joining the group. Proceed directly to join
44861f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt			 * operation without duplicated provision discovery. */
44871f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt			wpa_printf(MSG_DEBUG, "P2P: Provision discovery "
44881f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt				   "with " MACSTR " already done - proceed to "
44891f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt				   "join",
44901f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt				   MAC2STR(wpa_s->pending_join_dev_addr));
44911f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt			wpa_s->pending_pd_before_join = 0;
44921f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt			goto start;
44931f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt		}
44941f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt
44958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		if (p2p_prov_disc_req(wpa_s->global->p2p,
4496216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt				      wpa_s->pending_join_dev_addr,
4497216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt				      NULL, method, 1,
4498d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt				      freq, wpa_s->user_initiated_pd) < 0) {
44998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			wpa_printf(MSG_DEBUG, "P2P: Failed to send Provision "
45008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt				   "Discovery Request before joining an "
45018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt				   "existing group");
45028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			wpa_s->pending_pd_before_join = 0;
45038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			goto start;
45048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		}
45058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return;
45068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
45078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
45088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	wpa_printf(MSG_DEBUG, "P2P: Failed to find BSS/GO - try again later");
45098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	eloop_cancel_timeout(wpas_p2p_join_scan, wpa_s, NULL);
45108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	eloop_register_timeout(1, 0, wpas_p2p_join_scan, wpa_s, NULL);
45118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	wpas_p2p_check_join_scan_limit(wpa_s);
45128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	return;
45138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
45148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstart:
45158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	/* Start join operation immediately */
4516cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt	wpas_p2p_join_start(wpa_s, 0, NULL, 0);
45178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt}
45188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
45198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
4520344abd362cfe2d03ed956666527352826b67bde5Dmitry Shmidtstatic void wpas_p2p_join_scan_req(struct wpa_supplicant *wpa_s, int freq,
4521344abd362cfe2d03ed956666527352826b67bde5Dmitry Shmidt				   const u8 *ssid, size_t ssid_len)
45228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{
45238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	int ret;
45248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	struct wpa_driver_scan_params params;
45258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	struct wpabuf *wps_ie, *ies;
45261f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt	size_t ielen;
452704949598a23f501be6eec21697465fd46a28840aDmitry Shmidt	int freqs[2] = { 0, 0 };
45288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
45298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	os_memset(&params, 0, sizeof(params));
45308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
45318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	/* P2P Wildcard SSID */
45328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	params.num_ssids = 1;
4533344abd362cfe2d03ed956666527352826b67bde5Dmitry Shmidt	if (ssid && ssid_len) {
4534344abd362cfe2d03ed956666527352826b67bde5Dmitry Shmidt		params.ssids[0].ssid = ssid;
4535344abd362cfe2d03ed956666527352826b67bde5Dmitry Shmidt		params.ssids[0].ssid_len = ssid_len;
4536344abd362cfe2d03ed956666527352826b67bde5Dmitry Shmidt		os_memcpy(wpa_s->p2p_join_ssid, ssid, ssid_len);
4537344abd362cfe2d03ed956666527352826b67bde5Dmitry Shmidt		wpa_s->p2p_join_ssid_len = ssid_len;
4538344abd362cfe2d03ed956666527352826b67bde5Dmitry Shmidt	} else {
4539344abd362cfe2d03ed956666527352826b67bde5Dmitry Shmidt		params.ssids[0].ssid = (u8 *) P2P_WILDCARD_SSID;
4540344abd362cfe2d03ed956666527352826b67bde5Dmitry Shmidt		params.ssids[0].ssid_len = P2P_WILDCARD_SSID_LEN;
4541344abd362cfe2d03ed956666527352826b67bde5Dmitry Shmidt		wpa_s->p2p_join_ssid_len = 0;
4542344abd362cfe2d03ed956666527352826b67bde5Dmitry Shmidt	}
45438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
45448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	wpa_s->wps->dev.p2p = 1;
454504949598a23f501be6eec21697465fd46a28840aDmitry Shmidt	wps_ie = wps_build_probe_req_ie(DEV_PW_DEFAULT, &wpa_s->wps->dev,
454604949598a23f501be6eec21697465fd46a28840aDmitry Shmidt					wpa_s->wps->uuid, WPS_REQ_ENROLLEE, 0,
454704949598a23f501be6eec21697465fd46a28840aDmitry Shmidt					NULL);
45488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (wps_ie == NULL) {
45498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		wpas_p2p_scan_res_join(wpa_s, NULL);
45508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return;
45518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
45528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
45531f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt	ielen = p2p_scan_ie_buf_len(wpa_s->global->p2p);
45541f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt	ies = wpabuf_alloc(wpabuf_len(wps_ie) + ielen);
45558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (ies == NULL) {
45568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		wpabuf_free(wps_ie);
45578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		wpas_p2p_scan_res_join(wpa_s, NULL);
45588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return;
45598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
45608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	wpabuf_put_buf(ies, wps_ie);
45618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	wpabuf_free(wps_ie);
45628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
4563c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt	p2p_scan_ie(wpa_s->global->p2p, ies, NULL);
45648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
45651f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt	params.p2p_probe = 1;
45668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	params.extra_ies = wpabuf_head(ies);
45678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	params.extra_ies_len = wpabuf_len(ies);
45689e3f8ee32a0c11c56b11985805b5492d04886a99Dmitry Shmidt
45699e3f8ee32a0c11c56b11985805b5492d04886a99Dmitry Shmidt	if (!freq) {
45709e3f8ee32a0c11c56b11985805b5492d04886a99Dmitry Shmidt		int oper_freq;
45719e3f8ee32a0c11c56b11985805b5492d04886a99Dmitry Shmidt		/*
45729e3f8ee32a0c11c56b11985805b5492d04886a99Dmitry Shmidt		 * If freq is not provided, check the operating freq of the GO
45739e3f8ee32a0c11c56b11985805b5492d04886a99Dmitry Shmidt		 * and use a single channel scan on if possible.
45749e3f8ee32a0c11c56b11985805b5492d04886a99Dmitry Shmidt		 */
45759e3f8ee32a0c11c56b11985805b5492d04886a99Dmitry Shmidt		oper_freq = p2p_get_oper_freq(wpa_s->global->p2p,
45769e3f8ee32a0c11c56b11985805b5492d04886a99Dmitry Shmidt					      wpa_s->pending_join_iface_addr);
45779e3f8ee32a0c11c56b11985805b5492d04886a99Dmitry Shmidt		if (oper_freq > 0)
45789e3f8ee32a0c11c56b11985805b5492d04886a99Dmitry Shmidt			freq = oper_freq;
45799e3f8ee32a0c11c56b11985805b5492d04886a99Dmitry Shmidt	}
458004949598a23f501be6eec21697465fd46a28840aDmitry Shmidt	if (freq > 0) {
458104949598a23f501be6eec21697465fd46a28840aDmitry Shmidt		freqs[0] = freq;
458204949598a23f501be6eec21697465fd46a28840aDmitry Shmidt		params.freqs = freqs;
458304949598a23f501be6eec21697465fd46a28840aDmitry Shmidt	}
45848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
45858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	/*
45868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	 * Run a scan to update BSS table and start Provision Discovery once
45878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	 * the new scan results become available.
45888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	 */
45891f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt	ret = wpa_drv_scan(wpa_s, &params);
4590444d567b27731d8572ef37697dd12fd1c37c2f24Dmitry Shmidt	if (!ret) {
4591fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt		os_get_reltime(&wpa_s->scan_trigger_time);
459204949598a23f501be6eec21697465fd46a28840aDmitry Shmidt		wpa_s->scan_res_handler = wpas_p2p_scan_res_join;
4593fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt		wpa_s->own_scan_requested = 1;
4594444d567b27731d8572ef37697dd12fd1c37c2f24Dmitry Shmidt	}
45958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
45968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	wpabuf_free(ies);
45978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
45988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (ret) {
45998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		wpa_printf(MSG_DEBUG, "P2P: Failed to start scan for join - "
46008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			   "try again later");
46018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		eloop_cancel_timeout(wpas_p2p_join_scan, wpa_s, NULL);
46028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		eloop_register_timeout(1, 0, wpas_p2p_join_scan, wpa_s, NULL);
46038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		wpas_p2p_check_join_scan_limit(wpa_s);
46048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
46058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt}
46068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
46078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
460804949598a23f501be6eec21697465fd46a28840aDmitry Shmidtstatic void wpas_p2p_join_scan(void *eloop_ctx, void *timeout_ctx)
460904949598a23f501be6eec21697465fd46a28840aDmitry Shmidt{
461004949598a23f501be6eec21697465fd46a28840aDmitry Shmidt	struct wpa_supplicant *wpa_s = eloop_ctx;
4611344abd362cfe2d03ed956666527352826b67bde5Dmitry Shmidt	wpas_p2p_join_scan_req(wpa_s, 0, NULL, 0);
461204949598a23f501be6eec21697465fd46a28840aDmitry Shmidt}
461304949598a23f501be6eec21697465fd46a28840aDmitry Shmidt
461404949598a23f501be6eec21697465fd46a28840aDmitry Shmidt
46158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic int wpas_p2p_join(struct wpa_supplicant *wpa_s, const u8 *iface_addr,
461604949598a23f501be6eec21697465fd46a28840aDmitry Shmidt			 const u8 *dev_addr, enum p2p_wps_method wps_method,
4617cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt			 int auto_join, int op_freq,
4618cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt			 const u8 *ssid, size_t ssid_len)
46198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{
46208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	wpa_printf(MSG_DEBUG, "P2P: Request to join existing group (iface "
4621cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt		   MACSTR " dev " MACSTR " op_freq=%d)%s",
4622cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt		   MAC2STR(iface_addr), MAC2STR(dev_addr), op_freq,
462304949598a23f501be6eec21697465fd46a28840aDmitry Shmidt		   auto_join ? " (auto_join)" : "");
4624344abd362cfe2d03ed956666527352826b67bde5Dmitry Shmidt	if (ssid && ssid_len) {
4625344abd362cfe2d03ed956666527352826b67bde5Dmitry Shmidt		wpa_printf(MSG_DEBUG, "P2P: Group SSID specified: %s",
4626344abd362cfe2d03ed956666527352826b67bde5Dmitry Shmidt			   wpa_ssid_txt(ssid, ssid_len));
4627344abd362cfe2d03ed956666527352826b67bde5Dmitry Shmidt	}
46288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
462904949598a23f501be6eec21697465fd46a28840aDmitry Shmidt	wpa_s->p2p_auto_pd = 0;
463004949598a23f501be6eec21697465fd46a28840aDmitry Shmidt	wpa_s->p2p_auto_join = !!auto_join;
46318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	os_memcpy(wpa_s->pending_join_iface_addr, iface_addr, ETH_ALEN);
46328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	os_memcpy(wpa_s->pending_join_dev_addr, dev_addr, ETH_ALEN);
46338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	wpa_s->pending_join_wps_method = wps_method;
46348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
46358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	/* Make sure we are not running find during connection establishment */
46368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	wpas_p2p_stop_find(wpa_s);
46378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
46388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	wpa_s->p2p_join_scan_count = 0;
4639cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt	wpas_p2p_join_scan_req(wpa_s, op_freq, ssid, ssid_len);
46408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	return 0;
46418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt}
46428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
46438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
4644cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidtstatic int wpas_p2p_join_start(struct wpa_supplicant *wpa_s, int freq,
4645cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt			       const u8 *ssid, size_t ssid_len)
46468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{
46478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	struct wpa_supplicant *group;
46488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	struct p2p_go_neg_results res;
464904949598a23f501be6eec21697465fd46a28840aDmitry Shmidt	struct wpa_bss *bss;
46508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
46518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	group = wpas_p2p_get_group_iface(wpa_s, 0, 0);
46528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (group == NULL)
46538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return -1;
46548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (group != wpa_s) {
46558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		os_memcpy(group->p2p_pin, wpa_s->p2p_pin,
46568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			  sizeof(group->p2p_pin));
46578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		group->p2p_wps_method = wpa_s->p2p_wps_method;
46584b9d52f502481b258fec743c03a5e957e5605afcDmitry Shmidt	} else {
46594b9d52f502481b258fec743c03a5e957e5605afcDmitry Shmidt		/*
46604b9d52f502481b258fec743c03a5e957e5605afcDmitry Shmidt		 * Need to mark the current interface for p2p_group_formation
46614b9d52f502481b258fec743c03a5e957e5605afcDmitry Shmidt		 * when a separate group interface is not used. This is needed
46624b9d52f502481b258fec743c03a5e957e5605afcDmitry Shmidt		 * to allow p2p_cancel stop a pending p2p_connect-join.
46634b9d52f502481b258fec743c03a5e957e5605afcDmitry Shmidt		 * wpas_p2p_init_group_interface() addresses this for the case
46644b9d52f502481b258fec743c03a5e957e5605afcDmitry Shmidt		 * where a separate group interface is used.
46654b9d52f502481b258fec743c03a5e957e5605afcDmitry Shmidt		 */
46664b9d52f502481b258fec743c03a5e957e5605afcDmitry Shmidt		wpa_s->global->p2p_group_formation = wpa_s;
46678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
46688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
46698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	group->p2p_in_provisioning = 1;
467004949598a23f501be6eec21697465fd46a28840aDmitry Shmidt	group->p2p_fallback_to_go_neg = wpa_s->p2p_fallback_to_go_neg;
46718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
46728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	os_memset(&res, 0, sizeof(res));
4673cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt	os_memcpy(res.peer_device_addr, wpa_s->pending_join_dev_addr, ETH_ALEN);
46748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	os_memcpy(res.peer_interface_addr, wpa_s->pending_join_iface_addr,
46758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		  ETH_ALEN);
46768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	res.wps_method = wpa_s->pending_join_wps_method;
4677cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt	if (freq && ssid && ssid_len) {
4678cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt		res.freq = freq;
4679cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt		res.ssid_len = ssid_len;
4680cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt		os_memcpy(res.ssid, ssid, ssid_len);
4681cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt	} else {
4682cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt		bss = wpa_bss_get_bssid_latest(wpa_s,
4683cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt					       wpa_s->pending_join_iface_addr);
4684cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt		if (bss) {
4685cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt			res.freq = bss->freq;
4686cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt			res.ssid_len = bss->ssid_len;
4687cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt			os_memcpy(res.ssid, bss->ssid, bss->ssid_len);
4688cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt			wpa_printf(MSG_DEBUG, "P2P: Join target GO operating frequency from BSS table: %d MHz (SSID %s)",
4689cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt				   bss->freq,
4690cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt				   wpa_ssid_txt(bss->ssid, bss->ssid_len));
4691cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt		}
469204949598a23f501be6eec21697465fd46a28840aDmitry Shmidt	}
469304949598a23f501be6eec21697465fd46a28840aDmitry Shmidt
4694c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt	if (wpa_s->off_channel_freq || wpa_s->roc_waiting_drv_freq) {
4695c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt		wpa_printf(MSG_DEBUG, "P2P: Cancel remain-on-channel prior to "
4696c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt			   "starting client");
4697c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt		wpa_drv_cancel_remain_on_channel(wpa_s);
4698c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt		wpa_s->off_channel_freq = 0;
4699c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt		wpa_s->roc_waiting_drv_freq = 0;
4700c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt	}
47018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	wpas_start_wps_enrollee(group, &res);
47028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
47038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	/*
47048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	 * Allow a longer timeout for join-a-running-group than normal 15
47058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	 * second group formation timeout since the GO may not have authorized
47068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	 * our connection yet.
47078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	 */
47088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	eloop_cancel_timeout(wpas_p2p_group_formation_timeout, wpa_s, NULL);
47098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	eloop_register_timeout(60, 0, wpas_p2p_group_formation_timeout,
47108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			       wpa_s, NULL);
47118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
47128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	return 0;
47138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt}
47148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
47158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
47167a5e50a0554bee77a9da492ea3d86f46147f1671Dmitry Shmidtstatic int wpas_p2p_setup_freqs(struct wpa_supplicant *wpa_s, int freq,
471768d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt				int *force_freq, int *pref_freq, int go)
47187a5e50a0554bee77a9da492ea3d86f46147f1671Dmitry Shmidt{
471943cb578dfe2c492257636f6234a24178ed27789eDmitry Shmidt	struct wpa_used_freq_data *freqs;
472043cb578dfe2c492257636f6234a24178ed27789eDmitry Shmidt	int res, best_freq, num_unused;
4721c2ebb4b85d69b65f552fee71ac68f44e8d87b39eDmitry Shmidt	unsigned int freq_in_use = 0, num, i;
4722c2ebb4b85d69b65f552fee71ac68f44e8d87b39eDmitry Shmidt
472343cb578dfe2c492257636f6234a24178ed27789eDmitry Shmidt	freqs = os_calloc(wpa_s->num_multichan_concurrent,
472443cb578dfe2c492257636f6234a24178ed27789eDmitry Shmidt			  sizeof(struct wpa_used_freq_data));
4725c2ebb4b85d69b65f552fee71ac68f44e8d87b39eDmitry Shmidt	if (!freqs)
4726c2ebb4b85d69b65f552fee71ac68f44e8d87b39eDmitry Shmidt		return -1;
4727c2ebb4b85d69b65f552fee71ac68f44e8d87b39eDmitry Shmidt
472843cb578dfe2c492257636f6234a24178ed27789eDmitry Shmidt	num = wpas_p2p_valid_oper_freqs(wpa_s, freqs,
472943cb578dfe2c492257636f6234a24178ed27789eDmitry Shmidt					wpa_s->num_multichan_concurrent);
473043cb578dfe2c492257636f6234a24178ed27789eDmitry Shmidt
473143cb578dfe2c492257636f6234a24178ed27789eDmitry Shmidt	/*
473243cb578dfe2c492257636f6234a24178ed27789eDmitry Shmidt	 * It is possible that the total number of used frequencies is bigger
473343cb578dfe2c492257636f6234a24178ed27789eDmitry Shmidt	 * than the number of frequencies used for P2P, so get the system wide
473443cb578dfe2c492257636f6234a24178ed27789eDmitry Shmidt	 * number of unused frequencies.
473543cb578dfe2c492257636f6234a24178ed27789eDmitry Shmidt	 */
473643cb578dfe2c492257636f6234a24178ed27789eDmitry Shmidt	num_unused = wpas_p2p_num_unused_channels(wpa_s);
473743cb578dfe2c492257636f6234a24178ed27789eDmitry Shmidt
4738b7b4d0ec07161a6d76c40ba7ef1306e82fbb7e15Dmitry Shmidt	wpa_printf(MSG_DEBUG,
473943cb578dfe2c492257636f6234a24178ed27789eDmitry Shmidt		   "P2P: Setup freqs: freq=%d num_MCC=%d shared_freqs=%u num_unused=%d",
474043cb578dfe2c492257636f6234a24178ed27789eDmitry Shmidt		   freq, wpa_s->num_multichan_concurrent, num, num_unused);
4741c2ebb4b85d69b65f552fee71ac68f44e8d87b39eDmitry Shmidt
47427a5e50a0554bee77a9da492ea3d86f46147f1671Dmitry Shmidt	if (freq > 0) {
474368d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt		int ret;
474468d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt		if (go)
474568d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt			ret = p2p_supported_freq(wpa_s->global->p2p, freq);
474668d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt		else
474768d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt			ret = p2p_supported_freq_cli(wpa_s->global->p2p, freq);
474868d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt		if (!ret) {
4749203eadb9eda41a1dde4a583edb4684319e3f399eDmitry Shmidt			if ((wpa_s->drv_flags & WPA_DRIVER_FLAGS_DFS_OFFLOAD) &&
4750203eadb9eda41a1dde4a583edb4684319e3f399eDmitry Shmidt			    ieee80211_is_dfs(freq)) {
4751203eadb9eda41a1dde4a583edb4684319e3f399eDmitry Shmidt				/*
4752203eadb9eda41a1dde4a583edb4684319e3f399eDmitry Shmidt				 * If freq is a DFS channel and DFS is offloaded
4753203eadb9eda41a1dde4a583edb4684319e3f399eDmitry Shmidt				 * to the driver, allow P2P GO to use it.
4754203eadb9eda41a1dde4a583edb4684319e3f399eDmitry Shmidt				 */
4755203eadb9eda41a1dde4a583edb4684319e3f399eDmitry Shmidt				wpa_printf(MSG_DEBUG,
4756203eadb9eda41a1dde4a583edb4684319e3f399eDmitry Shmidt					   "P2P: The forced channel for GO (%u MHz) is DFS, and DFS is offloaded to the driver",
4757203eadb9eda41a1dde4a583edb4684319e3f399eDmitry Shmidt					   freq);
4758203eadb9eda41a1dde4a583edb4684319e3f399eDmitry Shmidt			} else {
4759203eadb9eda41a1dde4a583edb4684319e3f399eDmitry Shmidt				wpa_printf(MSG_DEBUG,
4760203eadb9eda41a1dde4a583edb4684319e3f399eDmitry Shmidt					   "P2P: The forced channel (%u MHz) is not supported for P2P uses",
4761203eadb9eda41a1dde4a583edb4684319e3f399eDmitry Shmidt					   freq);
4762203eadb9eda41a1dde4a583edb4684319e3f399eDmitry Shmidt				res = -3;
4763203eadb9eda41a1dde4a583edb4684319e3f399eDmitry Shmidt				goto exit_free;
4764203eadb9eda41a1dde4a583edb4684319e3f399eDmitry Shmidt			}
47657a5e50a0554bee77a9da492ea3d86f46147f1671Dmitry Shmidt		}
47667a5e50a0554bee77a9da492ea3d86f46147f1671Dmitry Shmidt
4767c2ebb4b85d69b65f552fee71ac68f44e8d87b39eDmitry Shmidt		for (i = 0; i < num; i++) {
476843cb578dfe2c492257636f6234a24178ed27789eDmitry Shmidt			if (freqs[i].freq == freq)
4769c2ebb4b85d69b65f552fee71ac68f44e8d87b39eDmitry Shmidt				freq_in_use = 1;
4770c2ebb4b85d69b65f552fee71ac68f44e8d87b39eDmitry Shmidt		}
4771c2ebb4b85d69b65f552fee71ac68f44e8d87b39eDmitry Shmidt
477243cb578dfe2c492257636f6234a24178ed27789eDmitry Shmidt		if (num_unused <= 0 && !freq_in_use) {
4773c2ebb4b85d69b65f552fee71ac68f44e8d87b39eDmitry Shmidt			wpa_printf(MSG_DEBUG, "P2P: Cannot start P2P group on %u MHz as there are no available channels",
4774c2ebb4b85d69b65f552fee71ac68f44e8d87b39eDmitry Shmidt				   freq);
4775c2ebb4b85d69b65f552fee71ac68f44e8d87b39eDmitry Shmidt			res = -2;
4776c2ebb4b85d69b65f552fee71ac68f44e8d87b39eDmitry Shmidt			goto exit_free;
47777a5e50a0554bee77a9da492ea3d86f46147f1671Dmitry Shmidt		}
47787a5e50a0554bee77a9da492ea3d86f46147f1671Dmitry Shmidt		wpa_printf(MSG_DEBUG, "P2P: Trying to force us to use the "
47797a5e50a0554bee77a9da492ea3d86f46147f1671Dmitry Shmidt			   "requested channel (%u MHz)", freq);
47807a5e50a0554bee77a9da492ea3d86f46147f1671Dmitry Shmidt		*force_freq = freq;
4781c2ebb4b85d69b65f552fee71ac68f44e8d87b39eDmitry Shmidt		goto exit_ok;
4782c2ebb4b85d69b65f552fee71ac68f44e8d87b39eDmitry Shmidt	}
4783c2ebb4b85d69b65f552fee71ac68f44e8d87b39eDmitry Shmidt
478443cb578dfe2c492257636f6234a24178ed27789eDmitry Shmidt	best_freq = wpas_p2p_pick_best_used_freq(wpa_s, freqs, num);
4785c2ebb4b85d69b65f552fee71ac68f44e8d87b39eDmitry Shmidt
478643cb578dfe2c492257636f6234a24178ed27789eDmitry Shmidt	/* We have a candidate frequency to use */
478743cb578dfe2c492257636f6234a24178ed27789eDmitry Shmidt	if (best_freq > 0) {
478843cb578dfe2c492257636f6234a24178ed27789eDmitry Shmidt		if (*pref_freq == 0 && num_unused > 0) {
4789e0e48dc666fb14a7bb60264ca87463ba7bc1fe0bDmitry Shmidt			wpa_printf(MSG_DEBUG, "P2P: Try to prefer a frequency (%u MHz) we are already using",
479043cb578dfe2c492257636f6234a24178ed27789eDmitry Shmidt				   best_freq);
479143cb578dfe2c492257636f6234a24178ed27789eDmitry Shmidt			*pref_freq = best_freq;
479251a47d533b6bf0efff06cc80195a588852a45058Dmitry Shmidt		} else {
479351a47d533b6bf0efff06cc80195a588852a45058Dmitry Shmidt			wpa_printf(MSG_DEBUG, "P2P: Try to force us to use frequency (%u MHz) which is already in use",
479443cb578dfe2c492257636f6234a24178ed27789eDmitry Shmidt				   best_freq);
479543cb578dfe2c492257636f6234a24178ed27789eDmitry Shmidt			*force_freq = best_freq;
4796c2ebb4b85d69b65f552fee71ac68f44e8d87b39eDmitry Shmidt		}
479743cb578dfe2c492257636f6234a24178ed27789eDmitry Shmidt	} else if (num_unused > 0) {
479843cb578dfe2c492257636f6234a24178ed27789eDmitry Shmidt		wpa_printf(MSG_DEBUG,
479943cb578dfe2c492257636f6234a24178ed27789eDmitry Shmidt			   "P2P: Current operating channels are not available for P2P. Try to use another channel");
480043cb578dfe2c492257636f6234a24178ed27789eDmitry Shmidt		*force_freq = 0;
480143cb578dfe2c492257636f6234a24178ed27789eDmitry Shmidt	} else {
480243cb578dfe2c492257636f6234a24178ed27789eDmitry Shmidt		wpa_printf(MSG_DEBUG,
480343cb578dfe2c492257636f6234a24178ed27789eDmitry Shmidt			   "P2P: All channels are in use and none of them are P2P enabled. Cannot start P2P group");
480443cb578dfe2c492257636f6234a24178ed27789eDmitry Shmidt		res = -2;
480543cb578dfe2c492257636f6234a24178ed27789eDmitry Shmidt		goto exit_free;
4806c2ebb4b85d69b65f552fee71ac68f44e8d87b39eDmitry Shmidt	}
4807c2ebb4b85d69b65f552fee71ac68f44e8d87b39eDmitry Shmidt
4808c2ebb4b85d69b65f552fee71ac68f44e8d87b39eDmitry Shmidtexit_ok:
4809c2ebb4b85d69b65f552fee71ac68f44e8d87b39eDmitry Shmidt	res = 0;
4810c2ebb4b85d69b65f552fee71ac68f44e8d87b39eDmitry Shmidtexit_free:
4811c2ebb4b85d69b65f552fee71ac68f44e8d87b39eDmitry Shmidt	os_free(freqs);
4812c2ebb4b85d69b65f552fee71ac68f44e8d87b39eDmitry Shmidt	return res;
48137a5e50a0554bee77a9da492ea3d86f46147f1671Dmitry Shmidt}
48147a5e50a0554bee77a9da492ea3d86f46147f1671Dmitry Shmidt
48157a5e50a0554bee77a9da492ea3d86f46147f1671Dmitry Shmidt
48168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt/**
48178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * wpas_p2p_connect - Request P2P Group Formation to be started
48188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @wpa_s: Pointer to wpa_supplicant data from wpa_supplicant_add_iface()
48198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @peer_addr: Address of the peer P2P Device
48208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @pin: PIN to use during provisioning or %NULL to indicate PBC mode
48218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @persistent_group: Whether to create a persistent group
482204949598a23f501be6eec21697465fd46a28840aDmitry Shmidt * @auto_join: Whether to select join vs. GO Negotiation automatically
48238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @join: Whether to join an existing group (as a client) instead of starting
48248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt *	Group Owner negotiation; @peer_addr is BSSID in that case
48258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @auth: Whether to only authorize the connection instead of doing that and
48268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt *	initiating Group Owner negotiation
48278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @go_intent: GO Intent or -1 to use default
48288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @freq: Frequency for the group or 0 for auto-selection
482904949598a23f501be6eec21697465fd46a28840aDmitry Shmidt * @persistent_id: Persistent group credentials to use for forcing GO
483004949598a23f501be6eec21697465fd46a28840aDmitry Shmidt *	parameters or -1 to generate new values (SSID/passphrase)
483104949598a23f501be6eec21697465fd46a28840aDmitry Shmidt * @pd: Whether to send Provision Discovery prior to GO Negotiation as an
483204949598a23f501be6eec21697465fd46a28840aDmitry Shmidt *	interoperability workaround when initiating group formation
483361d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt * @ht40: Start GO with 40 MHz channel width
483468d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt * @vht:  Start GO with VHT support
48358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * Returns: 0 or new PIN (if pin was %NULL) on success, -1 on unspecified
48368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt *	failure, -2 on failure due to channel not currently available,
48378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt *	-3 if forced channel is not supported
48388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */
48398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtint wpas_p2p_connect(struct wpa_supplicant *wpa_s, const u8 *peer_addr,
48408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		     const char *pin, enum p2p_wps_method wps_method,
484104949598a23f501be6eec21697465fd46a28840aDmitry Shmidt		     int persistent_group, int auto_join, int join, int auth,
484261d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt		     int go_intent, int freq, int persistent_id, int pd,
484368d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt		     int ht40, int vht)
48448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{
4845c2ebb4b85d69b65f552fee71ac68f44e8d87b39eDmitry Shmidt	int force_freq = 0, pref_freq = 0;
48467a5e50a0554bee77a9da492ea3d86f46147f1671Dmitry Shmidt	int ret = 0, res;
48478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	enum wpa_driver_if_type iftype;
48481f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt	const u8 *if_addr;
484904949598a23f501be6eec21697465fd46a28840aDmitry Shmidt	struct wpa_ssid *ssid = NULL;
48508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
48518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (wpa_s->global->p2p_disabled || wpa_s->global->p2p == NULL)
48528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return -1;
48538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
485404949598a23f501be6eec21697465fd46a28840aDmitry Shmidt	if (persistent_id >= 0) {
485504949598a23f501be6eec21697465fd46a28840aDmitry Shmidt		ssid = wpa_config_get_network(wpa_s->conf, persistent_id);
485604949598a23f501be6eec21697465fd46a28840aDmitry Shmidt		if (ssid == NULL || ssid->disabled != 2 ||
485704949598a23f501be6eec21697465fd46a28840aDmitry Shmidt		    ssid->mode != WPAS_MODE_P2P_GO)
485804949598a23f501be6eec21697465fd46a28840aDmitry Shmidt			return -1;
485904949598a23f501be6eec21697465fd46a28840aDmitry Shmidt	}
486004949598a23f501be6eec21697465fd46a28840aDmitry Shmidt
4861391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt	os_free(wpa_s->global->add_psk);
4862391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt	wpa_s->global->add_psk = NULL;
4863391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt
4864fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt	wpa_s->global->p2p_fail_on_wps_complete = 0;
4865216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt	wpa_s->global->pending_p2ps_group = 0;
4866fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt
48678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (go_intent < 0)
48688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		go_intent = wpa_s->conf->p2p_go_intent;
48698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
48708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (!auth)
48718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		wpa_s->p2p_long_listen = 0;
48728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
48738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	wpa_s->p2p_wps_method = wps_method;
487404949598a23f501be6eec21697465fd46a28840aDmitry Shmidt	wpa_s->p2p_persistent_group = !!persistent_group;
487504949598a23f501be6eec21697465fd46a28840aDmitry Shmidt	wpa_s->p2p_persistent_id = persistent_id;
487604949598a23f501be6eec21697465fd46a28840aDmitry Shmidt	wpa_s->p2p_go_intent = go_intent;
487704949598a23f501be6eec21697465fd46a28840aDmitry Shmidt	wpa_s->p2p_connect_freq = freq;
487804949598a23f501be6eec21697465fd46a28840aDmitry Shmidt	wpa_s->p2p_fallback_to_go_neg = 0;
487904949598a23f501be6eec21697465fd46a28840aDmitry Shmidt	wpa_s->p2p_pd_before_go_neg = !!pd;
488061d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt	wpa_s->p2p_go_ht40 = !!ht40;
488168d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt	wpa_s->p2p_go_vht = !!vht;
48828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
48838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (pin)
48848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		os_strlcpy(wpa_s->p2p_pin, pin, sizeof(wpa_s->p2p_pin));
48858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	else if (wps_method == WPS_PIN_DISPLAY) {
48868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		ret = wps_generate_pin();
48876c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt		res = os_snprintf(wpa_s->p2p_pin, sizeof(wpa_s->p2p_pin),
48886c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt				  "%08d", ret);
48896c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt		if (os_snprintf_error(sizeof(wpa_s->p2p_pin), res))
48906c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt			wpa_s->p2p_pin[sizeof(wpa_s->p2p_pin) - 1] = '\0';
48918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		wpa_printf(MSG_DEBUG, "P2P: Randomly generated PIN: %s",
48928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			   wpa_s->p2p_pin);
48938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	} else
48948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		wpa_s->p2p_pin[0] = '\0';
48958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
489604949598a23f501be6eec21697465fd46a28840aDmitry Shmidt	if (join || auto_join) {
48978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		u8 iface_addr[ETH_ALEN], dev_addr[ETH_ALEN];
48988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		if (auth) {
48998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			wpa_printf(MSG_DEBUG, "P2P: Authorize invitation to "
49008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt				   "connect a running group from " MACSTR,
49018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt				   MAC2STR(peer_addr));
49028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			os_memcpy(wpa_s->p2p_auth_invite, peer_addr, ETH_ALEN);
49038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			return ret;
49048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		}
49058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		os_memcpy(dev_addr, peer_addr, ETH_ALEN);
49068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		if (p2p_get_interface_addr(wpa_s->global->p2p, peer_addr,
49078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt					   iface_addr) < 0) {
49088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			os_memcpy(iface_addr, peer_addr, ETH_ALEN);
49098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			p2p_get_dev_addr(wpa_s->global->p2p, peer_addr,
49108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt					 dev_addr);
49118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		}
491204949598a23f501be6eec21697465fd46a28840aDmitry Shmidt		if (auto_join) {
4913fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt			os_get_reltime(&wpa_s->p2p_auto_started);
491404949598a23f501be6eec21697465fd46a28840aDmitry Shmidt			wpa_printf(MSG_DEBUG, "P2P: Auto join started at "
491504949598a23f501be6eec21697465fd46a28840aDmitry Shmidt				   "%ld.%06ld",
491604949598a23f501be6eec21697465fd46a28840aDmitry Shmidt				   wpa_s->p2p_auto_started.sec,
491704949598a23f501be6eec21697465fd46a28840aDmitry Shmidt				   wpa_s->p2p_auto_started.usec);
491804949598a23f501be6eec21697465fd46a28840aDmitry Shmidt		}
4919d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt		wpa_s->user_initiated_pd = 1;
492004949598a23f501be6eec21697465fd46a28840aDmitry Shmidt		if (wpas_p2p_join(wpa_s, iface_addr, dev_addr, wps_method,
4921cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt				  auto_join, freq, NULL, 0) < 0)
49228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			return -1;
49238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return ret;
49248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
49258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
492668d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt	res = wpas_p2p_setup_freqs(wpa_s, freq, &force_freq, &pref_freq,
492768d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt				   go_intent == 15);
49287a5e50a0554bee77a9da492ea3d86f46147f1671Dmitry Shmidt	if (res)
49297a5e50a0554bee77a9da492ea3d86f46147f1671Dmitry Shmidt		return res;
4930a0d265f81180f341d22511538fa18166e1bbce9fDmitry Shmidt	wpas_p2p_set_own_freq_preference(wpa_s,
4931a0d265f81180f341d22511538fa18166e1bbce9fDmitry Shmidt					 force_freq ? force_freq : pref_freq);
49328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
49338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	wpa_s->create_p2p_iface = wpas_p2p_create_iface(wpa_s);
49348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
49351f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt	if (wpa_s->create_p2p_iface) {
49361f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt		/* Prepare to add a new interface for the group */
49371f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt		iftype = WPA_IF_P2P_GROUP;
49381f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt		if (go_intent == 15)
49391f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt			iftype = WPA_IF_P2P_GO;
49401f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt		if (wpas_p2p_add_group_interface(wpa_s, iftype) < 0) {
49411f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt			wpa_printf(MSG_ERROR, "P2P: Failed to allocate a new "
49421f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt				   "interface for the group");
49438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			return -1;
49441f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt		}
49458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
49461f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt		if_addr = wpa_s->pending_interface_addr;
49471f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt	} else
49481f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt		if_addr = wpa_s->own_addr;
49498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
49508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (auth) {
49518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		if (wpas_p2p_auth_go_neg(wpa_s, peer_addr, wps_method,
49521f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt					 go_intent, if_addr,
4953d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt					 force_freq, persistent_group, ssid,
4954d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt					 pref_freq) < 0)
49558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			return -1;
49568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return ret;
49578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
49581f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt
49591f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt	if (wpas_p2p_start_go_neg(wpa_s, peer_addr, wps_method,
49601f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt				  go_intent, if_addr, force_freq,
4961d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt				  persistent_group, ssid, pref_freq) < 0) {
49621f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt		if (wpa_s->create_p2p_iface)
49631f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt			wpas_p2p_remove_pending_group_interface(wpa_s);
49648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return -1;
49658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
49668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	return ret;
49678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt}
49688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
49698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
49708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt/**
49718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * wpas_p2p_remain_on_channel_cb - Indication of remain-on-channel start
49728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @wpa_s: Pointer to wpa_supplicant data from wpa_supplicant_add_iface()
49738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @freq: Frequency of the channel in MHz
49748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @duration: Duration of the stay on the channel in milliseconds
49758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt *
49768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * This callback is called when the driver indicates that it has started the
49778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * requested remain-on-channel duration.
49788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */
49798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtvoid wpas_p2p_remain_on_channel_cb(struct wpa_supplicant *wpa_s,
49808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt				   unsigned int freq, unsigned int duration)
49818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{
49828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (wpa_s->global->p2p_disabled || wpa_s->global->p2p == NULL)
49838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return;
4984216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt	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)",
4985216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt		   wpa_s->off_channel_freq, wpa_s->pending_listen_freq,
4986216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt		   wpa_s->roc_waiting_drv_freq, freq, duration);
4987216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt	if (wpa_s->off_channel_freq &&
4988216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt	    wpa_s->off_channel_freq == wpa_s->pending_listen_freq) {
49898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		p2p_listen_cb(wpa_s->global->p2p, wpa_s->pending_listen_freq,
49908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			      wpa_s->pending_listen_duration);
49918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		wpa_s->pending_listen_freq = 0;
49927f93d6fa14a343127754c33a03cf2f641b6ff6e4Dmitry Shmidt	} else {
49937f93d6fa14a343127754c33a03cf2f641b6ff6e4Dmitry Shmidt		wpa_printf(MSG_DEBUG, "P2P: Ignore remain-on-channel callback (off_channel_freq=%u pending_listen_freq=%d freq=%u duration=%u)",
49947f93d6fa14a343127754c33a03cf2f641b6ff6e4Dmitry Shmidt			   wpa_s->off_channel_freq, wpa_s->pending_listen_freq,
49957f93d6fa14a343127754c33a03cf2f641b6ff6e4Dmitry Shmidt			   freq, duration);
49968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
49978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt}
49988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
49998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
500057cea1a480975338d84f7bbc229b4dc76e030600Jithu Janceint wpas_p2p_listen_start(struct wpa_supplicant *wpa_s, unsigned int timeout)
50018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{
50028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	/* Limit maximum Listen state time based on driver limitation. */
50038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (timeout > wpa_s->max_remain_on_chan)
50048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		timeout = wpa_s->max_remain_on_chan;
50058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
50068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	return p2p_listen(wpa_s->global->p2p, timeout);
50078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt}
50088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
50098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
50108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt/**
50118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * wpas_p2p_cancel_remain_on_channel_cb - Remain-on-channel timeout
50128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @wpa_s: Pointer to wpa_supplicant data from wpa_supplicant_add_iface()
50138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @freq: Frequency of the channel in MHz
50148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt *
50158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * This callback is called when the driver indicates that a remain-on-channel
50168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * operation has been completed, i.e., the duration on the requested channel
50178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * has timed out.
50188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */
50198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtvoid wpas_p2p_cancel_remain_on_channel_cb(struct wpa_supplicant *wpa_s,
50208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt					  unsigned int freq)
50218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{
50228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	wpa_printf(MSG_DEBUG, "P2P: Cancel remain-on-channel callback "
50238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		   "(p2p_long_listen=%d ms pending_action_tx=%p)",
5024a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt		   wpa_s->p2p_long_listen, offchannel_pending_action_tx(wpa_s));
5025fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt	wpas_p2p_listen_work_done(wpa_s);
50268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (wpa_s->global->p2p_disabled || wpa_s->global->p2p == NULL)
50278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return;
502857cea1a480975338d84f7bbc229b4dc76e030600Jithu Jance	if (wpa_s->p2p_long_listen > 0)
502957cea1a480975338d84f7bbc229b4dc76e030600Jithu Jance		wpa_s->p2p_long_listen -= wpa_s->max_remain_on_chan;
50308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (p2p_listen_end(wpa_s->global->p2p, freq) > 0)
50318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return; /* P2P module started a new operation */
5032a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt	if (offchannel_pending_action_tx(wpa_s))
50338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return;
50348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (wpa_s->p2p_long_listen > 0) {
50358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		wpa_printf(MSG_DEBUG, "P2P: Continuing long Listen state");
50368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		wpas_p2p_listen_start(wpa_s, wpa_s->p2p_long_listen);
5037391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt	} else {
5038391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt		/*
5039391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt		 * When listen duration is over, stop listen & update p2p_state
5040391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt		 * to IDLE.
5041391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt		 */
5042391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt		p2p_stop_listen(wpa_s->global->p2p);
50438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
50448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt}
50458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
50468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
50478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt/**
50488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * wpas_p2p_group_remove - Remove a P2P group
50498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @wpa_s: Pointer to wpa_supplicant data from wpa_supplicant_add_iface()
50508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @ifname: Network interface name of the group interface or "*" to remove all
50518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt *	groups
50528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * Returns: 0 on success, -1 on failure
50538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt *
50548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * This function is used to remove a P2P group. This can be used to disconnect
50558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * from a group in which the local end is a P2P Client or to end a P2P Group in
50568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * case the local end is the Group Owner. If a virtual network interface was
50578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * created for this group, that interface will be removed. Otherwise, only the
50588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * configured P2P group network will be removed from the interface.
50598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */
50608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtint wpas_p2p_group_remove(struct wpa_supplicant *wpa_s, const char *ifname)
50618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{
50628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	struct wpa_global *global = wpa_s->global;
50636c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt	struct wpa_supplicant *calling_wpa_s = wpa_s;
50648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
50658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (os_strcmp(ifname, "*") == 0) {
50668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		struct wpa_supplicant *prev;
50678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		wpa_s = global->ifaces;
50688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		while (wpa_s) {
50698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			prev = wpa_s;
50708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			wpa_s = wpa_s->next;
5071b7b4d0ec07161a6d76c40ba7ef1306e82fbb7e15Dmitry Shmidt			if (prev->p2p_group_interface !=
5072b7b4d0ec07161a6d76c40ba7ef1306e82fbb7e15Dmitry Shmidt			    NOT_P2P_GROUP_INTERFACE ||
5073b7b4d0ec07161a6d76c40ba7ef1306e82fbb7e15Dmitry Shmidt			    (prev->current_ssid &&
5074b7b4d0ec07161a6d76c40ba7ef1306e82fbb7e15Dmitry Shmidt			     prev->current_ssid->p2p_group))
50756c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt				wpas_p2p_disconnect_safely(prev, calling_wpa_s);
50768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		}
50778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return 0;
50788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
50798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
50808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	for (wpa_s = global->ifaces; wpa_s; wpa_s = wpa_s->next) {
50818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		if (os_strcmp(wpa_s->ifname, ifname) == 0)
50828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			break;
50838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
50848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
50856c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt	return wpas_p2p_disconnect_safely(wpa_s, calling_wpa_s);
50868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt}
50878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
50888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
50898bae4138a0356709720a96f3e50b4d734e532c12Dmitry Shmidtstatic int wpas_p2p_select_go_freq(struct wpa_supplicant *wpa_s, int freq)
50908bae4138a0356709720a96f3e50b4d734e532c12Dmitry Shmidt{
50918bae4138a0356709720a96f3e50b4d734e532c12Dmitry Shmidt	unsigned int r;
50928bae4138a0356709720a96f3e50b4d734e532c12Dmitry Shmidt
50938bae4138a0356709720a96f3e50b4d734e532c12Dmitry Shmidt	if (freq == 2) {
50948bae4138a0356709720a96f3e50b4d734e532c12Dmitry Shmidt		wpa_printf(MSG_DEBUG, "P2P: Request to start GO on 2.4 GHz "
50958bae4138a0356709720a96f3e50b4d734e532c12Dmitry Shmidt			   "band");
50968bae4138a0356709720a96f3e50b4d734e532c12Dmitry Shmidt		if (wpa_s->best_24_freq > 0 &&
509768d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt		    p2p_supported_freq_go(wpa_s->global->p2p,
509868d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt					  wpa_s->best_24_freq)) {
50998bae4138a0356709720a96f3e50b4d734e532c12Dmitry Shmidt			freq = wpa_s->best_24_freq;
51008bae4138a0356709720a96f3e50b4d734e532c12Dmitry Shmidt			wpa_printf(MSG_DEBUG, "P2P: Use best 2.4 GHz band "
51018bae4138a0356709720a96f3e50b4d734e532c12Dmitry Shmidt				   "channel: %d MHz", freq);
51028bae4138a0356709720a96f3e50b4d734e532c12Dmitry Shmidt		} else {
5103661b4f78e48c697429dc46154a4125892c001718Dmitry Shmidt			if (os_get_random((u8 *) &r, sizeof(r)) < 0)
5104661b4f78e48c697429dc46154a4125892c001718Dmitry Shmidt				return -1;
51058bae4138a0356709720a96f3e50b4d734e532c12Dmitry Shmidt			freq = 2412 + (r % 3) * 25;
51068bae4138a0356709720a96f3e50b4d734e532c12Dmitry Shmidt			wpa_printf(MSG_DEBUG, "P2P: Use random 2.4 GHz band "
51078bae4138a0356709720a96f3e50b4d734e532c12Dmitry Shmidt				   "channel: %d MHz", freq);
51088bae4138a0356709720a96f3e50b4d734e532c12Dmitry Shmidt		}
51098bae4138a0356709720a96f3e50b4d734e532c12Dmitry Shmidt	}
51108bae4138a0356709720a96f3e50b4d734e532c12Dmitry Shmidt
51118bae4138a0356709720a96f3e50b4d734e532c12Dmitry Shmidt	if (freq == 5) {
51128bae4138a0356709720a96f3e50b4d734e532c12Dmitry Shmidt		wpa_printf(MSG_DEBUG, "P2P: Request to start GO on 5 GHz "
51138bae4138a0356709720a96f3e50b4d734e532c12Dmitry Shmidt			   "band");
51148bae4138a0356709720a96f3e50b4d734e532c12Dmitry Shmidt		if (wpa_s->best_5_freq > 0 &&
511568d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt		    p2p_supported_freq_go(wpa_s->global->p2p,
51168bae4138a0356709720a96f3e50b4d734e532c12Dmitry Shmidt				       wpa_s->best_5_freq)) {
51178bae4138a0356709720a96f3e50b4d734e532c12Dmitry Shmidt			freq = wpa_s->best_5_freq;
51188bae4138a0356709720a96f3e50b4d734e532c12Dmitry Shmidt			wpa_printf(MSG_DEBUG, "P2P: Use best 5 GHz band "
51198bae4138a0356709720a96f3e50b4d734e532c12Dmitry Shmidt				   "channel: %d MHz", freq);
51208bae4138a0356709720a96f3e50b4d734e532c12Dmitry Shmidt		} else {
5121661b4f78e48c697429dc46154a4125892c001718Dmitry Shmidt			if (os_get_random((u8 *) &r, sizeof(r)) < 0)
5122661b4f78e48c697429dc46154a4125892c001718Dmitry Shmidt				return -1;
51238bae4138a0356709720a96f3e50b4d734e532c12Dmitry Shmidt			freq = 5180 + (r % 4) * 20;
512468d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt			if (!p2p_supported_freq_go(wpa_s->global->p2p, freq)) {
51258bae4138a0356709720a96f3e50b4d734e532c12Dmitry Shmidt				wpa_printf(MSG_DEBUG, "P2P: Could not select "
51268bae4138a0356709720a96f3e50b4d734e532c12Dmitry Shmidt					   "5 GHz channel for P2P group");
51278bae4138a0356709720a96f3e50b4d734e532c12Dmitry Shmidt				return -1;
51288bae4138a0356709720a96f3e50b4d734e532c12Dmitry Shmidt			}
51298bae4138a0356709720a96f3e50b4d734e532c12Dmitry Shmidt			wpa_printf(MSG_DEBUG, "P2P: Use random 5 GHz band "
51308bae4138a0356709720a96f3e50b4d734e532c12Dmitry Shmidt				   "channel: %d MHz", freq);
51318bae4138a0356709720a96f3e50b4d734e532c12Dmitry Shmidt		}
51328bae4138a0356709720a96f3e50b4d734e532c12Dmitry Shmidt	}
51338bae4138a0356709720a96f3e50b4d734e532c12Dmitry Shmidt
513468d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt	if (freq > 0 && !p2p_supported_freq_go(wpa_s->global->p2p, freq)) {
5135203eadb9eda41a1dde4a583edb4684319e3f399eDmitry Shmidt		if ((wpa_s->drv_flags & WPA_DRIVER_FLAGS_DFS_OFFLOAD) &&
5136203eadb9eda41a1dde4a583edb4684319e3f399eDmitry Shmidt		    ieee80211_is_dfs(freq)) {
5137203eadb9eda41a1dde4a583edb4684319e3f399eDmitry Shmidt			/*
5138203eadb9eda41a1dde4a583edb4684319e3f399eDmitry Shmidt			 * If freq is a DFS channel and DFS is offloaded to the
5139203eadb9eda41a1dde4a583edb4684319e3f399eDmitry Shmidt			 * driver, allow P2P GO to use it.
5140203eadb9eda41a1dde4a583edb4684319e3f399eDmitry Shmidt			 */
5141203eadb9eda41a1dde4a583edb4684319e3f399eDmitry Shmidt			wpa_printf(MSG_DEBUG, "P2P: "
5142203eadb9eda41a1dde4a583edb4684319e3f399eDmitry Shmidt				   "%s: The forced channel for GO (%u MHz) is DFS, and DFS is offloaded",
5143203eadb9eda41a1dde4a583edb4684319e3f399eDmitry Shmidt				   __func__, freq);
5144203eadb9eda41a1dde4a583edb4684319e3f399eDmitry Shmidt			return freq;
5145203eadb9eda41a1dde4a583edb4684319e3f399eDmitry Shmidt		}
51468bae4138a0356709720a96f3e50b4d734e532c12Dmitry Shmidt		wpa_printf(MSG_DEBUG, "P2P: The forced channel for GO "
51478bae4138a0356709720a96f3e50b4d734e532c12Dmitry Shmidt			   "(%u MHz) is not supported for P2P uses",
51488bae4138a0356709720a96f3e50b4d734e532c12Dmitry Shmidt			   freq);
51498bae4138a0356709720a96f3e50b4d734e532c12Dmitry Shmidt		return -1;
51508bae4138a0356709720a96f3e50b4d734e532c12Dmitry Shmidt	}
51518bae4138a0356709720a96f3e50b4d734e532c12Dmitry Shmidt
51528bae4138a0356709720a96f3e50b4d734e532c12Dmitry Shmidt	return freq;
51538bae4138a0356709720a96f3e50b4d734e532c12Dmitry Shmidt}
51548bae4138a0356709720a96f3e50b4d734e532c12Dmitry Shmidt
51558bae4138a0356709720a96f3e50b4d734e532c12Dmitry Shmidt
515643cb578dfe2c492257636f6234a24178ed27789eDmitry Shmidtstatic int wpas_p2p_select_freq_no_pref(struct wpa_supplicant *wpa_s,
515743cb578dfe2c492257636f6234a24178ed27789eDmitry Shmidt					struct p2p_go_neg_results *params,
515843cb578dfe2c492257636f6234a24178ed27789eDmitry Shmidt					const struct p2p_channels *channels)
515943cb578dfe2c492257636f6234a24178ed27789eDmitry Shmidt{
516043cb578dfe2c492257636f6234a24178ed27789eDmitry Shmidt	unsigned int i, r;
516143cb578dfe2c492257636f6234a24178ed27789eDmitry Shmidt
516243cb578dfe2c492257636f6234a24178ed27789eDmitry Shmidt	/* first try some random selection of the social channels */
5163661b4f78e48c697429dc46154a4125892c001718Dmitry Shmidt	if (os_get_random((u8 *) &r, sizeof(r)) < 0)
5164661b4f78e48c697429dc46154a4125892c001718Dmitry Shmidt		return -1;
516543cb578dfe2c492257636f6234a24178ed27789eDmitry Shmidt
516643cb578dfe2c492257636f6234a24178ed27789eDmitry Shmidt	for (i = 0; i < 3; i++) {
516743cb578dfe2c492257636f6234a24178ed27789eDmitry Shmidt		params->freq = 2412 + ((r + i) % 3) * 25;
516843cb578dfe2c492257636f6234a24178ed27789eDmitry Shmidt		if (!wpas_p2p_disallowed_freq(wpa_s->global, params->freq) &&
5169661b4f78e48c697429dc46154a4125892c001718Dmitry Shmidt		    freq_included(channels, params->freq) &&
5170661b4f78e48c697429dc46154a4125892c001718Dmitry Shmidt		    p2p_supported_freq(wpa_s->global->p2p, params->freq))
517143cb578dfe2c492257636f6234a24178ed27789eDmitry Shmidt			goto out;
517243cb578dfe2c492257636f6234a24178ed27789eDmitry Shmidt	}
517343cb578dfe2c492257636f6234a24178ed27789eDmitry Shmidt
517443cb578dfe2c492257636f6234a24178ed27789eDmitry Shmidt	/* try all channels in reg. class 81 */
517543cb578dfe2c492257636f6234a24178ed27789eDmitry Shmidt	for (i = 0; i < 11; i++) {
517643cb578dfe2c492257636f6234a24178ed27789eDmitry Shmidt		params->freq = 2412 + i * 5;
517743cb578dfe2c492257636f6234a24178ed27789eDmitry Shmidt		if (!wpas_p2p_disallowed_freq(wpa_s->global, params->freq) &&
5178661b4f78e48c697429dc46154a4125892c001718Dmitry Shmidt		    freq_included(channels, params->freq) &&
5179661b4f78e48c697429dc46154a4125892c001718Dmitry Shmidt		    p2p_supported_freq(wpa_s->global->p2p, params->freq))
518043cb578dfe2c492257636f6234a24178ed27789eDmitry Shmidt			goto out;
518143cb578dfe2c492257636f6234a24178ed27789eDmitry Shmidt	}
518243cb578dfe2c492257636f6234a24178ed27789eDmitry Shmidt
5183203eadb9eda41a1dde4a583edb4684319e3f399eDmitry Shmidt	/* try all channels in operating class 115 */
5184203eadb9eda41a1dde4a583edb4684319e3f399eDmitry Shmidt	for (i = 0; i < 4; i++) {
5185203eadb9eda41a1dde4a583edb4684319e3f399eDmitry Shmidt		params->freq = 5180 + i * 20;
5186203eadb9eda41a1dde4a583edb4684319e3f399eDmitry Shmidt		if (!wpas_p2p_disallowed_freq(wpa_s->global, params->freq) &&
5187203eadb9eda41a1dde4a583edb4684319e3f399eDmitry Shmidt		    freq_included(channels, params->freq) &&
5188203eadb9eda41a1dde4a583edb4684319e3f399eDmitry Shmidt		    p2p_supported_freq(wpa_s->global->p2p, params->freq))
5189203eadb9eda41a1dde4a583edb4684319e3f399eDmitry Shmidt			goto out;
5190203eadb9eda41a1dde4a583edb4684319e3f399eDmitry Shmidt	}
5191203eadb9eda41a1dde4a583edb4684319e3f399eDmitry Shmidt
5192203eadb9eda41a1dde4a583edb4684319e3f399eDmitry Shmidt	/* try all channels in operating class 124 */
5193203eadb9eda41a1dde4a583edb4684319e3f399eDmitry Shmidt	for (i = 0; i < 4; i++) {
5194203eadb9eda41a1dde4a583edb4684319e3f399eDmitry Shmidt		params->freq = 5745 + i * 20;
5195203eadb9eda41a1dde4a583edb4684319e3f399eDmitry Shmidt		if (!wpas_p2p_disallowed_freq(wpa_s->global, params->freq) &&
5196203eadb9eda41a1dde4a583edb4684319e3f399eDmitry Shmidt		    freq_included(channels, params->freq) &&
5197203eadb9eda41a1dde4a583edb4684319e3f399eDmitry Shmidt		    p2p_supported_freq(wpa_s->global->p2p, params->freq))
5198203eadb9eda41a1dde4a583edb4684319e3f399eDmitry Shmidt			goto out;
5199203eadb9eda41a1dde4a583edb4684319e3f399eDmitry Shmidt	}
5200203eadb9eda41a1dde4a583edb4684319e3f399eDmitry Shmidt
5201661b4f78e48c697429dc46154a4125892c001718Dmitry Shmidt	/* try social channel class 180 channel 2 */
5202661b4f78e48c697429dc46154a4125892c001718Dmitry Shmidt	params->freq = 58320 + 1 * 2160;
5203661b4f78e48c697429dc46154a4125892c001718Dmitry Shmidt	if (!wpas_p2p_disallowed_freq(wpa_s->global, params->freq) &&
5204661b4f78e48c697429dc46154a4125892c001718Dmitry Shmidt	    freq_included(channels, params->freq) &&
5205661b4f78e48c697429dc46154a4125892c001718Dmitry Shmidt	    p2p_supported_freq(wpa_s->global->p2p, params->freq))
5206661b4f78e48c697429dc46154a4125892c001718Dmitry Shmidt		goto out;
5207661b4f78e48c697429dc46154a4125892c001718Dmitry Shmidt
5208661b4f78e48c697429dc46154a4125892c001718Dmitry Shmidt	/* try all channels in reg. class 180 */
5209661b4f78e48c697429dc46154a4125892c001718Dmitry Shmidt	for (i = 0; i < 4; i++) {
5210661b4f78e48c697429dc46154a4125892c001718Dmitry Shmidt		params->freq = 58320 + i * 2160;
5211661b4f78e48c697429dc46154a4125892c001718Dmitry Shmidt		if (!wpas_p2p_disallowed_freq(wpa_s->global, params->freq) &&
5212661b4f78e48c697429dc46154a4125892c001718Dmitry Shmidt		    freq_included(channels, params->freq) &&
5213661b4f78e48c697429dc46154a4125892c001718Dmitry Shmidt		    p2p_supported_freq(wpa_s->global->p2p, params->freq))
5214661b4f78e48c697429dc46154a4125892c001718Dmitry Shmidt			goto out;
5215661b4f78e48c697429dc46154a4125892c001718Dmitry Shmidt	}
5216661b4f78e48c697429dc46154a4125892c001718Dmitry Shmidt
5217203eadb9eda41a1dde4a583edb4684319e3f399eDmitry Shmidt	wpa_printf(MSG_DEBUG, "P2P: No 2.4, 5, or 60 GHz channel allowed");
521843cb578dfe2c492257636f6234a24178ed27789eDmitry Shmidt	return -1;
521943cb578dfe2c492257636f6234a24178ed27789eDmitry Shmidtout:
522043cb578dfe2c492257636f6234a24178ed27789eDmitry Shmidt	wpa_printf(MSG_DEBUG, "P2P: Set GO freq %d MHz (no preference known)",
522143cb578dfe2c492257636f6234a24178ed27789eDmitry Shmidt		   params->freq);
522243cb578dfe2c492257636f6234a24178ed27789eDmitry Shmidt	return 0;
522343cb578dfe2c492257636f6234a24178ed27789eDmitry Shmidt}
522443cb578dfe2c492257636f6234a24178ed27789eDmitry Shmidt
522543cb578dfe2c492257636f6234a24178ed27789eDmitry Shmidt
52261f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidtstatic int wpas_p2p_init_go_params(struct wpa_supplicant *wpa_s,
52271f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt				   struct p2p_go_neg_results *params,
522868d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt				   int freq, int ht40, int vht,
52297a5e50a0554bee77a9da492ea3d86f46147f1671Dmitry Shmidt				   const struct p2p_channels *channels)
52308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{
523143cb578dfe2c492257636f6234a24178ed27789eDmitry Shmidt	struct wpa_used_freq_data *freqs;
523243cb578dfe2c492257636f6234a24178ed27789eDmitry Shmidt	unsigned int pref_freq, cand_freq;
5233c2ebb4b85d69b65f552fee71ac68f44e8d87b39eDmitry Shmidt	unsigned int num, i;
52348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
52358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	os_memset(params, 0, sizeof(*params));
52368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	params->role_go = 1;
523761d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt	params->ht40 = ht40;
523868d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt	params->vht = vht;
52398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (freq) {
52407a5e50a0554bee77a9da492ea3d86f46147f1671Dmitry Shmidt		if (!freq_included(channels, freq)) {
52417a5e50a0554bee77a9da492ea3d86f46147f1671Dmitry Shmidt			wpa_printf(MSG_DEBUG, "P2P: Forced GO freq %d MHz not "
52427a5e50a0554bee77a9da492ea3d86f46147f1671Dmitry Shmidt				   "accepted", freq);
52437a5e50a0554bee77a9da492ea3d86f46147f1671Dmitry Shmidt			return -1;
52447a5e50a0554bee77a9da492ea3d86f46147f1671Dmitry Shmidt		}
52458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		wpa_printf(MSG_DEBUG, "P2P: Set GO freq based on forced "
52468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			   "frequency %d MHz", freq);
52478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		params->freq = freq;
52488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	} else if (wpa_s->conf->p2p_oper_reg_class == 81 &&
52498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		   wpa_s->conf->p2p_oper_channel >= 1 &&
52507a5e50a0554bee77a9da492ea3d86f46147f1671Dmitry Shmidt		   wpa_s->conf->p2p_oper_channel <= 11 &&
52517a5e50a0554bee77a9da492ea3d86f46147f1671Dmitry Shmidt		   freq_included(channels,
52527a5e50a0554bee77a9da492ea3d86f46147f1671Dmitry Shmidt				 2407 + 5 * wpa_s->conf->p2p_oper_channel)) {
52538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		params->freq = 2407 + 5 * wpa_s->conf->p2p_oper_channel;
52548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		wpa_printf(MSG_DEBUG, "P2P: Set GO freq based on configured "
52558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			   "frequency %d MHz", params->freq);
52567a5e50a0554bee77a9da492ea3d86f46147f1671Dmitry Shmidt	} else if ((wpa_s->conf->p2p_oper_reg_class == 115 ||
52577a5e50a0554bee77a9da492ea3d86f46147f1671Dmitry Shmidt		    wpa_s->conf->p2p_oper_reg_class == 116 ||
52587a5e50a0554bee77a9da492ea3d86f46147f1671Dmitry Shmidt		    wpa_s->conf->p2p_oper_reg_class == 117 ||
52597a5e50a0554bee77a9da492ea3d86f46147f1671Dmitry Shmidt		    wpa_s->conf->p2p_oper_reg_class == 124 ||
5260a3dc30964aa24aea2b518246f6812663a1103490Dmitry Shmidt		    wpa_s->conf->p2p_oper_reg_class == 125 ||
52617a5e50a0554bee77a9da492ea3d86f46147f1671Dmitry Shmidt		    wpa_s->conf->p2p_oper_reg_class == 126 ||
52627a5e50a0554bee77a9da492ea3d86f46147f1671Dmitry Shmidt		    wpa_s->conf->p2p_oper_reg_class == 127) &&
52637a5e50a0554bee77a9da492ea3d86f46147f1671Dmitry Shmidt		   freq_included(channels,
52647a5e50a0554bee77a9da492ea3d86f46147f1671Dmitry Shmidt				 5000 + 5 * wpa_s->conf->p2p_oper_channel)) {
52658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		params->freq = 5000 + 5 * wpa_s->conf->p2p_oper_channel;
52668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		wpa_printf(MSG_DEBUG, "P2P: Set GO freq based on configured "
52678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			   "frequency %d MHz", params->freq);
52688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	} else if (wpa_s->conf->p2p_oper_channel == 0 &&
52698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		   wpa_s->best_overall_freq > 0 &&
527068d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt		   p2p_supported_freq_go(wpa_s->global->p2p,
527168d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt					 wpa_s->best_overall_freq) &&
52727a5e50a0554bee77a9da492ea3d86f46147f1671Dmitry Shmidt		   freq_included(channels, wpa_s->best_overall_freq)) {
52738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		params->freq = wpa_s->best_overall_freq;
52748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		wpa_printf(MSG_DEBUG, "P2P: Set GO freq based on best overall "
52758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			   "channel %d MHz", params->freq);
52768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	} else if (wpa_s->conf->p2p_oper_channel == 0 &&
52778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		   wpa_s->best_24_freq > 0 &&
527868d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt		   p2p_supported_freq_go(wpa_s->global->p2p,
527968d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt					 wpa_s->best_24_freq) &&
52807a5e50a0554bee77a9da492ea3d86f46147f1671Dmitry Shmidt		   freq_included(channels, wpa_s->best_24_freq)) {
52818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		params->freq = wpa_s->best_24_freq;
52828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		wpa_printf(MSG_DEBUG, "P2P: Set GO freq based on best 2.4 GHz "
52838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			   "channel %d MHz", params->freq);
52848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	} else if (wpa_s->conf->p2p_oper_channel == 0 &&
52858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		   wpa_s->best_5_freq > 0 &&
528668d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt		   p2p_supported_freq_go(wpa_s->global->p2p,
528768d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt					 wpa_s->best_5_freq) &&
52887a5e50a0554bee77a9da492ea3d86f46147f1671Dmitry Shmidt		   freq_included(channels, wpa_s->best_5_freq)) {
52898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		params->freq = wpa_s->best_5_freq;
52908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		wpa_printf(MSG_DEBUG, "P2P: Set GO freq based on best 5 GHz "
52918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			   "channel %d MHz", params->freq);
529244c957860ca714a86357591f39aff0bfa904c743Dmitry Shmidt	} else if ((pref_freq = p2p_get_pref_freq(wpa_s->global->p2p,
529344c957860ca714a86357591f39aff0bfa904c743Dmitry Shmidt						  channels))) {
529444c957860ca714a86357591f39aff0bfa904c743Dmitry Shmidt		params->freq = pref_freq;
529544c957860ca714a86357591f39aff0bfa904c743Dmitry Shmidt		wpa_printf(MSG_DEBUG, "P2P: Set GO freq %d MHz from preferred "
529644c957860ca714a86357591f39aff0bfa904c743Dmitry Shmidt			   "channels", params->freq);
52978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	} else {
529843cb578dfe2c492257636f6234a24178ed27789eDmitry Shmidt		/* no preference, select some channel */
529943cb578dfe2c492257636f6234a24178ed27789eDmitry Shmidt		if (wpas_p2p_select_freq_no_pref(wpa_s, params, channels) < 0)
530004949598a23f501be6eec21697465fd46a28840aDmitry Shmidt			return -1;
53018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
53028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
530343cb578dfe2c492257636f6234a24178ed27789eDmitry Shmidt	freqs = os_calloc(wpa_s->num_multichan_concurrent,
530443cb578dfe2c492257636f6234a24178ed27789eDmitry Shmidt			  sizeof(struct wpa_used_freq_data));
5305c2ebb4b85d69b65f552fee71ac68f44e8d87b39eDmitry Shmidt	if (!freqs)
5306c2ebb4b85d69b65f552fee71ac68f44e8d87b39eDmitry Shmidt		return -1;
5307c2ebb4b85d69b65f552fee71ac68f44e8d87b39eDmitry Shmidt
530843cb578dfe2c492257636f6234a24178ed27789eDmitry Shmidt	num = wpas_p2p_valid_oper_freqs(wpa_s, freqs,
5309c2ebb4b85d69b65f552fee71ac68f44e8d87b39eDmitry Shmidt					wpa_s->num_multichan_concurrent);
5310c2ebb4b85d69b65f552fee71ac68f44e8d87b39eDmitry Shmidt
531143cb578dfe2c492257636f6234a24178ed27789eDmitry Shmidt	cand_freq = wpas_p2p_pick_best_used_freq(wpa_s, freqs, num);
531243cb578dfe2c492257636f6234a24178ed27789eDmitry Shmidt
531343cb578dfe2c492257636f6234a24178ed27789eDmitry Shmidt	/* First try the best used frequency if possible */
531443cb578dfe2c492257636f6234a24178ed27789eDmitry Shmidt	if (!freq && cand_freq > 0 && freq_included(channels, cand_freq)) {
531543cb578dfe2c492257636f6234a24178ed27789eDmitry Shmidt		params->freq = cand_freq;
531643cb578dfe2c492257636f6234a24178ed27789eDmitry Shmidt	} else if (!freq) {
531743cb578dfe2c492257636f6234a24178ed27789eDmitry Shmidt		/* Try any of the used frequencies */
531843cb578dfe2c492257636f6234a24178ed27789eDmitry Shmidt		for (i = 0; i < num; i++) {
531943cb578dfe2c492257636f6234a24178ed27789eDmitry Shmidt			if (freq_included(channels, freqs[i].freq)) {
532043cb578dfe2c492257636f6234a24178ed27789eDmitry Shmidt				wpa_printf(MSG_DEBUG, "P2P: Force GO on a channel we are already using (%u MHz)",
532143cb578dfe2c492257636f6234a24178ed27789eDmitry Shmidt					   freqs[i].freq);
532243cb578dfe2c492257636f6234a24178ed27789eDmitry Shmidt				params->freq = freqs[i].freq;
532343cb578dfe2c492257636f6234a24178ed27789eDmitry Shmidt				break;
532443cb578dfe2c492257636f6234a24178ed27789eDmitry Shmidt			}
53257a5e50a0554bee77a9da492ea3d86f46147f1671Dmitry Shmidt		}
53261f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt
532743cb578dfe2c492257636f6234a24178ed27789eDmitry Shmidt		if (i == num) {
532843cb578dfe2c492257636f6234a24178ed27789eDmitry Shmidt			if (wpas_p2p_num_unused_channels(wpa_s) <= 0) {
5329e0e48dc666fb14a7bb60264ca87463ba7bc1fe0bDmitry Shmidt				wpa_printf(MSG_DEBUG, "P2P: Cannot force GO on any of the channels we are already using");
533043cb578dfe2c492257636f6234a24178ed27789eDmitry Shmidt				os_free(freqs);
533143cb578dfe2c492257636f6234a24178ed27789eDmitry Shmidt				return -1;
533243cb578dfe2c492257636f6234a24178ed27789eDmitry Shmidt			} else {
533343cb578dfe2c492257636f6234a24178ed27789eDmitry Shmidt				wpa_printf(MSG_DEBUG, "P2P: Cannot force GO on any of the channels we are already using. Use one of the free channels");
533443cb578dfe2c492257636f6234a24178ed27789eDmitry Shmidt			}
533543cb578dfe2c492257636f6234a24178ed27789eDmitry Shmidt		}
533643cb578dfe2c492257636f6234a24178ed27789eDmitry Shmidt	} else {
533743cb578dfe2c492257636f6234a24178ed27789eDmitry Shmidt		for (i = 0; i < num; i++) {
533843cb578dfe2c492257636f6234a24178ed27789eDmitry Shmidt			if (freqs[i].freq == freq)
533943cb578dfe2c492257636f6234a24178ed27789eDmitry Shmidt				break;
534043cb578dfe2c492257636f6234a24178ed27789eDmitry Shmidt		}
534143cb578dfe2c492257636f6234a24178ed27789eDmitry Shmidt
534243cb578dfe2c492257636f6234a24178ed27789eDmitry Shmidt		if (i == num) {
534343cb578dfe2c492257636f6234a24178ed27789eDmitry Shmidt			if (wpas_p2p_num_unused_channels(wpa_s) <= 0) {
534443cb578dfe2c492257636f6234a24178ed27789eDmitry Shmidt				if (freq)
534543cb578dfe2c492257636f6234a24178ed27789eDmitry Shmidt					wpa_printf(MSG_DEBUG, "P2P: Cannot force GO on freq (%u MHz) as all the channels are in use", freq);
534643cb578dfe2c492257636f6234a24178ed27789eDmitry Shmidt				os_free(freqs);
534743cb578dfe2c492257636f6234a24178ed27789eDmitry Shmidt				return -1;
534843cb578dfe2c492257636f6234a24178ed27789eDmitry Shmidt			} else {
534943cb578dfe2c492257636f6234a24178ed27789eDmitry Shmidt				wpa_printf(MSG_DEBUG, "P2P: Use one of the free channels");
535043cb578dfe2c492257636f6234a24178ed27789eDmitry Shmidt			}
5351c2ebb4b85d69b65f552fee71ac68f44e8d87b39eDmitry Shmidt		}
5352c2ebb4b85d69b65f552fee71ac68f44e8d87b39eDmitry Shmidt	}
5353e0e48dc666fb14a7bb60264ca87463ba7bc1fe0bDmitry Shmidt
5354c2ebb4b85d69b65f552fee71ac68f44e8d87b39eDmitry Shmidt	os_free(freqs);
53551f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt	return 0;
53568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt}
53578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
53588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
53598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic struct wpa_supplicant *
53608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtwpas_p2p_get_group_iface(struct wpa_supplicant *wpa_s, int addr_allocated,
53618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			 int go)
53628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{
53638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	struct wpa_supplicant *group_wpa_s;
53648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
5365aa532510a7b8c4da2d7d6e2c11dda5db840894e4Dmitry Shmidt	if (!wpas_p2p_create_iface(wpa_s)) {
5366aa532510a7b8c4da2d7d6e2c11dda5db840894e4Dmitry Shmidt		wpa_dbg(wpa_s, MSG_DEBUG, "P2P: Use same interface for group "
5367aa532510a7b8c4da2d7d6e2c11dda5db840894e4Dmitry Shmidt			"operations");
53685605286c30e1701491bd3af974ae423727750eddDmitry Shmidt		wpa_s->p2p_first_connection_timeout = 0;
53698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return wpa_s;
5370aa532510a7b8c4da2d7d6e2c11dda5db840894e4Dmitry Shmidt	}
53718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
53728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (wpas_p2p_add_group_interface(wpa_s, go ? WPA_IF_P2P_GO :
5373aa532510a7b8c4da2d7d6e2c11dda5db840894e4Dmitry Shmidt					 WPA_IF_P2P_CLIENT) < 0) {
5374b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt		wpa_msg_global(wpa_s, MSG_ERROR,
5375b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt			       "P2P: Failed to add group interface");
53768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return NULL;
5377aa532510a7b8c4da2d7d6e2c11dda5db840894e4Dmitry Shmidt	}
53788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	group_wpa_s = wpas_p2p_init_group_interface(wpa_s, go);
53798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (group_wpa_s == NULL) {
5380b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt		wpa_msg_global(wpa_s, MSG_ERROR,
5381b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt			       "P2P: Failed to initialize group interface");
53828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		wpas_p2p_remove_pending_group_interface(wpa_s);
53838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return NULL;
53848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
53858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
5386aa532510a7b8c4da2d7d6e2c11dda5db840894e4Dmitry Shmidt	wpa_dbg(wpa_s, MSG_DEBUG, "P2P: Use separate group interface %s",
5387aa532510a7b8c4da2d7d6e2c11dda5db840894e4Dmitry Shmidt		group_wpa_s->ifname);
53885605286c30e1701491bd3af974ae423727750eddDmitry Shmidt	group_wpa_s->p2p_first_connection_timeout = 0;
53898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	return group_wpa_s;
53908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt}
53918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
53928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
53938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt/**
53948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * wpas_p2p_group_add - Add a new P2P group with local end as Group Owner
53958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @wpa_s: Pointer to wpa_supplicant data from wpa_supplicant_add_iface()
53968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @persistent_group: Whether to create a persistent group
53978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @freq: Frequency for the group or 0 to indicate no hardcoding
539868d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt * @ht40: Start GO with 40 MHz channel width
539968d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt * @vht:  Start GO with VHT support
54008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * Returns: 0 on success, -1 on failure
54018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt *
54028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * This function creates a new P2P group with the local end as the Group Owner,
54038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * i.e., without using Group Owner Negotiation.
54048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */
54058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtint wpas_p2p_group_add(struct wpa_supplicant *wpa_s, int persistent_group,
540668d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt		       int freq, int ht40, int vht)
54078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{
54088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	struct p2p_go_neg_results params;
54098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
54108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (wpa_s->global->p2p_disabled || wpa_s->global->p2p == NULL)
54118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return -1;
54128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
5413391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt	os_free(wpa_s->global->add_psk);
5414391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt	wpa_s->global->add_psk = NULL;
5415391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt
5416dca3979ccdf869f140f096b83df322a0efc84f22Dmitry Shmidt	/* Make sure we are not running find during connection establishment */
54171f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt	wpa_printf(MSG_DEBUG, "P2P: Stop any on-going P2P FIND");
5418d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt	wpas_p2p_stop_find_oper(wpa_s);
5419dca3979ccdf869f140f096b83df322a0efc84f22Dmitry Shmidt
54208bae4138a0356709720a96f3e50b4d734e532c12Dmitry Shmidt	freq = wpas_p2p_select_go_freq(wpa_s, freq);
54218bae4138a0356709720a96f3e50b4d734e532c12Dmitry Shmidt	if (freq < 0)
54228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return -1;
54238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
542468d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt	if (wpas_p2p_init_go_params(wpa_s, &params, freq, ht40, vht, NULL))
54251f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt		return -1;
542604949598a23f501be6eec21697465fd46a28840aDmitry Shmidt	if (params.freq &&
542768d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt	    !p2p_supported_freq_go(wpa_s->global->p2p, params.freq)) {
5428203eadb9eda41a1dde4a583edb4684319e3f399eDmitry Shmidt		if ((wpa_s->drv_flags & WPA_DRIVER_FLAGS_DFS_OFFLOAD) &&
5429203eadb9eda41a1dde4a583edb4684319e3f399eDmitry Shmidt		    ieee80211_is_dfs(params.freq)) {
5430203eadb9eda41a1dde4a583edb4684319e3f399eDmitry Shmidt			/*
5431203eadb9eda41a1dde4a583edb4684319e3f399eDmitry Shmidt			 * If freq is a DFS channel and DFS is offloaded to the
5432203eadb9eda41a1dde4a583edb4684319e3f399eDmitry Shmidt			 * driver, allow P2P GO to use it.
5433203eadb9eda41a1dde4a583edb4684319e3f399eDmitry Shmidt			 */
5434203eadb9eda41a1dde4a583edb4684319e3f399eDmitry Shmidt			wpa_printf(MSG_DEBUG,
5435203eadb9eda41a1dde4a583edb4684319e3f399eDmitry Shmidt				   "P2P: %s: The forced channel for GO (%u MHz) is DFS, and DFS is offloaded to driver",
5436203eadb9eda41a1dde4a583edb4684319e3f399eDmitry Shmidt				__func__, params.freq);
5437203eadb9eda41a1dde4a583edb4684319e3f399eDmitry Shmidt		} else {
5438203eadb9eda41a1dde4a583edb4684319e3f399eDmitry Shmidt			wpa_printf(MSG_DEBUG,
5439203eadb9eda41a1dde4a583edb4684319e3f399eDmitry Shmidt				   "P2P: The selected channel for GO (%u MHz) is not supported for P2P uses",
5440203eadb9eda41a1dde4a583edb4684319e3f399eDmitry Shmidt				   params.freq);
5441203eadb9eda41a1dde4a583edb4684319e3f399eDmitry Shmidt			return -1;
5442203eadb9eda41a1dde4a583edb4684319e3f399eDmitry Shmidt		}
544304949598a23f501be6eec21697465fd46a28840aDmitry Shmidt	}
54448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	p2p_go_params(wpa_s->global->p2p, &params);
54458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	params.persistent_group = persistent_group;
54468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
54478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	wpa_s = wpas_p2p_get_group_iface(wpa_s, 0, 1);
54488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (wpa_s == NULL)
54498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return -1;
54508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	wpas_start_wps_go(wpa_s, &params, 0);
54518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
54528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	return 0;
54538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt}
54548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
54558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
54568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic int wpas_start_p2p_client(struct wpa_supplicant *wpa_s,
545715907098d1f67c24bb000e593e279af173cf57d7Dmitry Shmidt				 struct wpa_ssid *params, int addr_allocated,
545815907098d1f67c24bb000e593e279af173cf57d7Dmitry Shmidt				 int freq)
54598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{
54608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	struct wpa_ssid *ssid;
54618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
54628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	wpa_s = wpas_p2p_get_group_iface(wpa_s, addr_allocated, 0);
54638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (wpa_s == NULL)
54648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return -1;
5465391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt	wpa_s->p2p_last_4way_hs_fail = NULL;
54668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
54678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	wpa_supplicant_ap_deinit(wpa_s);
54688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
54698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	ssid = wpa_config_add_network(wpa_s->conf);
54708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (ssid == NULL)
54718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return -1;
54728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	wpa_config_set_network_defaults(ssid);
54738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	ssid->temporary = 1;
54748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	ssid->proto = WPA_PROTO_RSN;
54758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	ssid->pairwise_cipher = WPA_CIPHER_CCMP;
54768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	ssid->group_cipher = WPA_CIPHER_CCMP;
54778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	ssid->key_mgmt = WPA_KEY_MGMT_PSK;
54788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	ssid->ssid = os_malloc(params->ssid_len);
54798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (ssid->ssid == NULL) {
54808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		wpa_config_remove_network(wpa_s->conf, ssid->id);
54818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return -1;
54828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
54838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	os_memcpy(ssid->ssid, params->ssid, params->ssid_len);
54848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	ssid->ssid_len = params->ssid_len;
54858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	ssid->p2p_group = 1;
54868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	ssid->export_keys = 1;
54878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (params->psk_set) {
54888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		os_memcpy(ssid->psk, params->psk, 32);
54898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		ssid->psk_set = 1;
54908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
54918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (params->passphrase)
54928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		ssid->passphrase = os_strdup(params->passphrase);
54938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
54948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	wpa_s->show_group_started = 1;
549515907098d1f67c24bb000e593e279af173cf57d7Dmitry Shmidt	wpa_s->p2p_in_invitation = 1;
549615907098d1f67c24bb000e593e279af173cf57d7Dmitry Shmidt	wpa_s->p2p_invite_go_freq = freq;
54978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
549815907098d1f67c24bb000e593e279af173cf57d7Dmitry Shmidt	eloop_cancel_timeout(wpas_p2p_group_formation_timeout, wpa_s->parent,
549915907098d1f67c24bb000e593e279af173cf57d7Dmitry Shmidt			     NULL);
550015907098d1f67c24bb000e593e279af173cf57d7Dmitry Shmidt	eloop_register_timeout(P2P_MAX_INITIAL_CONN_WAIT, 0,
550115907098d1f67c24bb000e593e279af173cf57d7Dmitry Shmidt			       wpas_p2p_group_formation_timeout,
550215907098d1f67c24bb000e593e279af173cf57d7Dmitry Shmidt			       wpa_s->parent, NULL);
5503fa3fc4a1ac08ad14272301c7f6f01b362997c3e4Dmitry Shmidt	wpa_supplicant_select_network(wpa_s, ssid);
5504fa3fc4a1ac08ad14272301c7f6f01b362997c3e4Dmitry Shmidt
55058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	return 0;
55068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt}
55078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
55088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
55098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtint wpas_p2p_group_add_persistent(struct wpa_supplicant *wpa_s,
55108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt				  struct wpa_ssid *ssid, int addr_allocated,
551196be6222df414a7dde5c5b1b72df22e67b1a77fcDmitry Shmidt				  int force_freq, int neg_freq, int ht40,
551296be6222df414a7dde5c5b1b72df22e67b1a77fcDmitry Shmidt				  int vht, const struct p2p_channels *channels,
55135605286c30e1701491bd3af974ae423727750eddDmitry Shmidt				  int connection_timeout)
55148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{
55158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	struct p2p_go_neg_results params;
551696be6222df414a7dde5c5b1b72df22e67b1a77fcDmitry Shmidt	int go = 0, freq;
55178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
55188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (ssid->disabled != 2 || ssid->ssid == NULL)
55198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return -1;
55208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
55218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (wpas_get_p2p_group(wpa_s, ssid->ssid, ssid->ssid_len, &go) &&
55228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	    go == (ssid->mode == WPAS_MODE_P2P_GO)) {
55238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		wpa_printf(MSG_DEBUG, "P2P: Requested persistent group is "
55248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			   "already running");
5525b1e52102c211357f585e9ff6d54501e90254326eDmitry Shmidt		if (go == 0 &&
5526b1e52102c211357f585e9ff6d54501e90254326eDmitry Shmidt		    eloop_cancel_timeout(wpas_p2p_group_formation_timeout,
5527b1e52102c211357f585e9ff6d54501e90254326eDmitry Shmidt					 wpa_s->parent, NULL)) {
5528b1e52102c211357f585e9ff6d54501e90254326eDmitry Shmidt			/*
5529b1e52102c211357f585e9ff6d54501e90254326eDmitry Shmidt			 * This can happen if Invitation Response frame was lost
5530b1e52102c211357f585e9ff6d54501e90254326eDmitry Shmidt			 * and the peer (GO of a persistent group) tries to
5531b1e52102c211357f585e9ff6d54501e90254326eDmitry Shmidt			 * invite us again. Reschedule the timeout to avoid
5532b1e52102c211357f585e9ff6d54501e90254326eDmitry Shmidt			 * terminating the wait for the connection too early
5533b1e52102c211357f585e9ff6d54501e90254326eDmitry Shmidt			 * since we now know that the peer is still trying to
5534b1e52102c211357f585e9ff6d54501e90254326eDmitry Shmidt			 * invite us instead of having already started the GO.
5535b1e52102c211357f585e9ff6d54501e90254326eDmitry Shmidt			 */
5536b1e52102c211357f585e9ff6d54501e90254326eDmitry Shmidt			wpa_printf(MSG_DEBUG,
5537b1e52102c211357f585e9ff6d54501e90254326eDmitry Shmidt				   "P2P: Reschedule group formation timeout since peer is still trying to invite us");
5538b1e52102c211357f585e9ff6d54501e90254326eDmitry Shmidt			eloop_register_timeout(P2P_MAX_INITIAL_CONN_WAIT, 0,
5539b1e52102c211357f585e9ff6d54501e90254326eDmitry Shmidt					       wpas_p2p_group_formation_timeout,
5540b1e52102c211357f585e9ff6d54501e90254326eDmitry Shmidt					       wpa_s->parent, NULL);
5541b1e52102c211357f585e9ff6d54501e90254326eDmitry Shmidt		}
55428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return 0;
55438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
55448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
5545391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt	os_free(wpa_s->global->add_psk);
5546391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt	wpa_s->global->add_psk = NULL;
5547391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt
55488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	/* Make sure we are not running find during connection establishment */
5549d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt	wpas_p2p_stop_find_oper(wpa_s);
55508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
555104949598a23f501be6eec21697465fd46a28840aDmitry Shmidt	wpa_s->p2p_fallback_to_go_neg = 0;
555204949598a23f501be6eec21697465fd46a28840aDmitry Shmidt
55536c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt	if (ssid->mode == WPAS_MODE_P2P_GO) {
55546c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt		if (force_freq > 0) {
55556c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt			freq = wpas_p2p_select_go_freq(wpa_s, force_freq);
55566c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt			if (freq < 0)
55576c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt				return -1;
55586c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt		} else {
55596c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt			freq = wpas_p2p_select_go_freq(wpa_s, neg_freq);
55606c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt			if (freq < 0 ||
55616c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt			    (freq > 0 && !freq_included(channels, freq)))
55626c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt				freq = 0;
55636c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt		}
5564912c6ecf72fb2c84fbf17dbd0666492778dbd9fcDmitry Shmidt	} else if (ssid->mode == WPAS_MODE_INFRA) {
55656c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt		freq = neg_freq;
5566912c6ecf72fb2c84fbf17dbd0666492778dbd9fcDmitry Shmidt		if (freq <= 0 || !freq_included(channels, freq)) {
5567912c6ecf72fb2c84fbf17dbd0666492778dbd9fcDmitry Shmidt			struct os_reltime now;
5568912c6ecf72fb2c84fbf17dbd0666492778dbd9fcDmitry Shmidt			struct wpa_bss *bss =
5569912c6ecf72fb2c84fbf17dbd0666492778dbd9fcDmitry Shmidt				wpa_bss_get_p2p_dev_addr(wpa_s, ssid->bssid);
5570912c6ecf72fb2c84fbf17dbd0666492778dbd9fcDmitry Shmidt
5571912c6ecf72fb2c84fbf17dbd0666492778dbd9fcDmitry Shmidt			os_get_reltime(&now);
5572912c6ecf72fb2c84fbf17dbd0666492778dbd9fcDmitry Shmidt			if (bss &&
5573912c6ecf72fb2c84fbf17dbd0666492778dbd9fcDmitry Shmidt			    !os_reltime_expired(&now, &bss->last_update, 5) &&
5574912c6ecf72fb2c84fbf17dbd0666492778dbd9fcDmitry Shmidt			    freq_included(channels, bss->freq))
5575912c6ecf72fb2c84fbf17dbd0666492778dbd9fcDmitry Shmidt				freq = bss->freq;
5576912c6ecf72fb2c84fbf17dbd0666492778dbd9fcDmitry Shmidt			else
5577912c6ecf72fb2c84fbf17dbd0666492778dbd9fcDmitry Shmidt				freq = 0;
5578912c6ecf72fb2c84fbf17dbd0666492778dbd9fcDmitry Shmidt		}
55798bae4138a0356709720a96f3e50b4d734e532c12Dmitry Shmidt
558015907098d1f67c24bb000e593e279af173cf57d7Dmitry Shmidt		return wpas_start_p2p_client(wpa_s, ssid, addr_allocated, freq);
5581912c6ecf72fb2c84fbf17dbd0666492778dbd9fcDmitry Shmidt	} else {
558215907098d1f67c24bb000e593e279af173cf57d7Dmitry Shmidt		return -1;
5583912c6ecf72fb2c84fbf17dbd0666492778dbd9fcDmitry Shmidt	}
558415907098d1f67c24bb000e593e279af173cf57d7Dmitry Shmidt
558568d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt	if (wpas_p2p_init_go_params(wpa_s, &params, freq, ht40, vht, channels))
55861f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt		return -1;
55878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
55888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	params.role_go = 1;
5589d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt	params.psk_set = ssid->psk_set;
5590d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt	if (params.psk_set)
5591d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt		os_memcpy(params.psk, ssid->psk, sizeof(params.psk));
5592a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt	if (ssid->passphrase) {
5593a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt		if (os_strlen(ssid->passphrase) >= sizeof(params.passphrase)) {
5594a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt			wpa_printf(MSG_ERROR, "P2P: Invalid passphrase in "
5595a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt				   "persistent group");
5596a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt			return -1;
5597a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt		}
5598a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt		os_strlcpy(params.passphrase, ssid->passphrase,
5599a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt			   sizeof(params.passphrase));
56008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
56018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	os_memcpy(params.ssid, ssid->ssid, ssid->ssid_len);
56028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	params.ssid_len = ssid->ssid_len;
56038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	params.persistent_group = 1;
56048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
56058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	wpa_s = wpas_p2p_get_group_iface(wpa_s, addr_allocated, 1);
56068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (wpa_s == NULL)
56078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return -1;
56088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
56096c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt	p2p_channels_to_freqs(channels, params.freq_list, P2P_MAX_CHANNELS);
56106c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt
56115605286c30e1701491bd3af974ae423727750eddDmitry Shmidt	wpa_s->p2p_first_connection_timeout = connection_timeout;
56128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	wpas_start_wps_go(wpa_s, &params, 0);
56138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
56148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	return 0;
56158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt}
56168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
56178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
56188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic void wpas_p2p_ie_update(void *ctx, struct wpabuf *beacon_ies,
56198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			       struct wpabuf *proberesp_ies)
56208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{
56218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	struct wpa_supplicant *wpa_s = ctx;
56228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (wpa_s->ap_iface) {
56238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		struct hostapd_data *hapd = wpa_s->ap_iface->bss[0];
56241f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt		if (!(hapd->conf->p2p & P2P_GROUP_OWNER)) {
56251f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt			wpabuf_free(beacon_ies);
56261f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt			wpabuf_free(proberesp_ies);
56271f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt			return;
56281f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt		}
56298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		if (beacon_ies) {
56308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			wpabuf_free(hapd->p2p_beacon_ie);
56318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			hapd->p2p_beacon_ie = beacon_ies;
56328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		}
56338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		wpabuf_free(hapd->p2p_probe_resp_ie);
56348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		hapd->p2p_probe_resp_ie = proberesp_ies;
56358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	} else {
56368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		wpabuf_free(beacon_ies);
56378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		wpabuf_free(proberesp_ies);
56388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
56398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	wpa_supplicant_ap_update_beacon(wpa_s);
56408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt}
56418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
56428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
56438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic void wpas_p2p_idle_update(void *ctx, int idle)
56448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{
56458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	struct wpa_supplicant *wpa_s = ctx;
56468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (!wpa_s->ap_iface)
56478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return;
56488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	wpa_printf(MSG_DEBUG, "P2P: GO - group %sidle", idle ? "" : "not ");
5649fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt	if (idle) {
5650fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt		if (wpa_s->global->p2p_fail_on_wps_complete &&
5651fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt		    wpa_s->p2p_in_provisioning) {
5652fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt			wpas_p2p_grpform_fail_after_wps(wpa_s);
5653fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt			return;
5654fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt		}
56558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		wpas_p2p_set_group_idle_timeout(wpa_s);
5656fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt	} else
56578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		eloop_cancel_timeout(wpas_p2p_group_idle_timeout, wpa_s, NULL);
56588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt}
56598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
56608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
56618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstruct p2p_group * wpas_p2p_group_init(struct wpa_supplicant *wpa_s,
566204949598a23f501be6eec21697465fd46a28840aDmitry Shmidt				       struct wpa_ssid *ssid)
56638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{
56648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	struct p2p_group *group;
56658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	struct p2p_group_config *cfg;
56668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
56678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (wpa_s->global->p2p_disabled || wpa_s->global->p2p == NULL)
56688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return NULL;
56698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
56708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	cfg = os_zalloc(sizeof(*cfg));
56718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (cfg == NULL)
56728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return NULL;
56738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
567404949598a23f501be6eec21697465fd46a28840aDmitry Shmidt	if (ssid->p2p_persistent_group && wpa_s->conf->persistent_reconnect)
56751f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt		cfg->persistent_group = 2;
567604949598a23f501be6eec21697465fd46a28840aDmitry Shmidt	else if (ssid->p2p_persistent_group)
56771f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt		cfg->persistent_group = 1;
56788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	os_memcpy(cfg->interface_addr, wpa_s->own_addr, ETH_ALEN);
56798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (wpa_s->max_stations &&
56808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	    wpa_s->max_stations < wpa_s->conf->max_num_sta)
56818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		cfg->max_clients = wpa_s->max_stations;
56828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	else
56838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		cfg->max_clients = wpa_s->conf->max_num_sta;
568404949598a23f501be6eec21697465fd46a28840aDmitry Shmidt	os_memcpy(cfg->ssid, ssid->ssid, ssid->ssid_len);
568504949598a23f501be6eec21697465fd46a28840aDmitry Shmidt	cfg->ssid_len = ssid->ssid_len;
5686cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt	cfg->freq = ssid->frequency;
56878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	cfg->cb_ctx = wpa_s;
56888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	cfg->ie_update = wpas_p2p_ie_update;
56898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	cfg->idle_update = wpas_p2p_idle_update;
56908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
56918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	group = p2p_group_init(wpa_s->global->p2p, cfg);
56928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (group == NULL)
56938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		os_free(cfg);
569404949598a23f501be6eec21697465fd46a28840aDmitry Shmidt	if (ssid->mode != WPAS_MODE_P2P_GROUP_FORMATION)
56958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		p2p_group_notif_formation_done(group);
56968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	wpa_s->p2p_group = group;
56978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	return group;
56988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt}
56998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
57008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
57018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtvoid wpas_p2p_wps_success(struct wpa_supplicant *wpa_s, const u8 *peer_addr,
57028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			  int registrar)
57038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{
570404949598a23f501be6eec21697465fd46a28840aDmitry Shmidt	struct wpa_ssid *ssid = wpa_s->current_ssid;
570504949598a23f501be6eec21697465fd46a28840aDmitry Shmidt
57068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (!wpa_s->p2p_in_provisioning) {
57078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		wpa_printf(MSG_DEBUG, "P2P: Ignore WPS success event - P2P "
57088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			   "provisioning not in progress");
57098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return;
57108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
57118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
571204949598a23f501be6eec21697465fd46a28840aDmitry Shmidt	if (ssid && ssid->mode == WPAS_MODE_INFRA) {
571304949598a23f501be6eec21697465fd46a28840aDmitry Shmidt		u8 go_dev_addr[ETH_ALEN];
571404949598a23f501be6eec21697465fd46a28840aDmitry Shmidt		os_memcpy(go_dev_addr, wpa_s->bssid, ETH_ALEN);
571504949598a23f501be6eec21697465fd46a28840aDmitry Shmidt		wpas_p2p_persistent_group(wpa_s, go_dev_addr, ssid->ssid,
571604949598a23f501be6eec21697465fd46a28840aDmitry Shmidt					  ssid->ssid_len);
571704949598a23f501be6eec21697465fd46a28840aDmitry Shmidt		/* Clear any stored provisioning info */
571804949598a23f501be6eec21697465fd46a28840aDmitry Shmidt		p2p_clear_provisioning_info(wpa_s->global->p2p, go_dev_addr);
571904949598a23f501be6eec21697465fd46a28840aDmitry Shmidt	}
57201f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt
57218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	eloop_cancel_timeout(wpas_p2p_group_formation_timeout, wpa_s->parent,
57228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			     NULL);
57235605286c30e1701491bd3af974ae423727750eddDmitry Shmidt	wpa_s->p2p_go_group_formation_completed = 1;
572404949598a23f501be6eec21697465fd46a28840aDmitry Shmidt	if (ssid && ssid->mode == WPAS_MODE_INFRA) {
572504949598a23f501be6eec21697465fd46a28840aDmitry Shmidt		/*
572604949598a23f501be6eec21697465fd46a28840aDmitry Shmidt		 * Use a separate timeout for initial data connection to
572704949598a23f501be6eec21697465fd46a28840aDmitry Shmidt		 * complete to allow the group to be removed automatically if
572804949598a23f501be6eec21697465fd46a28840aDmitry Shmidt		 * something goes wrong in this step before the P2P group idle
572904949598a23f501be6eec21697465fd46a28840aDmitry Shmidt		 * timeout mechanism is taken into use.
573004949598a23f501be6eec21697465fd46a28840aDmitry Shmidt		 */
57315605286c30e1701491bd3af974ae423727750eddDmitry Shmidt		wpa_dbg(wpa_s, MSG_DEBUG,
57325605286c30e1701491bd3af974ae423727750eddDmitry Shmidt			"P2P: Re-start group formation timeout (%d seconds) as client for initial connection",
57335605286c30e1701491bd3af974ae423727750eddDmitry Shmidt			P2P_MAX_INITIAL_CONN_WAIT);
573404949598a23f501be6eec21697465fd46a28840aDmitry Shmidt		eloop_register_timeout(P2P_MAX_INITIAL_CONN_WAIT, 0,
573504949598a23f501be6eec21697465fd46a28840aDmitry Shmidt				       wpas_p2p_group_formation_timeout,
573604949598a23f501be6eec21697465fd46a28840aDmitry Shmidt				       wpa_s->parent, NULL);
57375605286c30e1701491bd3af974ae423727750eddDmitry Shmidt	} else if (ssid) {
57385605286c30e1701491bd3af974ae423727750eddDmitry Shmidt		/*
57395605286c30e1701491bd3af974ae423727750eddDmitry Shmidt		 * Use a separate timeout for initial data connection to
57405605286c30e1701491bd3af974ae423727750eddDmitry Shmidt		 * complete to allow the group to be removed automatically if
57415605286c30e1701491bd3af974ae423727750eddDmitry Shmidt		 * the client does not complete data connection successfully.
57425605286c30e1701491bd3af974ae423727750eddDmitry Shmidt		 */
57435605286c30e1701491bd3af974ae423727750eddDmitry Shmidt		wpa_dbg(wpa_s, MSG_DEBUG,
57445605286c30e1701491bd3af974ae423727750eddDmitry Shmidt			"P2P: Re-start group formation timeout (%d seconds) as GO for initial connection",
57455605286c30e1701491bd3af974ae423727750eddDmitry Shmidt			P2P_MAX_INITIAL_CONN_WAIT_GO);
57465605286c30e1701491bd3af974ae423727750eddDmitry Shmidt		eloop_register_timeout(P2P_MAX_INITIAL_CONN_WAIT_GO, 0,
57475605286c30e1701491bd3af974ae423727750eddDmitry Shmidt				       wpas_p2p_group_formation_timeout,
57485605286c30e1701491bd3af974ae423727750eddDmitry Shmidt				       wpa_s->parent, NULL);
57495605286c30e1701491bd3af974ae423727750eddDmitry Shmidt		/*
57505605286c30e1701491bd3af974ae423727750eddDmitry Shmidt		 * Complete group formation on first successful data connection
57515605286c30e1701491bd3af974ae423727750eddDmitry Shmidt		 */
57525605286c30e1701491bd3af974ae423727750eddDmitry Shmidt		wpa_s->p2p_go_group_formation_completed = 0;
575304949598a23f501be6eec21697465fd46a28840aDmitry Shmidt	}
57548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (wpa_s->global->p2p)
57558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		p2p_wps_success_cb(wpa_s->global->p2p, peer_addr);
5756a3dc30964aa24aea2b518246f6812663a1103490Dmitry Shmidt	wpas_group_formation_completed(wpa_s, 1, 0);
57578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt}
57588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
57598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
576075ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinenvoid wpas_p2p_wps_failed(struct wpa_supplicant *wpa_s,
576175ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen			 struct wps_event_fail *fail)
576275ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen{
576375ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen	if (!wpa_s->p2p_in_provisioning) {
576475ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen		wpa_printf(MSG_DEBUG, "P2P: Ignore WPS fail event - P2P "
576575ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen			   "provisioning not in progress");
576675ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen		return;
576775ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen	}
57681f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt
57691f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt	if (wpa_s->go_params) {
57701f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt		p2p_clear_provisioning_info(
57711f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt			wpa_s->global->p2p,
577204949598a23f501be6eec21697465fd46a28840aDmitry Shmidt			wpa_s->go_params->peer_device_addr);
57731f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt	}
57741f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt
577575ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen	wpas_notify_p2p_wps_failed(wpa_s, fail);
5776fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt
5777fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt	if (wpa_s == wpa_s->global->p2p_group_formation) {
5778fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt		/*
5779fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt		 * Allow some time for the failed WPS negotiation exchange to
5780fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt		 * complete, but remove the group since group formation cannot
5781fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt		 * succeed after provisioning failure.
5782fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt		 */
5783fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt		wpa_printf(MSG_DEBUG, "P2P: WPS step failed during group formation - reject connection from timeout");
5784fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt		wpa_s->global->p2p_fail_on_wps_complete = 1;
5785fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt		eloop_deplete_timeout(0, 50000,
5786fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt				      wpas_p2p_group_formation_timeout,
5787fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt				      wpa_s->parent, NULL);
5788fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt	}
5789fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt}
5790fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt
5791fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt
5792fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidtint wpas_p2p_wps_eapol_cb(struct wpa_supplicant *wpa_s)
5793fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt{
5794fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt	if (!wpa_s->global->p2p_fail_on_wps_complete ||
5795fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt	    !wpa_s->p2p_in_provisioning)
5796fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt		return 0;
5797fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt
5798fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt	wpas_p2p_grpform_fail_after_wps(wpa_s);
5799fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt
5800fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt	return 1;
580175ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen}
580275ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen
580375ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen
58048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtint wpas_p2p_prov_disc(struct wpa_supplicant *wpa_s, const u8 *peer_addr,
580504949598a23f501be6eec21697465fd46a28840aDmitry Shmidt		       const char *config_method,
5806216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt		       enum wpas_p2p_prov_disc_use use,
5807216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt		       struct p2ps_provision *p2ps_prov)
58088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{
58098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	u16 config_methods;
58108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
5811216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt	wpa_s->global->pending_p2ps_group = 0;
581204949598a23f501be6eec21697465fd46a28840aDmitry Shmidt	wpa_s->p2p_fallback_to_go_neg = 0;
581304949598a23f501be6eec21697465fd46a28840aDmitry Shmidt	wpa_s->pending_pd_use = NORMAL_PD;
5814216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt	if (p2ps_prov && use == WPAS_P2P_PD_FOR_ASP) {
5815216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt		p2ps_prov->conncap = p2ps_group_capability(
5816216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt			wpa_s, P2PS_SETUP_NONE, p2ps_prov->role);
5817216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt		wpa_printf(MSG_DEBUG,
5818216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt			   "P2P: %s conncap: %d - ASP parsed: %x %x %d %s",
5819216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt			   __func__, p2ps_prov->conncap,
5820216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt			   p2ps_prov->adv_id, p2ps_prov->conncap,
5821216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt			   p2ps_prov->status, p2ps_prov->info);
5822216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt
5823216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt		config_methods = 0;
5824216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt	} else if (os_strncmp(config_method, "display", 7) == 0)
58258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		config_methods = WPS_CONFIG_DISPLAY;
58261f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt	else if (os_strncmp(config_method, "keypad", 6) == 0)
58278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		config_methods = WPS_CONFIG_KEYPAD;
58281f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt	else if (os_strncmp(config_method, "pbc", 3) == 0 ||
58291f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt		 os_strncmp(config_method, "pushbutton", 10) == 0)
58308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		config_methods = WPS_CONFIG_PUSHBUTTON;
58311f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt	else {
58321f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt		wpa_printf(MSG_DEBUG, "P2P: Unknown config method");
5833216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt		os_free(p2ps_prov);
58348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return -1;
58351f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt	}
58368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
583704949598a23f501be6eec21697465fd46a28840aDmitry Shmidt	if (use == WPAS_P2P_PD_AUTO) {
583804949598a23f501be6eec21697465fd46a28840aDmitry Shmidt		os_memcpy(wpa_s->pending_join_dev_addr, peer_addr, ETH_ALEN);
583904949598a23f501be6eec21697465fd46a28840aDmitry Shmidt		wpa_s->pending_pd_config_methods = config_methods;
584004949598a23f501be6eec21697465fd46a28840aDmitry Shmidt		wpa_s->p2p_auto_pd = 1;
584104949598a23f501be6eec21697465fd46a28840aDmitry Shmidt		wpa_s->p2p_auto_join = 0;
584204949598a23f501be6eec21697465fd46a28840aDmitry Shmidt		wpa_s->pending_pd_before_join = 0;
584304949598a23f501be6eec21697465fd46a28840aDmitry Shmidt		wpa_s->auto_pd_scan_retry = 0;
584404949598a23f501be6eec21697465fd46a28840aDmitry Shmidt		wpas_p2p_stop_find(wpa_s);
584504949598a23f501be6eec21697465fd46a28840aDmitry Shmidt		wpa_s->p2p_join_scan_count = 0;
5846fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt		os_get_reltime(&wpa_s->p2p_auto_started);
584704949598a23f501be6eec21697465fd46a28840aDmitry Shmidt		wpa_printf(MSG_DEBUG, "P2P: Auto PD started at %ld.%06ld",
584804949598a23f501be6eec21697465fd46a28840aDmitry Shmidt			   wpa_s->p2p_auto_started.sec,
584904949598a23f501be6eec21697465fd46a28840aDmitry Shmidt			   wpa_s->p2p_auto_started.usec);
585004949598a23f501be6eec21697465fd46a28840aDmitry Shmidt		wpas_p2p_join_scan(wpa_s, NULL);
585104949598a23f501be6eec21697465fd46a28840aDmitry Shmidt		return 0;
585204949598a23f501be6eec21697465fd46a28840aDmitry Shmidt	}
585304949598a23f501be6eec21697465fd46a28840aDmitry Shmidt
5854216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt	if (wpa_s->global->p2p == NULL || wpa_s->global->p2p_disabled) {
5855216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt		os_free(p2ps_prov);
58568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return -1;
5857216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt	}
58588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
5859216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt	return p2p_prov_disc_req(wpa_s->global->p2p, peer_addr, p2ps_prov,
586004949598a23f501be6eec21697465fd46a28840aDmitry Shmidt				 config_methods, use == WPAS_P2P_PD_FOR_JOIN,
5861d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt				 0, 1);
58628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt}
58638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
58648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
58658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtint wpas_p2p_scan_result_text(const u8 *ies, size_t ies_len, char *buf,
58668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			      char *end)
58678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{
58688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	return p2p_scan_result_text(ies, ies_len, buf, end);
58698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt}
58708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
58718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
58728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic void wpas_p2p_clear_pending_action_tx(struct wpa_supplicant *wpa_s)
58738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{
5874a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt	if (!offchannel_pending_action_tx(wpa_s))
58758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return;
58768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
587703658834c33748b9ad86f3d4cdf0c7be9c6887d1Dmitry Shmidt	wpas_p2p_action_tx_clear(wpa_s);
587803658834c33748b9ad86f3d4cdf0c7be9c6887d1Dmitry Shmidt
58798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	wpa_printf(MSG_DEBUG, "P2P: Drop pending Action TX due to new "
58808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		   "operation request");
5881a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt	offchannel_clear_pending_action_tx(wpa_s);
58828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt}
58838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
58848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
58858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtint wpas_p2p_find(struct wpa_supplicant *wpa_s, unsigned int timeout,
58868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		  enum p2p_discovery_type type,
5887c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt		  unsigned int num_req_dev_types, const u8 *req_dev_types,
5888216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt		  const u8 *dev_id, unsigned int search_delay,
5889203eadb9eda41a1dde4a583edb4684319e3f399eDmitry Shmidt		  u8 seek_cnt, const char **seek_string, int freq)
58908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{
58918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	wpas_p2p_clear_pending_action_tx(wpa_s);
58928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	wpa_s->p2p_long_listen = 0;
58938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
589404949598a23f501be6eec21697465fd46a28840aDmitry Shmidt	if (wpa_s->global->p2p_disabled || wpa_s->global->p2p == NULL ||
589504949598a23f501be6eec21697465fd46a28840aDmitry Shmidt	    wpa_s->p2p_in_provisioning)
58968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return -1;
58978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
5898c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt	wpa_supplicant_cancel_sched_scan(wpa_s);
5899c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt
59008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	return p2p_find(wpa_s->global->p2p, timeout, type,
590161d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt			num_req_dev_types, req_dev_types, dev_id,
5902203eadb9eda41a1dde4a583edb4684319e3f399eDmitry Shmidt			search_delay, seek_cnt, seek_string, freq);
59038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt}
59048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
59058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
59066c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidtstatic void wpas_p2p_scan_res_ignore_search(struct wpa_supplicant *wpa_s,
59076c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt					    struct wpa_scan_results *scan_res)
59086c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt{
59096c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt	wpa_printf(MSG_DEBUG, "P2P: Ignore scan results");
59106c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt
59116c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt	if (wpa_s->p2p_scan_work) {
59126c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt		struct wpa_radio_work *work = wpa_s->p2p_scan_work;
59136c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt		wpa_s->p2p_scan_work = NULL;
59146c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt		radio_work_done(work);
59156c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt	}
59166c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt
59176c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt	if (wpa_s->global->p2p_disabled || wpa_s->global->p2p == NULL)
59186c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt		return;
59196c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt
59206c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt	/*
59216c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt	 * Indicate that results have been processed so that the P2P module can
59226c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt	 * continue pending tasks.
59236c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt	 */
59246c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt	p2p_scan_res_handled(wpa_s->global->p2p);
59256c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt}
59266c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt
59276c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt
59286c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidtstatic void wpas_p2p_stop_find_oper(struct wpa_supplicant *wpa_s)
59298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{
59308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	wpas_p2p_clear_pending_action_tx(wpa_s);
59318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	wpa_s->p2p_long_listen = 0;
59328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	eloop_cancel_timeout(wpas_p2p_long_listen_timeout, wpa_s, NULL);
59338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	eloop_cancel_timeout(wpas_p2p_join_scan, wpa_s, NULL);
59348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
59358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (wpa_s->global->p2p)
59368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		p2p_stop_find(wpa_s->global->p2p);
59378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
59386c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt	if (wpa_s->scan_res_handler == wpas_p2p_scan_res_handler) {
59396c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt		wpa_printf(MSG_DEBUG,
59406c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt			   "P2P: Do not consider the scan results after stop_find");
59416c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt		wpa_s->scan_res_handler = wpas_p2p_scan_res_ignore_search;
59426c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt	}
5943d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt}
5944d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt
5945d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt
5946d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidtvoid wpas_p2p_stop_find(struct wpa_supplicant *wpa_s)
5947d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt{
59486c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt	wpas_p2p_stop_find_oper(wpa_s);
5949216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt	if (!wpa_s->global->pending_group_iface_for_p2ps)
5950216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt		wpas_p2p_remove_pending_group_interface(wpa_s);
59518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt}
59528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
59538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
59548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic void wpas_p2p_long_listen_timeout(void *eloop_ctx, void *timeout_ctx)
59558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{
59568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	struct wpa_supplicant *wpa_s = eloop_ctx;
59578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	wpa_s->p2p_long_listen = 0;
59588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt}
59598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
59608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
59618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtint wpas_p2p_listen(struct wpa_supplicant *wpa_s, unsigned int timeout)
59628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{
59638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	int res;
59648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
59658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (wpa_s->global->p2p_disabled || wpa_s->global->p2p == NULL)
59668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return -1;
59678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
5968c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt	wpa_supplicant_cancel_sched_scan(wpa_s);
59698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	wpas_p2p_clear_pending_action_tx(wpa_s);
59708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
59718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (timeout == 0) {
59728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		/*
59738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		 * This is a request for unlimited Listen state. However, at
59748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		 * least for now, this is mapped to a Listen state for one
59758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		 * hour.
59768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		 */
59778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		timeout = 3600;
59788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
59798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	eloop_cancel_timeout(wpas_p2p_long_listen_timeout, wpa_s, NULL);
59808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	wpa_s->p2p_long_listen = 0;
59818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
59821f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt	/*
59831f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt	 * Stop previous find/listen operation to avoid trying to request a new
59841f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt	 * remain-on-channel operation while the driver is still running the
59851f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt	 * previous one.
59861f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt	 */
59871f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt	if (wpa_s->global->p2p)
59881f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt		p2p_stop_find(wpa_s->global->p2p);
59891f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt
59908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	res = wpas_p2p_listen_start(wpa_s, timeout * 1000);
59918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (res == 0 && timeout * 1000 > wpa_s->max_remain_on_chan) {
59928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		wpa_s->p2p_long_listen = timeout * 1000;
59938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		eloop_register_timeout(timeout, 0,
59948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt				       wpas_p2p_long_listen_timeout,
59958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt				       wpa_s, NULL);
59968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
59978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
59988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	return res;
59998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt}
60008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
60018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
60028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtint wpas_p2p_assoc_req_ie(struct wpa_supplicant *wpa_s, struct wpa_bss *bss,
60038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			  u8 *buf, size_t len, int p2p_group)
60048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{
60058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	struct wpabuf *p2p_ie;
60068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	int ret;
60078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
60088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (wpa_s->global->p2p_disabled)
60098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return -1;
60108bd70b7d6ba220544ee2f0e201e5df23e277fa1dDmitry Shmidt	/*
60118bd70b7d6ba220544ee2f0e201e5df23e277fa1dDmitry Shmidt	 * Advertize mandatory cross connection capability even on
60128bd70b7d6ba220544ee2f0e201e5df23e277fa1dDmitry Shmidt	 * p2p_disabled=1 interface when associating with a P2P Manager WLAN AP.
60138bd70b7d6ba220544ee2f0e201e5df23e277fa1dDmitry Shmidt	 */
60148bd70b7d6ba220544ee2f0e201e5df23e277fa1dDmitry Shmidt	if (wpa_s->conf->p2p_disabled && p2p_group)
6015661b4f78e48c697429dc46154a4125892c001718Dmitry Shmidt		return -1;
60168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (wpa_s->global->p2p == NULL)
60178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return -1;
60188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (bss == NULL)
60198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return -1;
60208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
60218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	p2p_ie = wpa_bss_get_vendor_ie_multi(bss, P2P_IE_VENDOR_TYPE);
60228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	ret = p2p_assoc_req_ie(wpa_s->global->p2p, bss->bssid, buf, len,
60238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			       p2p_group, p2p_ie);
60248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	wpabuf_free(p2p_ie);
60258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
60268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	return ret;
60278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt}
60288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
60298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
60308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtint wpas_p2p_probe_req_rx(struct wpa_supplicant *wpa_s, const u8 *addr,
60311f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt			  const u8 *dst, const u8 *bssid,
6032a3dc30964aa24aea2b518246f6812663a1103490Dmitry Shmidt			  const u8 *ie, size_t ie_len,
6033a3dc30964aa24aea2b518246f6812663a1103490Dmitry Shmidt			  unsigned int rx_freq, int ssi_signal)
60348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{
60358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (wpa_s->global->p2p_disabled)
60368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return 0;
60378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (wpa_s->global->p2p == NULL)
60388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return 0;
60398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
604004949598a23f501be6eec21697465fd46a28840aDmitry Shmidt	switch (p2p_probe_req_rx(wpa_s->global->p2p, addr, dst, bssid,
6041a3dc30964aa24aea2b518246f6812663a1103490Dmitry Shmidt				 ie, ie_len, rx_freq)) {
604204949598a23f501be6eec21697465fd46a28840aDmitry Shmidt	case P2P_PREQ_NOT_P2P:
604304949598a23f501be6eec21697465fd46a28840aDmitry Shmidt		wpas_notify_preq(wpa_s, addr, dst, bssid, ie, ie_len,
604404949598a23f501be6eec21697465fd46a28840aDmitry Shmidt				 ssi_signal);
604504949598a23f501be6eec21697465fd46a28840aDmitry Shmidt		/* fall through */
604604949598a23f501be6eec21697465fd46a28840aDmitry Shmidt	case P2P_PREQ_MALFORMED:
604704949598a23f501be6eec21697465fd46a28840aDmitry Shmidt	case P2P_PREQ_NOT_LISTEN:
604804949598a23f501be6eec21697465fd46a28840aDmitry Shmidt	case P2P_PREQ_NOT_PROCESSED:
604904949598a23f501be6eec21697465fd46a28840aDmitry Shmidt	default: /* make gcc happy */
605004949598a23f501be6eec21697465fd46a28840aDmitry Shmidt		return 0;
605104949598a23f501be6eec21697465fd46a28840aDmitry Shmidt	case P2P_PREQ_PROCESSED:
605204949598a23f501be6eec21697465fd46a28840aDmitry Shmidt		return 1;
605304949598a23f501be6eec21697465fd46a28840aDmitry Shmidt	}
60548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt}
60558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
60568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
60578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtvoid wpas_p2p_rx_action(struct wpa_supplicant *wpa_s, const u8 *da,
60588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			const u8 *sa, const u8 *bssid,
60598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			u8 category, const u8 *data, size_t len, int freq)
60608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{
60618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (wpa_s->global->p2p_disabled)
60628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return;
60638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (wpa_s->global->p2p == NULL)
60648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return;
60658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
60668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	p2p_rx_action(wpa_s->global->p2p, da, sa, bssid, category, data, len,
60678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		      freq);
60688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt}
60698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
60708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
60718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtvoid wpas_p2p_scan_ie(struct wpa_supplicant *wpa_s, struct wpabuf *ies)
60728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{
60738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (wpa_s->global->p2p_disabled)
60748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return;
60758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (wpa_s->global->p2p == NULL)
60768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return;
60778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
6078c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt	p2p_scan_ie(wpa_s->global->p2p, ies, NULL);
60798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt}
60808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
60818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
608243cb578dfe2c492257636f6234a24178ed27789eDmitry Shmidtstatic void wpas_p2p_group_deinit(struct wpa_supplicant *wpa_s)
60838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{
60848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	p2p_group_deinit(wpa_s->p2p_group);
60858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	wpa_s->p2p_group = NULL;
60861f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt
60871f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt	wpa_s->ap_configured_cb = NULL;
60881f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt	wpa_s->ap_configured_cb_ctx = NULL;
60891f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt	wpa_s->ap_configured_cb_data = NULL;
60901f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt	wpa_s->connect_without_scan = NULL;
60918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt}
60928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
60938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
60948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtint wpas_p2p_reject(struct wpa_supplicant *wpa_s, const u8 *addr)
60958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{
60968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	wpa_s->p2p_long_listen = 0;
60978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
60988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (wpa_s->global->p2p_disabled || wpa_s->global->p2p == NULL)
60998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return -1;
61008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
61018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	return p2p_reject(wpa_s->global->p2p, addr);
61028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt}
61038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
61048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
61058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt/* Invite to reinvoke a persistent group */
61068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtint wpas_p2p_invite(struct wpa_supplicant *wpa_s, const u8 *peer_addr,
610731be0a4b946ecab910c0a9af3837dbccea5d204bJouni Malinen		    struct wpa_ssid *ssid, const u8 *go_dev_addr, int freq,
610868d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt		    int ht40, int vht, int pref_freq)
61098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{
61108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	enum p2p_invite_role role;
6111c2ebb4b85d69b65f552fee71ac68f44e8d87b39eDmitry Shmidt	u8 *bssid = NULL;
6112c2ebb4b85d69b65f552fee71ac68f44e8d87b39eDmitry Shmidt	int force_freq = 0;
61137a5e50a0554bee77a9da492ea3d86f46147f1671Dmitry Shmidt	int res;
6114a0d265f81180f341d22511538fa18166e1bbce9fDmitry Shmidt	int no_pref_freq_given = pref_freq == 0;
61157a5e50a0554bee77a9da492ea3d86f46147f1671Dmitry Shmidt
6116700a137ab366edc72e371da68ba187b4717ee660Dmitry Shmidt	wpa_s->global->p2p_invite_group = NULL;
61177a5e50a0554bee77a9da492ea3d86f46147f1671Dmitry Shmidt	if (peer_addr)
61187a5e50a0554bee77a9da492ea3d86f46147f1671Dmitry Shmidt		os_memcpy(wpa_s->p2p_auth_invite, peer_addr, ETH_ALEN);
61197a5e50a0554bee77a9da492ea3d86f46147f1671Dmitry Shmidt	else
61207a5e50a0554bee77a9da492ea3d86f46147f1671Dmitry Shmidt		os_memset(wpa_s->p2p_auth_invite, 0, ETH_ALEN);
61218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
612231be0a4b946ecab910c0a9af3837dbccea5d204bJouni Malinen	wpa_s->p2p_persistent_go_freq = freq;
612331be0a4b946ecab910c0a9af3837dbccea5d204bJouni Malinen	wpa_s->p2p_go_ht40 = !!ht40;
61248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (ssid->mode == WPAS_MODE_P2P_GO) {
61258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		role = P2P_INVITE_ROLE_GO;
61268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		if (peer_addr == NULL) {
61278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			wpa_printf(MSG_DEBUG, "P2P: Missing peer "
61288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt				   "address in invitation command");
61298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			return -1;
61308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		}
61318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		if (wpas_p2p_create_iface(wpa_s)) {
61328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			if (wpas_p2p_add_group_interface(wpa_s,
61338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt							 WPA_IF_P2P_GO) < 0) {
61348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt				wpa_printf(MSG_ERROR, "P2P: Failed to "
61358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt					   "allocate a new interface for the "
61368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt					   "group");
61378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt				return -1;
61388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			}
61398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			bssid = wpa_s->pending_interface_addr;
61408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		} else
61418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			bssid = wpa_s->own_addr;
61428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	} else {
61438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		role = P2P_INVITE_ROLE_CLIENT;
61448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		peer_addr = ssid->bssid;
61458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
61468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	wpa_s->pending_invite_ssid_id = ssid->id;
61478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
614868d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt	res = wpas_p2p_setup_freqs(wpa_s, freq, &force_freq, &pref_freq,
614968d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt				   role == P2P_INVITE_ROLE_GO);
61507a5e50a0554bee77a9da492ea3d86f46147f1671Dmitry Shmidt	if (res)
61517a5e50a0554bee77a9da492ea3d86f46147f1671Dmitry Shmidt		return res;
6152af84a575044f6556994fcc124a955fc0ac0a6736Irfan Sheriff
61538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (wpa_s->global->p2p_disabled || wpa_s->global->p2p == NULL)
61548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return -1;
61558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
6156a0d265f81180f341d22511538fa18166e1bbce9fDmitry Shmidt	if (wpa_s->parent->conf->p2p_ignore_shared_freq &&
6157a0d265f81180f341d22511538fa18166e1bbce9fDmitry Shmidt	    no_pref_freq_given && pref_freq > 0 &&
6158a0d265f81180f341d22511538fa18166e1bbce9fDmitry Shmidt	    wpa_s->num_multichan_concurrent > 1 &&
6159a0d265f81180f341d22511538fa18166e1bbce9fDmitry Shmidt	    wpas_p2p_num_unused_channels(wpa_s) > 0) {
6160a0d265f81180f341d22511538fa18166e1bbce9fDmitry Shmidt		wpa_printf(MSG_DEBUG, "P2P: Ignore own channel preference %d MHz for invitation due to p2p_ignore_shared_freq=1 configuration",
6161a0d265f81180f341d22511538fa18166e1bbce9fDmitry Shmidt			   pref_freq);
6162a0d265f81180f341d22511538fa18166e1bbce9fDmitry Shmidt		pref_freq = 0;
6163a0d265f81180f341d22511538fa18166e1bbce9fDmitry Shmidt	}
6164a0d265f81180f341d22511538fa18166e1bbce9fDmitry Shmidt
61652f74e36e84064ffa32f82f3decf36b653c7e4fadDmitry Shmidt	/*
61662f74e36e84064ffa32f82f3decf36b653c7e4fadDmitry Shmidt	 * Stop any find/listen operations before invitation and possibly
61672f74e36e84064ffa32f82f3decf36b653c7e4fadDmitry Shmidt	 * connection establishment.
61682f74e36e84064ffa32f82f3decf36b653c7e4fadDmitry Shmidt	 */
61692f74e36e84064ffa32f82f3decf36b653c7e4fadDmitry Shmidt	wpas_p2p_stop_find_oper(wpa_s);
61702f74e36e84064ffa32f82f3decf36b653c7e4fadDmitry Shmidt
61718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	return p2p_invite(wpa_s->global->p2p, peer_addr, role, bssid,
61727a5e50a0554bee77a9da492ea3d86f46147f1671Dmitry Shmidt			  ssid->ssid, ssid->ssid_len, force_freq, go_dev_addr,
6173cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt			  1, pref_freq, -1);
61748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt}
61758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
61768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
61778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt/* Invite to join an active group */
61788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtint wpas_p2p_invite_group(struct wpa_supplicant *wpa_s, const char *ifname,
61798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			  const u8 *peer_addr, const u8 *go_dev_addr)
61808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{
61818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	struct wpa_global *global = wpa_s->global;
61828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	enum p2p_invite_role role;
6183c2ebb4b85d69b65f552fee71ac68f44e8d87b39eDmitry Shmidt	u8 *bssid = NULL;
61848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	struct wpa_ssid *ssid;
6185c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt	int persistent;
6186051af73b8f8014eff33330aead0f36944b3403e6Dmitry Shmidt	int freq = 0, force_freq = 0, pref_freq = 0;
61877a5e50a0554bee77a9da492ea3d86f46147f1671Dmitry Shmidt	int res;
61888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
618931be0a4b946ecab910c0a9af3837dbccea5d204bJouni Malinen	wpa_s->p2p_persistent_go_freq = 0;
619031be0a4b946ecab910c0a9af3837dbccea5d204bJouni Malinen	wpa_s->p2p_go_ht40 = 0;
619168d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt	wpa_s->p2p_go_vht = 0;
619231be0a4b946ecab910c0a9af3837dbccea5d204bJouni Malinen
61938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	for (wpa_s = global->ifaces; wpa_s; wpa_s = wpa_s->next) {
61948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		if (os_strcmp(wpa_s->ifname, ifname) == 0)
61958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			break;
61968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
61978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (wpa_s == NULL) {
61988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		wpa_printf(MSG_DEBUG, "P2P: Interface '%s' not found", ifname);
61998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return -1;
62008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
62018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
62028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	ssid = wpa_s->current_ssid;
62038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (ssid == NULL) {
62048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		wpa_printf(MSG_DEBUG, "P2P: No current SSID to use for "
62058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			   "invitation");
62068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return -1;
62078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
62088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
6209700a137ab366edc72e371da68ba187b4717ee660Dmitry Shmidt	wpa_s->global->p2p_invite_group = wpa_s;
6210c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt	persistent = ssid->p2p_persistent_group &&
6211c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt		wpas_p2p_get_persistent(wpa_s->parent, peer_addr,
6212c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt					ssid->ssid, ssid->ssid_len);
6213c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt
62148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (ssid->mode == WPAS_MODE_P2P_GO) {
62158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		role = P2P_INVITE_ROLE_ACTIVE_GO;
62168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		bssid = wpa_s->own_addr;
62178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		if (go_dev_addr == NULL)
62181f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt			go_dev_addr = wpa_s->global->p2p_dev_addr;
6219051af73b8f8014eff33330aead0f36944b3403e6Dmitry Shmidt		freq = ssid->frequency;
62208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	} else {
62218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		role = P2P_INVITE_ROLE_CLIENT;
62228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		if (wpa_s->wpa_state < WPA_ASSOCIATED) {
62238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			wpa_printf(MSG_DEBUG, "P2P: Not associated - cannot "
62248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt				   "invite to current group");
62258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			return -1;
62268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		}
62278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		bssid = wpa_s->bssid;
62288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		if (go_dev_addr == NULL &&
62298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		    !is_zero_ether_addr(wpa_s->go_dev_addr))
62308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			go_dev_addr = wpa_s->go_dev_addr;
6231051af73b8f8014eff33330aead0f36944b3403e6Dmitry Shmidt		freq = wpa_s->current_bss ? wpa_s->current_bss->freq :
6232051af73b8f8014eff33330aead0f36944b3403e6Dmitry Shmidt			(int) wpa_s->assoc_freq;
62338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
62348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	wpa_s->parent->pending_invite_ssid_id = -1;
62358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
62368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (wpa_s->global->p2p_disabled || wpa_s->global->p2p == NULL)
62378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return -1;
62388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
623968d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt	res = wpas_p2p_setup_freqs(wpa_s, freq, &force_freq, &pref_freq,
624068d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt				   role == P2P_INVITE_ROLE_ACTIVE_GO);
62417a5e50a0554bee77a9da492ea3d86f46147f1671Dmitry Shmidt	if (res)
62427a5e50a0554bee77a9da492ea3d86f46147f1671Dmitry Shmidt		return res;
6243c2ebb4b85d69b65f552fee71ac68f44e8d87b39eDmitry Shmidt	wpas_p2p_set_own_freq_preference(wpa_s, force_freq);
62447a5e50a0554bee77a9da492ea3d86f46147f1671Dmitry Shmidt
62458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	return p2p_invite(wpa_s->global->p2p, peer_addr, role, bssid,
62467a5e50a0554bee77a9da492ea3d86f46147f1671Dmitry Shmidt			  ssid->ssid, ssid->ssid_len, force_freq,
6247cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt			  go_dev_addr, persistent, pref_freq, -1);
62488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt}
62498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
62508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
62518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtvoid wpas_p2p_completed(struct wpa_supplicant *wpa_s)
62528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{
62538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	struct wpa_ssid *ssid = wpa_s->current_ssid;
62548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	u8 go_dev_addr[ETH_ALEN];
625575ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen	int network_id = -1;
62568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	int persistent;
62571f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt	int freq;
6258cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt	u8 ip[3 * 4];
6259cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt	char ip_addr[100];
62608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
626104949598a23f501be6eec21697465fd46a28840aDmitry Shmidt	if (ssid == NULL || ssid->mode != WPAS_MODE_P2P_GROUP_FORMATION) {
626204949598a23f501be6eec21697465fd46a28840aDmitry Shmidt		eloop_cancel_timeout(wpas_p2p_group_formation_timeout,
626304949598a23f501be6eec21697465fd46a28840aDmitry Shmidt				     wpa_s->parent, NULL);
626404949598a23f501be6eec21697465fd46a28840aDmitry Shmidt	}
626504949598a23f501be6eec21697465fd46a28840aDmitry Shmidt
62668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (!wpa_s->show_group_started || !ssid)
6267fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt		return;
62688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
62698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	wpa_s->show_group_started = 0;
62708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
62718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	os_memset(go_dev_addr, 0, ETH_ALEN);
62728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (ssid->bssid_set)
62738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		os_memcpy(go_dev_addr, ssid->bssid, ETH_ALEN);
62748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	persistent = wpas_p2p_persistent_group(wpa_s, go_dev_addr, ssid->ssid,
62758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt					       ssid->ssid_len);
62768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	os_memcpy(wpa_s->go_dev_addr, go_dev_addr, ETH_ALEN);
62778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
62788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (wpa_s->global->p2p_group_formation == wpa_s)
62798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		wpa_s->global->p2p_group_formation = NULL;
62808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
62811f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt	freq = wpa_s->current_bss ? wpa_s->current_bss->freq :
62821f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt		(int) wpa_s->assoc_freq;
6283cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt
6284cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt	ip_addr[0] = '\0';
6285cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt	if (wpa_sm_get_p2p_ip_addr(wpa_s->wpa, ip) == 0) {
62866c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt		int res;
62876c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt
62886c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt		res = os_snprintf(ip_addr, sizeof(ip_addr),
62896c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt				  " ip_addr=%u.%u.%u.%u "
62906c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt				  "ip_mask=%u.%u.%u.%u go_ip_addr=%u.%u.%u.%u",
62916c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt				  ip[0], ip[1], ip[2], ip[3],
62926c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt				  ip[4], ip[5], ip[6], ip[7],
62936c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt				  ip[8], ip[9], ip[10], ip[11]);
62946c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt		if (os_snprintf_error(sizeof(ip_addr), res))
62956c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt			ip_addr[0] = '\0';
6296cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt	}
6297cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt
62987f0b69e88015ca077ef7a417fde0a76c10df23a5Dmitry Shmidt	wpas_p2p_group_started(wpa_s, 0, ssid, freq,
62997f0b69e88015ca077ef7a417fde0a76c10df23a5Dmitry Shmidt			       ssid->passphrase == NULL && ssid->psk_set ?
63007f0b69e88015ca077ef7a417fde0a76c10df23a5Dmitry Shmidt			       ssid->psk : NULL,
63017f0b69e88015ca077ef7a417fde0a76c10df23a5Dmitry Shmidt			       ssid->passphrase, go_dev_addr, persistent,
63027f0b69e88015ca077ef7a417fde0a76c10df23a5Dmitry Shmidt			       ip_addr);
63038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
63048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (persistent)
630575ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen		network_id = wpas_p2p_store_persistent_group(wpa_s->parent,
630675ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen							     ssid, go_dev_addr);
630775ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen	if (network_id < 0)
630875ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen		network_id = ssid->id;
630975ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen	wpas_notify_p2p_group_started(wpa_s, ssid, network_id, 1);
63108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt}
63118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
63128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
63138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtint wpas_p2p_presence_req(struct wpa_supplicant *wpa_s, u32 duration1,
63148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			  u32 interval1, u32 duration2, u32 interval2)
63158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{
6316fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt	int ret;
6317fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt
63188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (wpa_s->global->p2p_disabled || wpa_s->global->p2p == NULL)
63198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return -1;
63208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
63218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (wpa_s->wpa_state < WPA_ASSOCIATED ||
63228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	    wpa_s->current_ssid == NULL ||
63238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	    wpa_s->current_ssid->mode != WPAS_MODE_INFRA)
63248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return -1;
63258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
6326fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt	ret = p2p_presence_req(wpa_s->global->p2p, wpa_s->bssid,
6327fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt			       wpa_s->own_addr, wpa_s->assoc_freq,
6328fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt			       duration1, interval1, duration2, interval2);
6329fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt	if (ret == 0)
6330fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt		wpa_s->waiting_presence_resp = 1;
6331fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt
6332fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt	return ret;
63338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt}
63348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
63358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
63368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtint wpas_p2p_ext_listen(struct wpa_supplicant *wpa_s, unsigned int period,
63378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			unsigned int interval)
63388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{
63398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (wpa_s->global->p2p_disabled || wpa_s->global->p2p == NULL)
63408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return -1;
63418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
63428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	return p2p_ext_listen(wpa_s->global->p2p, period, interval);
63438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt}
63448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
63458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
63461f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidtstatic int wpas_p2p_is_client(struct wpa_supplicant *wpa_s)
63471f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt{
6348d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt	if (wpa_s->current_ssid == NULL) {
6349d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt		/*
6350d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt		 * current_ssid can be cleared when P2P client interface gets
6351d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt		 * disconnected, so assume this interface was used as P2P
6352d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt		 * client.
6353d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt		 */
6354d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt		return 1;
6355d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt	}
6356d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt	return wpa_s->current_ssid->p2p_group &&
63571f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt		wpa_s->current_ssid->mode == WPAS_MODE_INFRA;
63581f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt}
63591f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt
63601f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt
63618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic void wpas_p2p_group_idle_timeout(void *eloop_ctx, void *timeout_ctx)
63628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{
63638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	struct wpa_supplicant *wpa_s = eloop_ctx;
63648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
63651f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt	if (wpa_s->conf->p2p_group_idle == 0 && !wpas_p2p_is_client(wpa_s)) {
63668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		wpa_printf(MSG_DEBUG, "P2P: Ignore group idle timeout - "
63678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			   "disabled");
63688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return;
63698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
63708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
637104949598a23f501be6eec21697465fd46a28840aDmitry Shmidt	wpa_printf(MSG_DEBUG, "P2P: Group idle timeout reached - terminate "
637204949598a23f501be6eec21697465fd46a28840aDmitry Shmidt		   "group");
637361d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt	wpas_p2p_group_delete(wpa_s, P2P_GROUP_REMOVAL_IDLE_TIMEOUT);
63748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt}
63758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
63768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
63778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic void wpas_p2p_set_group_idle_timeout(struct wpa_supplicant *wpa_s)
63788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{
637904949598a23f501be6eec21697465fd46a28840aDmitry Shmidt	int timeout;
638004949598a23f501be6eec21697465fd46a28840aDmitry Shmidt
638104949598a23f501be6eec21697465fd46a28840aDmitry Shmidt	if (eloop_cancel_timeout(wpas_p2p_group_idle_timeout, wpa_s, NULL) > 0)
638204949598a23f501be6eec21697465fd46a28840aDmitry Shmidt		wpa_printf(MSG_DEBUG, "P2P: Cancelled P2P group idle timeout");
63831f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt
63841f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt	if (wpa_s->current_ssid == NULL || !wpa_s->current_ssid->p2p_group)
63858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return;
63868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
63871f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt	timeout = wpa_s->conf->p2p_group_idle;
63881f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt	if (wpa_s->current_ssid->mode == WPAS_MODE_INFRA &&
63891f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt	    (timeout == 0 || timeout > P2P_MAX_CLIENT_IDLE))
63901f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt	    timeout = P2P_MAX_CLIENT_IDLE;
63911f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt
63921f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt	if (timeout == 0)
63938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return;
63948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
639504949598a23f501be6eec21697465fd46a28840aDmitry Shmidt	if (timeout < 0) {
639604949598a23f501be6eec21697465fd46a28840aDmitry Shmidt		if (wpa_s->current_ssid->mode == WPAS_MODE_INFRA)
639704949598a23f501be6eec21697465fd46a28840aDmitry Shmidt			timeout = 0; /* special client mode no-timeout */
639804949598a23f501be6eec21697465fd46a28840aDmitry Shmidt		else
639904949598a23f501be6eec21697465fd46a28840aDmitry Shmidt			return;
640004949598a23f501be6eec21697465fd46a28840aDmitry Shmidt	}
640104949598a23f501be6eec21697465fd46a28840aDmitry Shmidt
640204949598a23f501be6eec21697465fd46a28840aDmitry Shmidt	if (wpa_s->p2p_in_provisioning) {
640304949598a23f501be6eec21697465fd46a28840aDmitry Shmidt		/*
640404949598a23f501be6eec21697465fd46a28840aDmitry Shmidt		 * Use the normal group formation timeout during the
640504949598a23f501be6eec21697465fd46a28840aDmitry Shmidt		 * provisioning phase to avoid terminating this process too
640604949598a23f501be6eec21697465fd46a28840aDmitry Shmidt		 * early due to group idle timeout.
640704949598a23f501be6eec21697465fd46a28840aDmitry Shmidt		 */
640804949598a23f501be6eec21697465fd46a28840aDmitry Shmidt		wpa_printf(MSG_DEBUG, "P2P: Do not use P2P group idle timeout "
640904949598a23f501be6eec21697465fd46a28840aDmitry Shmidt			   "during provisioning");
641004949598a23f501be6eec21697465fd46a28840aDmitry Shmidt		return;
641104949598a23f501be6eec21697465fd46a28840aDmitry Shmidt	}
64129e4e8acef07b7053e93024a621489286900b9ec7Deepthi Gowri
641304949598a23f501be6eec21697465fd46a28840aDmitry Shmidt	if (wpa_s->show_group_started) {
641404949598a23f501be6eec21697465fd46a28840aDmitry Shmidt		/*
641504949598a23f501be6eec21697465fd46a28840aDmitry Shmidt		 * Use the normal group formation timeout between the end of
641604949598a23f501be6eec21697465fd46a28840aDmitry Shmidt		 * the provisioning phase and completion of 4-way handshake to
641704949598a23f501be6eec21697465fd46a28840aDmitry Shmidt		 * avoid terminating this process too early due to group idle
641804949598a23f501be6eec21697465fd46a28840aDmitry Shmidt		 * timeout.
641904949598a23f501be6eec21697465fd46a28840aDmitry Shmidt		 */
642004949598a23f501be6eec21697465fd46a28840aDmitry Shmidt		wpa_printf(MSG_DEBUG, "P2P: Do not use P2P group idle timeout "
642104949598a23f501be6eec21697465fd46a28840aDmitry Shmidt			   "while waiting for initial 4-way handshake to "
642204949598a23f501be6eec21697465fd46a28840aDmitry Shmidt			   "complete");
642304949598a23f501be6eec21697465fd46a28840aDmitry Shmidt		return;
642404949598a23f501be6eec21697465fd46a28840aDmitry Shmidt	}
642504949598a23f501be6eec21697465fd46a28840aDmitry Shmidt
64268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	wpa_printf(MSG_DEBUG, "P2P: Set P2P group idle timeout to %u seconds",
64271f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt		   timeout);
64281f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt	eloop_register_timeout(timeout, 0, wpas_p2p_group_idle_timeout,
64291f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt			       wpa_s, NULL);
64308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt}
64318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
64328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
64332b89da85b8cfe9bb862e8dd334855263c3522c00Jouni Malinen/* Returns 1 if the interface was removed */
64342b89da85b8cfe9bb862e8dd334855263c3522c00Jouni Malinenint wpas_p2p_deauth_notif(struct wpa_supplicant *wpa_s, const u8 *bssid,
64352b89da85b8cfe9bb862e8dd334855263c3522c00Jouni Malinen			  u16 reason_code, const u8 *ie, size_t ie_len,
64362b89da85b8cfe9bb862e8dd334855263c3522c00Jouni Malinen			  int locally_generated)
64378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{
64388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (wpa_s->global->p2p_disabled || wpa_s->global->p2p == NULL)
64392b89da85b8cfe9bb862e8dd334855263c3522c00Jouni Malinen		return 0;
64408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
644104949598a23f501be6eec21697465fd46a28840aDmitry Shmidt	if (!locally_generated)
644204949598a23f501be6eec21697465fd46a28840aDmitry Shmidt		p2p_deauth_notif(wpa_s->global->p2p, bssid, reason_code, ie,
644304949598a23f501be6eec21697465fd46a28840aDmitry Shmidt				 ie_len);
644404949598a23f501be6eec21697465fd46a28840aDmitry Shmidt
644504949598a23f501be6eec21697465fd46a28840aDmitry Shmidt	if (reason_code == WLAN_REASON_DEAUTH_LEAVING && !locally_generated &&
644604949598a23f501be6eec21697465fd46a28840aDmitry Shmidt	    wpa_s->current_ssid &&
644704949598a23f501be6eec21697465fd46a28840aDmitry Shmidt	    wpa_s->current_ssid->p2p_group &&
644804949598a23f501be6eec21697465fd46a28840aDmitry Shmidt	    wpa_s->current_ssid->mode == WPAS_MODE_INFRA) {
644904949598a23f501be6eec21697465fd46a28840aDmitry Shmidt		wpa_printf(MSG_DEBUG, "P2P: GO indicated that the P2P Group "
645004949598a23f501be6eec21697465fd46a28840aDmitry Shmidt			   "session is ending");
64512b89da85b8cfe9bb862e8dd334855263c3522c00Jouni Malinen		if (wpas_p2p_group_delete(wpa_s,
64522b89da85b8cfe9bb862e8dd334855263c3522c00Jouni Malinen					  P2P_GROUP_REMOVAL_GO_ENDING_SESSION)
64532b89da85b8cfe9bb862e8dd334855263c3522c00Jouni Malinen		    > 0)
64542b89da85b8cfe9bb862e8dd334855263c3522c00Jouni Malinen			return 1;
645504949598a23f501be6eec21697465fd46a28840aDmitry Shmidt	}
64562b89da85b8cfe9bb862e8dd334855263c3522c00Jouni Malinen
64572b89da85b8cfe9bb862e8dd334855263c3522c00Jouni Malinen	return 0;
64588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt}
64598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
64608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
64618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtvoid wpas_p2p_disassoc_notif(struct wpa_supplicant *wpa_s, const u8 *bssid,
646204949598a23f501be6eec21697465fd46a28840aDmitry Shmidt			     u16 reason_code, const u8 *ie, size_t ie_len,
646304949598a23f501be6eec21697465fd46a28840aDmitry Shmidt			     int locally_generated)
64648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{
64658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (wpa_s->global->p2p_disabled || wpa_s->global->p2p == NULL)
64668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return;
64678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
646804949598a23f501be6eec21697465fd46a28840aDmitry Shmidt	if (!locally_generated)
646904949598a23f501be6eec21697465fd46a28840aDmitry Shmidt		p2p_disassoc_notif(wpa_s->global->p2p, bssid, reason_code, ie,
647004949598a23f501be6eec21697465fd46a28840aDmitry Shmidt				   ie_len);
64718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt}
64728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
64738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
64748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtvoid wpas_p2p_update_config(struct wpa_supplicant *wpa_s)
64758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{
64768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	struct p2p_data *p2p = wpa_s->global->p2p;
64778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
64788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (p2p == NULL)
64798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return;
64808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
64818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (!(wpa_s->drv_flags & WPA_DRIVER_FLAGS_P2P_CAPABLE))
64828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return;
64838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
64848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (wpa_s->conf->changed_parameters & CFG_CHANGED_DEVICE_NAME)
64858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		p2p_set_dev_name(p2p, wpa_s->conf->device_name);
64868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
64878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (wpa_s->conf->changed_parameters & CFG_CHANGED_DEVICE_TYPE)
64888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		p2p_set_pri_dev_type(p2p, wpa_s->conf->device_type);
64898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
64908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (wpa_s->wps &&
64918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	    (wpa_s->conf->changed_parameters & CFG_CHANGED_CONFIG_METHODS))
64928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		p2p_set_config_methods(p2p, wpa_s->wps->config_methods);
64938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
64948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (wpa_s->wps && (wpa_s->conf->changed_parameters & CFG_CHANGED_UUID))
64958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		p2p_set_uuid(p2p, wpa_s->wps->uuid);
64968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
64978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (wpa_s->conf->changed_parameters & CFG_CHANGED_WPS_STRING) {
64988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		p2p_set_manufacturer(p2p, wpa_s->conf->manufacturer);
64998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		p2p_set_model_name(p2p, wpa_s->conf->model_name);
65008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		p2p_set_model_number(p2p, wpa_s->conf->model_number);
65018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		p2p_set_serial_number(p2p, wpa_s->conf->serial_number);
65028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
65038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
65048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (wpa_s->conf->changed_parameters & CFG_CHANGED_SEC_DEVICE_TYPE)
65058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		p2p_set_sec_dev_types(p2p,
65068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt				      (void *) wpa_s->conf->sec_device_type,
65078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt				      wpa_s->conf->num_sec_device_types);
65088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
65098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (wpa_s->conf->changed_parameters & CFG_CHANGED_VENDOR_EXTENSION) {
65108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		int i;
65118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		p2p_remove_wps_vendor_extensions(p2p);
65128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		for (i = 0; i < MAX_WPS_VENDOR_EXT; i++) {
65138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			if (wpa_s->conf->wps_vendor_ext[i] == NULL)
65148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt				continue;
65158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			p2p_add_wps_vendor_extension(
65168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt				p2p, wpa_s->conf->wps_vendor_ext[i]);
65178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		}
65188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
65198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
65208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if ((wpa_s->conf->changed_parameters & CFG_CHANGED_COUNTRY) &&
65218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	    wpa_s->conf->country[0] && wpa_s->conf->country[1]) {
65228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		char country[3];
65238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		country[0] = wpa_s->conf->country[0];
65248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		country[1] = wpa_s->conf->country[1];
65258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		country[2] = 0x04;
65268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		p2p_set_country(p2p, country);
65278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
65288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
65298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (wpa_s->conf->changed_parameters & CFG_CHANGED_P2P_SSID_POSTFIX) {
65308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		p2p_set_ssid_postfix(p2p, (u8 *) wpa_s->conf->p2p_ssid_postfix,
65318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt				     wpa_s->conf->p2p_ssid_postfix ?
65328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt				     os_strlen(wpa_s->conf->p2p_ssid_postfix) :
65338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt				     0);
65348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
65358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
65368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (wpa_s->conf->changed_parameters & CFG_CHANGED_P2P_INTRA_BSS)
65378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		p2p_set_intra_bss_dist(p2p, wpa_s->conf->p2p_intra_bss);
653875ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen
653975ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen	if (wpa_s->conf->changed_parameters & CFG_CHANGED_P2P_LISTEN_CHANNEL) {
654075ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen		u8 reg_class, channel;
654175ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen		int ret;
654275ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen		unsigned int r;
654343cb578dfe2c492257636f6234a24178ed27789eDmitry Shmidt		u8 channel_forced;
654443cb578dfe2c492257636f6234a24178ed27789eDmitry Shmidt
654575ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen		if (wpa_s->conf->p2p_listen_reg_class &&
654675ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen		    wpa_s->conf->p2p_listen_channel) {
654775ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen			reg_class = wpa_s->conf->p2p_listen_reg_class;
654875ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen			channel = wpa_s->conf->p2p_listen_channel;
654943cb578dfe2c492257636f6234a24178ed27789eDmitry Shmidt			channel_forced = 1;
655075ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen		} else {
655175ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen			reg_class = 81;
655275ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen			/*
655375ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen			 * Pick one of the social channels randomly as the
655475ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen			 * listen channel.
655575ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen			 */
6556661b4f78e48c697429dc46154a4125892c001718Dmitry Shmidt			if (os_get_random((u8 *) &r, sizeof(r)) < 0)
6557661b4f78e48c697429dc46154a4125892c001718Dmitry Shmidt				channel = 1;
6558661b4f78e48c697429dc46154a4125892c001718Dmitry Shmidt			else
6559661b4f78e48c697429dc46154a4125892c001718Dmitry Shmidt				channel = 1 + (r % 3) * 5;
656043cb578dfe2c492257636f6234a24178ed27789eDmitry Shmidt			channel_forced = 0;
656175ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen		}
656243cb578dfe2c492257636f6234a24178ed27789eDmitry Shmidt		ret = p2p_set_listen_channel(p2p, reg_class, channel,
656343cb578dfe2c492257636f6234a24178ed27789eDmitry Shmidt					     channel_forced);
656475ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen		if (ret)
656575ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen			wpa_printf(MSG_ERROR, "P2P: Own listen channel update "
656675ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen				   "failed: %d", ret);
656775ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen	}
656875ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen	if (wpa_s->conf->changed_parameters & CFG_CHANGED_P2P_OPER_CHANNEL) {
656975ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen		u8 op_reg_class, op_channel, cfg_op_channel;
657075ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen		int ret = 0;
657175ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen		unsigned int r;
657275ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen		if (wpa_s->conf->p2p_oper_reg_class &&
657375ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen		    wpa_s->conf->p2p_oper_channel) {
657475ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen			op_reg_class = wpa_s->conf->p2p_oper_reg_class;
657575ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen			op_channel = wpa_s->conf->p2p_oper_channel;
657675ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen			cfg_op_channel = 1;
657775ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen		} else {
657875ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen			op_reg_class = 81;
657975ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen			/*
658075ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen			 * Use random operation channel from (1, 6, 11)
658175ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen			 *if no other preference is indicated.
658275ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen			 */
6583661b4f78e48c697429dc46154a4125892c001718Dmitry Shmidt			if (os_get_random((u8 *) &r, sizeof(r)) < 0)
6584661b4f78e48c697429dc46154a4125892c001718Dmitry Shmidt				op_channel = 1;
6585661b4f78e48c697429dc46154a4125892c001718Dmitry Shmidt			else
6586661b4f78e48c697429dc46154a4125892c001718Dmitry Shmidt				op_channel = 1 + (r % 3) * 5;
658775ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen			cfg_op_channel = 0;
658875ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen		}
658975ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen		ret = p2p_set_oper_channel(p2p, op_reg_class, op_channel,
659075ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen					   cfg_op_channel);
659175ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen		if (ret)
659275ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen			wpa_printf(MSG_ERROR, "P2P: Own oper channel update "
659375ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen				   "failed: %d", ret);
659475ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen	}
659504949598a23f501be6eec21697465fd46a28840aDmitry Shmidt
659604949598a23f501be6eec21697465fd46a28840aDmitry Shmidt	if (wpa_s->conf->changed_parameters & CFG_CHANGED_P2P_PREF_CHAN) {
659704949598a23f501be6eec21697465fd46a28840aDmitry Shmidt		if (p2p_set_pref_chan(p2p, wpa_s->conf->num_p2p_pref_chan,
659804949598a23f501be6eec21697465fd46a28840aDmitry Shmidt				      wpa_s->conf->p2p_pref_chan) < 0) {
659904949598a23f501be6eec21697465fd46a28840aDmitry Shmidt			wpa_printf(MSG_ERROR, "P2P: Preferred channel list "
660004949598a23f501be6eec21697465fd46a28840aDmitry Shmidt				   "update failed");
660104949598a23f501be6eec21697465fd46a28840aDmitry Shmidt		}
660268d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt
660368d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt		if (p2p_set_no_go_freq(p2p, &wpa_s->conf->p2p_no_go_freq) < 0) {
660468d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt			wpa_printf(MSG_ERROR, "P2P: No GO channel list "
660568d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt				   "update failed");
660668d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt		}
660704949598a23f501be6eec21697465fd46a28840aDmitry Shmidt	}
66082271d3fdd5982d0e5e81cf9999a861bba933eacbDmitry Shmidt
66092271d3fdd5982d0e5e81cf9999a861bba933eacbDmitry Shmidt	if (wpa_s->conf->changed_parameters & CFG_CHANGED_P2P_PASSPHRASE_LEN)
66102271d3fdd5982d0e5e81cf9999a861bba933eacbDmitry Shmidt		p2p_set_passphrase_len(p2p, wpa_s->conf->p2p_passphrase_len);
66118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt}
66128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
66138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
66148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtint wpas_p2p_set_noa(struct wpa_supplicant *wpa_s, u8 count, int start,
66158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		     int duration)
66168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{
66178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (!wpa_s->ap_iface)
66188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return -1;
66198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	return hostapd_p2p_set_noa(wpa_s->ap_iface->bss[0], count, start,
66208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt				   duration);
66218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt}
66228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
66238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
66248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtint wpas_p2p_set_cross_connect(struct wpa_supplicant *wpa_s, int enabled)
66258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{
66268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (wpa_s->global->p2p_disabled || wpa_s->global->p2p == NULL)
66278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return -1;
66288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
66298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	wpa_s->global->cross_connection = enabled;
66308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	p2p_set_cross_connect(wpa_s->global->p2p, enabled);
66318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
66328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (!enabled) {
66338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		struct wpa_supplicant *iface;
66348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
66358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		for (iface = wpa_s->global->ifaces; iface; iface = iface->next)
66368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		{
66378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			if (iface->cross_connect_enabled == 0)
66388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt				continue;
66398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
66408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			iface->cross_connect_enabled = 0;
66418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			iface->cross_connect_in_use = 0;
6642b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt			wpa_msg_global(iface->parent, MSG_INFO,
6643b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt				       P2P_EVENT_CROSS_CONNECT_DISABLE "%s %s",
6644b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt				       iface->ifname,
6645b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt				       iface->cross_connect_uplink);
66468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		}
66478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
66488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
66498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	return 0;
66508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt}
66518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
66528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
66538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic void wpas_p2p_enable_cross_connect(struct wpa_supplicant *uplink)
66548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{
66558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	struct wpa_supplicant *iface;
66568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
66578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (!uplink->global->cross_connection)
66588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return;
66598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
66608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	for (iface = uplink->global->ifaces; iface; iface = iface->next) {
66618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		if (!iface->cross_connect_enabled)
66628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			continue;
66638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		if (os_strcmp(uplink->ifname, iface->cross_connect_uplink) !=
66648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		    0)
66658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			continue;
66668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		if (iface->ap_iface == NULL)
66678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			continue;
66688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		if (iface->cross_connect_in_use)
66698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			continue;
66708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
66718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		iface->cross_connect_in_use = 1;
6672b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt		wpa_msg_global(iface->parent, MSG_INFO,
6673b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt			       P2P_EVENT_CROSS_CONNECT_ENABLE "%s %s",
6674b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt			       iface->ifname, iface->cross_connect_uplink);
66758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
66768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt}
66778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
66788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
66798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic void wpas_p2p_disable_cross_connect(struct wpa_supplicant *uplink)
66808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{
66818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	struct wpa_supplicant *iface;
66828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
66838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	for (iface = uplink->global->ifaces; iface; iface = iface->next) {
66848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		if (!iface->cross_connect_enabled)
66858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			continue;
66868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		if (os_strcmp(uplink->ifname, iface->cross_connect_uplink) !=
66878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		    0)
66888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			continue;
66898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		if (!iface->cross_connect_in_use)
66908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			continue;
66918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
6692b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt		wpa_msg_global(iface->parent, MSG_INFO,
6693b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt			       P2P_EVENT_CROSS_CONNECT_DISABLE "%s %s",
6694b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt			       iface->ifname, iface->cross_connect_uplink);
66958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		iface->cross_connect_in_use = 0;
66968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
66978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt}
66988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
66998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
67008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtvoid wpas_p2p_notif_connected(struct wpa_supplicant *wpa_s)
67018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{
67028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (wpa_s->ap_iface || wpa_s->current_ssid == NULL ||
67038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	    wpa_s->current_ssid->mode != WPAS_MODE_INFRA ||
67048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	    wpa_s->cross_connect_disallowed)
67058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		wpas_p2p_disable_cross_connect(wpa_s);
67068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	else
67078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		wpas_p2p_enable_cross_connect(wpa_s);
670804949598a23f501be6eec21697465fd46a28840aDmitry Shmidt	if (!wpa_s->ap_iface &&
670904949598a23f501be6eec21697465fd46a28840aDmitry Shmidt	    eloop_cancel_timeout(wpas_p2p_group_idle_timeout, wpa_s, NULL) > 0)
671004949598a23f501be6eec21697465fd46a28840aDmitry Shmidt		wpa_printf(MSG_DEBUG, "P2P: Cancelled P2P group idle timeout");
67118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt}
67128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
67138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
67148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtvoid wpas_p2p_notif_disconnected(struct wpa_supplicant *wpa_s)
67158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{
67168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	wpas_p2p_disable_cross_connect(wpa_s);
67171f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt	if (!wpa_s->ap_iface &&
67181f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt	    !eloop_is_timeout_registered(wpas_p2p_group_idle_timeout,
67191f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt					 wpa_s, NULL))
67208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		wpas_p2p_set_group_idle_timeout(wpa_s);
67218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt}
67228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
67238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
67248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic void wpas_p2p_cross_connect_setup(struct wpa_supplicant *wpa_s)
67258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{
67268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	struct wpa_supplicant *iface;
67278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
67288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (!wpa_s->global->cross_connection)
67298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return;
67308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
67318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	for (iface = wpa_s->global->ifaces; iface; iface = iface->next) {
67328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		if (iface == wpa_s)
67338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			continue;
67348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		if (iface->drv_flags &
67358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		    WPA_DRIVER_FLAGS_P2P_DEDICATED_INTERFACE)
67368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			continue;
67376c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt		if ((iface->drv_flags & WPA_DRIVER_FLAGS_P2P_CAPABLE) &&
67386c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt		    iface != wpa_s->parent)
67398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			continue;
67408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
67418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		wpa_s->cross_connect_enabled = 1;
67428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		os_strlcpy(wpa_s->cross_connect_uplink, iface->ifname,
67438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			   sizeof(wpa_s->cross_connect_uplink));
67448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		wpa_printf(MSG_DEBUG, "P2P: Enable cross connection from "
67458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			   "%s to %s whenever uplink is available",
67468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			   wpa_s->ifname, wpa_s->cross_connect_uplink);
67478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
67488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		if (iface->ap_iface || iface->current_ssid == NULL ||
67498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		    iface->current_ssid->mode != WPAS_MODE_INFRA ||
67508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		    iface->cross_connect_disallowed ||
67518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		    iface->wpa_state != WPA_COMPLETED)
67528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			break;
67538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
67548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		wpa_s->cross_connect_in_use = 1;
6755b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt		wpa_msg_global(wpa_s->parent, MSG_INFO,
6756b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt			       P2P_EVENT_CROSS_CONNECT_ENABLE "%s %s",
6757b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt			       wpa_s->ifname, wpa_s->cross_connect_uplink);
67588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		break;
67598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
67608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt}
67618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
67628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
67638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtint wpas_p2p_notif_pbc_overlap(struct wpa_supplicant *wpa_s)
67648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{
67658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (wpa_s->p2p_group_interface != P2P_GROUP_INTERFACE_CLIENT &&
67668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	    !wpa_s->p2p_in_provisioning)
67678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return 0; /* not P2P client operation */
67688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
67698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	wpa_printf(MSG_DEBUG, "P2P: Terminate connection due to WPS PBC "
67708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		   "session overlap");
67718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (wpa_s != wpa_s->parent)
67728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		wpa_msg_ctrl(wpa_s->parent, MSG_INFO, WPS_EVENT_OVERLAP);
6773a3dc30964aa24aea2b518246f6812663a1103490Dmitry Shmidt	wpas_p2p_group_formation_failed(wpa_s, 0);
67748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	return 1;
67758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt}
67768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
67778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
6778df5a7e4c5c64890c2425bb47d665bbce4992b676Dmitry Shmidtvoid wpas_p2p_pbc_overlap_cb(void *eloop_ctx, void *timeout_ctx)
6779df5a7e4c5c64890c2425bb47d665bbce4992b676Dmitry Shmidt{
6780df5a7e4c5c64890c2425bb47d665bbce4992b676Dmitry Shmidt	struct wpa_supplicant *wpa_s = eloop_ctx;
6781df5a7e4c5c64890c2425bb47d665bbce4992b676Dmitry Shmidt	wpas_p2p_notif_pbc_overlap(wpa_s);
6782df5a7e4c5c64890c2425bb47d665bbce4992b676Dmitry Shmidt}
6783df5a7e4c5c64890c2425bb47d665bbce4992b676Dmitry Shmidt
6784df5a7e4c5c64890c2425bb47d665bbce4992b676Dmitry Shmidt
67858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtvoid wpas_p2p_update_channel_list(struct wpa_supplicant *wpa_s)
67868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{
678768d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt	struct p2p_channels chan, cli_chan;
6788684785c7f4e58498603a9a5ce26f933cc2557ebdDmitry Shmidt	struct wpa_supplicant *ifs;
67898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
67908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (wpa_s->global == NULL || wpa_s->global->p2p == NULL)
67918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return;
67928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
67938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	os_memset(&chan, 0, sizeof(chan));
679468d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt	os_memset(&cli_chan, 0, sizeof(cli_chan));
679568d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt	if (wpas_p2p_setup_channels(wpa_s, &chan, &cli_chan)) {
67968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		wpa_printf(MSG_ERROR, "P2P: Failed to update supported "
67978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			   "channel list");
67988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return;
67998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
68008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
680168d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt	p2p_update_channel_list(wpa_s->global->p2p, &chan, &cli_chan);
6802684785c7f4e58498603a9a5ce26f933cc2557ebdDmitry Shmidt
6803684785c7f4e58498603a9a5ce26f933cc2557ebdDmitry Shmidt	for (ifs = wpa_s->global->ifaces; ifs; ifs = ifs->next) {
6804684785c7f4e58498603a9a5ce26f933cc2557ebdDmitry Shmidt		int freq;
6805684785c7f4e58498603a9a5ce26f933cc2557ebdDmitry Shmidt		if (!ifs->current_ssid ||
6806684785c7f4e58498603a9a5ce26f933cc2557ebdDmitry Shmidt		    !ifs->current_ssid->p2p_group ||
6807684785c7f4e58498603a9a5ce26f933cc2557ebdDmitry Shmidt		    (ifs->current_ssid->mode != WPAS_MODE_P2P_GO &&
6808684785c7f4e58498603a9a5ce26f933cc2557ebdDmitry Shmidt		     ifs->current_ssid->mode != WPAS_MODE_P2P_GROUP_FORMATION))
6809684785c7f4e58498603a9a5ce26f933cc2557ebdDmitry Shmidt				continue;
6810684785c7f4e58498603a9a5ce26f933cc2557ebdDmitry Shmidt		freq = ifs->current_ssid->frequency;
6811684785c7f4e58498603a9a5ce26f933cc2557ebdDmitry Shmidt		if (freq_included(&chan, freq)) {
6812684785c7f4e58498603a9a5ce26f933cc2557ebdDmitry Shmidt			wpa_dbg(ifs, MSG_DEBUG,
6813684785c7f4e58498603a9a5ce26f933cc2557ebdDmitry Shmidt				"P2P GO operating frequency %d MHz in valid range",
6814684785c7f4e58498603a9a5ce26f933cc2557ebdDmitry Shmidt				freq);
6815684785c7f4e58498603a9a5ce26f933cc2557ebdDmitry Shmidt			continue;
6816684785c7f4e58498603a9a5ce26f933cc2557ebdDmitry Shmidt		}
6817684785c7f4e58498603a9a5ce26f933cc2557ebdDmitry Shmidt
6818684785c7f4e58498603a9a5ce26f933cc2557ebdDmitry Shmidt		wpa_dbg(ifs, MSG_DEBUG,
6819684785c7f4e58498603a9a5ce26f933cc2557ebdDmitry Shmidt			"P2P GO operating in invalid frequency %d MHz",	freq);
6820684785c7f4e58498603a9a5ce26f933cc2557ebdDmitry Shmidt		/* TODO: Consider using CSA or removing the group within
6821684785c7f4e58498603a9a5ce26f933cc2557ebdDmitry Shmidt		 * wpa_supplicant */
6822684785c7f4e58498603a9a5ce26f933cc2557ebdDmitry Shmidt		wpa_msg(ifs, MSG_INFO, P2P_EVENT_REMOVE_AND_REFORM_GROUP);
6823684785c7f4e58498603a9a5ce26f933cc2557ebdDmitry Shmidt	}
68248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt}
68258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
68268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
6827a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidtstatic void wpas_p2p_scan_res_ignore(struct wpa_supplicant *wpa_s,
6828a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt				     struct wpa_scan_results *scan_res)
6829a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt{
6830a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt	wpa_printf(MSG_DEBUG, "P2P: Ignore scan results");
6831a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt}
6832a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt
6833a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt
68348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtint wpas_p2p_cancel(struct wpa_supplicant *wpa_s)
68358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{
68368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	struct wpa_global *global = wpa_s->global;
68378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	int found = 0;
68388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	const u8 *peer;
68398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
68408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (global->p2p == NULL)
68418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return -1;
68428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
68438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	wpa_printf(MSG_DEBUG, "P2P: Request to cancel group formation");
68448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
68458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (wpa_s->pending_interface_name[0] &&
68468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	    !is_zero_ether_addr(wpa_s->pending_interface_addr))
68478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		found = 1;
68488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
68498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	peer = p2p_get_go_neg_peer(global->p2p);
68508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (peer) {
68518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		wpa_printf(MSG_DEBUG, "P2P: Unauthorize pending GO Neg peer "
68528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			   MACSTR, MAC2STR(peer));
68538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		p2p_unauthorize(global->p2p, peer);
685404949598a23f501be6eec21697465fd46a28840aDmitry Shmidt		found = 1;
68558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
68568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
6857a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt	if (wpa_s->scan_res_handler == wpas_p2p_scan_res_join) {
6858a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt		wpa_printf(MSG_DEBUG, "P2P: Stop pending scan for join");
6859a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt		wpa_s->scan_res_handler = wpas_p2p_scan_res_ignore;
6860a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt		found = 1;
6861a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt	}
6862a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt
6863a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt	if (wpa_s->pending_pd_before_join) {
6864a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt		wpa_printf(MSG_DEBUG, "P2P: Stop pending PD before join");
6865a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt		wpa_s->pending_pd_before_join = 0;
6866a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt		found = 1;
6867a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt	}
6868a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt
68698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	wpas_p2p_stop_find(wpa_s);
68708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
68718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	for (wpa_s = global->ifaces; wpa_s; wpa_s = wpa_s->next) {
68728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		if (wpa_s == global->p2p_group_formation &&
68738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		    (wpa_s->p2p_in_provisioning ||
68748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		     wpa_s->parent->pending_interface_type ==
68758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		     WPA_IF_P2P_CLIENT)) {
68768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			wpa_printf(MSG_DEBUG, "P2P: Interface %s in group "
68778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt				   "formation found - cancelling",
68788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt				   wpa_s->ifname);
68798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			found = 1;
68808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			eloop_cancel_timeout(wpas_p2p_group_formation_timeout,
68818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt					     wpa_s->parent, NULL);
6882adddfc48d2d7bfa2b1a2405ab8f404b6383ec236Jouni Malinen			if (wpa_s->p2p_in_provisioning) {
6883a3dc30964aa24aea2b518246f6812663a1103490Dmitry Shmidt				wpas_group_formation_completed(wpa_s, 0, 0);
6884adddfc48d2d7bfa2b1a2405ab8f404b6383ec236Jouni Malinen				break;
6885adddfc48d2d7bfa2b1a2405ab8f404b6383ec236Jouni Malinen			}
688661d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt			wpas_p2p_group_delete(wpa_s,
688761d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt					      P2P_GROUP_REMOVAL_REQUESTED);
68888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			break;
688921de214b4ba4271ca20843f3b8fba9f1501b2a89Dmitry Shmidt		} else if (wpa_s->p2p_in_invitation) {
689021de214b4ba4271ca20843f3b8fba9f1501b2a89Dmitry Shmidt			wpa_printf(MSG_DEBUG, "P2P: Interface %s in invitation found - cancelling",
689121de214b4ba4271ca20843f3b8fba9f1501b2a89Dmitry Shmidt				   wpa_s->ifname);
689221de214b4ba4271ca20843f3b8fba9f1501b2a89Dmitry Shmidt			found = 1;
6893a3dc30964aa24aea2b518246f6812663a1103490Dmitry Shmidt			wpas_p2p_group_formation_failed(wpa_s, 0);
68948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		}
68958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
68968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
68978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (!found) {
68988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		wpa_printf(MSG_DEBUG, "P2P: No ongoing group formation found");
68998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return -1;
69008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
69018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
69028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	return 0;
69038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt}
69048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
69058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
69068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtvoid wpas_p2p_interface_unavailable(struct wpa_supplicant *wpa_s)
69078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{
69088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (wpa_s->current_ssid == NULL || !wpa_s->current_ssid->p2p_group)
69098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return;
69108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
69118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	wpa_printf(MSG_DEBUG, "P2P: Remove group due to driver resource not "
69128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		   "being available anymore");
691361d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt	wpas_p2p_group_delete(wpa_s, P2P_GROUP_REMOVAL_UNAVAILABLE);
69148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt}
69158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
69168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
69178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtvoid wpas_p2p_update_best_channels(struct wpa_supplicant *wpa_s,
69188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt				   int freq_24, int freq_5, int freq_overall)
69198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{
69208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	struct p2p_data *p2p = wpa_s->global->p2p;
6921fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt	if (p2p == NULL)
69228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return;
69238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	p2p_set_best_channels(p2p, freq_24, freq_5, freq_overall);
69248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt}
69258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
69268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
69278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtint wpas_p2p_unauthorize(struct wpa_supplicant *wpa_s, const char *addr)
69288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{
69298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	u8 peer[ETH_ALEN];
69308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	struct p2p_data *p2p = wpa_s->global->p2p;
69318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
6932fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt	if (p2p == NULL)
69338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return -1;
69348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
69358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (hwaddr_aton(addr, peer))
69368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return -1;
69378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
69388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	return p2p_unauthorize(p2p, peer);
69398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt}
69408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
69418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
69428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt/**
69438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * wpas_p2p_disconnect - Disconnect from a P2P Group
69448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @wpa_s: Pointer to wpa_supplicant data
69458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * Returns: 0 on success, -1 on failure
69468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt *
69478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * This can be used to disconnect from a group in which the local end is a P2P
69488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * Client or to end a P2P Group in case the local end is the Group Owner. If a
69498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * virtual network interface was created for this group, that interface will be
69508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * removed. Otherwise, only the configured P2P group network will be removed
69518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * from the interface.
69528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */
69538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtint wpas_p2p_disconnect(struct wpa_supplicant *wpa_s)
69548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{
69558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
69568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (wpa_s == NULL)
69578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return -1;
69588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
69592b89da85b8cfe9bb862e8dd334855263c3522c00Jouni Malinen	return wpas_p2p_group_delete(wpa_s, P2P_GROUP_REMOVAL_REQUESTED) < 0 ?
69602b89da85b8cfe9bb862e8dd334855263c3522c00Jouni Malinen		-1 : 0;
69618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt}
69621f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt
69631f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt
69641f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidtint wpas_p2p_in_progress(struct wpa_supplicant *wpa_s)
69651f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt{
6966f86232838cf712377867cb42417c1613ab5dc425Dmitry Shmidt	int ret;
6967f86232838cf712377867cb42417c1613ab5dc425Dmitry Shmidt
69681f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt	if (wpa_s->global->p2p_disabled || wpa_s->global->p2p == NULL)
69691f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt		return 0;
69701f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt
6971f86232838cf712377867cb42417c1613ab5dc425Dmitry Shmidt	ret = p2p_in_progress(wpa_s->global->p2p);
6972f86232838cf712377867cb42417c1613ab5dc425Dmitry Shmidt	if (ret == 0) {
6973f86232838cf712377867cb42417c1613ab5dc425Dmitry Shmidt		/*
6974f86232838cf712377867cb42417c1613ab5dc425Dmitry Shmidt		 * Check whether there is an ongoing WPS provisioning step (or
6975f86232838cf712377867cb42417c1613ab5dc425Dmitry Shmidt		 * other parts of group formation) on another interface since
6976f86232838cf712377867cb42417c1613ab5dc425Dmitry Shmidt		 * p2p_in_progress() does not report this to avoid issues for
6977f86232838cf712377867cb42417c1613ab5dc425Dmitry Shmidt		 * scans during such provisioning step.
6978f86232838cf712377867cb42417c1613ab5dc425Dmitry Shmidt		 */
6979f86232838cf712377867cb42417c1613ab5dc425Dmitry Shmidt		if (wpa_s->global->p2p_group_formation &&
6980f86232838cf712377867cb42417c1613ab5dc425Dmitry Shmidt		    wpa_s->global->p2p_group_formation != wpa_s) {
6981f86232838cf712377867cb42417c1613ab5dc425Dmitry Shmidt			wpa_dbg(wpa_s, MSG_DEBUG, "P2P: Another interface (%s) "
6982f86232838cf712377867cb42417c1613ab5dc425Dmitry Shmidt				"in group formation",
6983f86232838cf712377867cb42417c1613ab5dc425Dmitry Shmidt				wpa_s->global->p2p_group_formation->ifname);
6984f86232838cf712377867cb42417c1613ab5dc425Dmitry Shmidt			ret = 1;
6985f86232838cf712377867cb42417c1613ab5dc425Dmitry Shmidt		}
6986f86232838cf712377867cb42417c1613ab5dc425Dmitry Shmidt	}
6987f86232838cf712377867cb42417c1613ab5dc425Dmitry Shmidt
698892c368d56f46a4e648b441085707c1381b5e5f63Dmitry Shmidt	if (!ret && wpa_s->global->p2p_go_wait_client.sec) {
6989fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt		struct os_reltime now;
6990fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt		os_get_reltime(&now);
6991fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt		if (os_reltime_expired(&now, &wpa_s->global->p2p_go_wait_client,
6992fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt				       P2P_MAX_INITIAL_CONN_WAIT_GO)) {
699392c368d56f46a4e648b441085707c1381b5e5f63Dmitry Shmidt			/* Wait for the first client has expired */
699492c368d56f46a4e648b441085707c1381b5e5f63Dmitry Shmidt			wpa_s->global->p2p_go_wait_client.sec = 0;
699592c368d56f46a4e648b441085707c1381b5e5f63Dmitry Shmidt		} else {
699692c368d56f46a4e648b441085707c1381b5e5f63Dmitry Shmidt			wpa_dbg(wpa_s, MSG_DEBUG, "P2P: Waiting for initial client connection during group formation");
699792c368d56f46a4e648b441085707c1381b5e5f63Dmitry Shmidt			ret = 1;
699892c368d56f46a4e648b441085707c1381b5e5f63Dmitry Shmidt		}
699992c368d56f46a4e648b441085707c1381b5e5f63Dmitry Shmidt	}
700092c368d56f46a4e648b441085707c1381b5e5f63Dmitry Shmidt
7001f86232838cf712377867cb42417c1613ab5dc425Dmitry Shmidt	return ret;
70021f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt}
70031f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt
70041f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt
70051f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidtvoid wpas_p2p_network_removed(struct wpa_supplicant *wpa_s,
70061f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt			      struct wpa_ssid *ssid)
70071f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt{
70081f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt	if (wpa_s->p2p_in_provisioning && ssid->p2p_group &&
70091f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt	    eloop_cancel_timeout(wpas_p2p_group_formation_timeout,
70101f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt				 wpa_s->parent, NULL) > 0) {
701104949598a23f501be6eec21697465fd46a28840aDmitry Shmidt		/**
701204949598a23f501be6eec21697465fd46a28840aDmitry Shmidt		 * Remove the network by scheduling the group formation
701304949598a23f501be6eec21697465fd46a28840aDmitry Shmidt		 * timeout to happen immediately. The teardown code
701404949598a23f501be6eec21697465fd46a28840aDmitry Shmidt		 * needs to be scheduled to run asynch later so that we
701504949598a23f501be6eec21697465fd46a28840aDmitry Shmidt		 * don't delete data from under ourselves unexpectedly.
701604949598a23f501be6eec21697465fd46a28840aDmitry Shmidt		 * Calling wpas_p2p_group_formation_timeout directly
701704949598a23f501be6eec21697465fd46a28840aDmitry Shmidt		 * causes a series of crashes in WPS failure scenarios.
701804949598a23f501be6eec21697465fd46a28840aDmitry Shmidt		 */
70191f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt		wpa_printf(MSG_DEBUG, "P2P: Canceled group formation due to "
70201f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt			   "P2P group network getting removed");
702104949598a23f501be6eec21697465fd46a28840aDmitry Shmidt		eloop_register_timeout(0, 0, wpas_p2p_group_formation_timeout,
702204949598a23f501be6eec21697465fd46a28840aDmitry Shmidt				       wpa_s->parent, NULL);
70231f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt	}
70241f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt}
70251f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt
70261f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt
70271f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidtstruct wpa_ssid * wpas_p2p_get_persistent(struct wpa_supplicant *wpa_s,
7028c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt					  const u8 *addr, const u8 *ssid,
7029c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt					  size_t ssid_len)
70301f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt{
70311f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt	struct wpa_ssid *s;
70321f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt	size_t i;
70331f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt
70341f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt	for (s = wpa_s->conf->ssid; s; s = s->next) {
70351f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt		if (s->disabled != 2)
70361f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt			continue;
7037c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt		if (ssid &&
7038c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt		    (ssid_len != s->ssid_len ||
7039c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt		     os_memcmp(ssid, s->ssid, ssid_len) != 0))
7040c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt			continue;
7041391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt		if (addr == NULL) {
7042391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt			if (s->mode == WPAS_MODE_P2P_GO)
7043391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt				return s;
7044391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt			continue;
7045391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt		}
70461f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt		if (os_memcmp(s->bssid, addr, ETH_ALEN) == 0)
70471f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt			return s; /* peer is GO in the persistent group */
70481f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt		if (s->mode != WPAS_MODE_P2P_GO || s->p2p_client_list == NULL)
70491f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt			continue;
70501f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt		for (i = 0; i < s->num_p2p_clients; i++) {
7051ff787d557db719adea0fdf2679667500c65cf74dDmitry Shmidt			if (os_memcmp(s->p2p_client_list + i * 2 * ETH_ALEN,
70521f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt				      addr, ETH_ALEN) == 0)
70531f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt				return s; /* peer is P2P client in persistent
70541f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt					   * group */
70551f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt		}
70561f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt	}
70571f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt
70581f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt	return NULL;
70591f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt}
70601f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt
70611f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt
70621f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidtvoid wpas_p2p_notify_ap_sta_authorized(struct wpa_supplicant *wpa_s,
70631f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt				       const u8 *addr)
70641f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt{
70655605286c30e1701491bd3af974ae423727750eddDmitry Shmidt	if (eloop_cancel_timeout(wpas_p2p_group_formation_timeout,
70665605286c30e1701491bd3af974ae423727750eddDmitry Shmidt				 wpa_s->parent, NULL) > 0) {
70675605286c30e1701491bd3af974ae423727750eddDmitry Shmidt		/*
70685605286c30e1701491bd3af974ae423727750eddDmitry Shmidt		 * This can happen if WPS provisioning step is not terminated
70695605286c30e1701491bd3af974ae423727750eddDmitry Shmidt		 * cleanly (e.g., P2P Client does not send WSC_Done). Since the
70705605286c30e1701491bd3af974ae423727750eddDmitry Shmidt		 * peer was able to connect, there is no need to time out group
70715605286c30e1701491bd3af974ae423727750eddDmitry Shmidt		 * formation after this, though. In addition, this is used with
70725605286c30e1701491bd3af974ae423727750eddDmitry Shmidt		 * the initial connection wait on the GO as a separate formation
70735605286c30e1701491bd3af974ae423727750eddDmitry Shmidt		 * timeout and as such, expected to be hit after the initial WPS
70745605286c30e1701491bd3af974ae423727750eddDmitry Shmidt		 * provisioning step.
70755605286c30e1701491bd3af974ae423727750eddDmitry Shmidt		 */
70765605286c30e1701491bd3af974ae423727750eddDmitry Shmidt		wpa_printf(MSG_DEBUG, "P2P: Canceled P2P group formation timeout on data connection");
70776c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt
70786c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt		if (!wpa_s->p2p_go_group_formation_completed &&
70796c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt		    !wpa_s->group_formation_reported) {
70806c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt			/*
70816c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt			 * GO has not yet notified group formation success since
70826c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt			 * the WPS step was not completed cleanly. Do that
70836c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt			 * notification now since the P2P Client was able to
70846c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt			 * connect and as such, must have received the
70856c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt			 * credential from the WPS step.
70866c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt			 */
70876c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt			if (wpa_s->global->p2p)
70886c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt				p2p_wps_success_cb(wpa_s->global->p2p, addr);
7089a3dc30964aa24aea2b518246f6812663a1103490Dmitry Shmidt			wpas_group_formation_completed(wpa_s, 1, 0);
70906c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt		}
70915605286c30e1701491bd3af974ae423727750eddDmitry Shmidt	}
70925605286c30e1701491bd3af974ae423727750eddDmitry Shmidt	if (!wpa_s->p2p_go_group_formation_completed) {
70935605286c30e1701491bd3af974ae423727750eddDmitry Shmidt		wpa_dbg(wpa_s, MSG_DEBUG, "P2P: Marking group formation completed on GO on first data connection");
70945605286c30e1701491bd3af974ae423727750eddDmitry Shmidt		wpa_s->p2p_go_group_formation_completed = 1;
70955605286c30e1701491bd3af974ae423727750eddDmitry Shmidt		wpa_s->global->p2p_group_formation = NULL;
70965605286c30e1701491bd3af974ae423727750eddDmitry Shmidt		wpa_s->p2p_in_provisioning = 0;
709721de214b4ba4271ca20843f3b8fba9f1501b2a89Dmitry Shmidt		wpa_s->p2p_in_invitation = 0;
70985605286c30e1701491bd3af974ae423727750eddDmitry Shmidt	}
709992c368d56f46a4e648b441085707c1381b5e5f63Dmitry Shmidt	wpa_s->global->p2p_go_wait_client.sec = 0;
71001f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt	if (addr == NULL)
71011f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt		return;
71021f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt	wpas_p2p_add_persistent_group_client(wpa_s, addr);
71031f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt}
7104c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt
710504949598a23f501be6eec21697465fd46a28840aDmitry Shmidt
71067f65602d49069f96a7bb44da8bd79ffe8d4c6a98Dmitry Shmidtstatic int wpas_p2p_fallback_to_go_neg(struct wpa_supplicant *wpa_s,
71077f65602d49069f96a7bb44da8bd79ffe8d4c6a98Dmitry Shmidt				       int group_added)
710804949598a23f501be6eec21697465fd46a28840aDmitry Shmidt{
710904949598a23f501be6eec21697465fd46a28840aDmitry Shmidt	struct wpa_supplicant *group = wpa_s;
71107f65602d49069f96a7bb44da8bd79ffe8d4c6a98Dmitry Shmidt	int ret = 0;
71117f65602d49069f96a7bb44da8bd79ffe8d4c6a98Dmitry Shmidt
711204949598a23f501be6eec21697465fd46a28840aDmitry Shmidt	if (wpa_s->global->p2p_group_formation)
711304949598a23f501be6eec21697465fd46a28840aDmitry Shmidt		group = wpa_s->global->p2p_group_formation;
7114a3dc30964aa24aea2b518246f6812663a1103490Dmitry Shmidt	wpa_s = wpa_s->global->p2p_init_wpa_s;
711504949598a23f501be6eec21697465fd46a28840aDmitry Shmidt	offchannel_send_action_done(wpa_s);
711604949598a23f501be6eec21697465fd46a28840aDmitry Shmidt	if (group_added)
71177f65602d49069f96a7bb44da8bd79ffe8d4c6a98Dmitry Shmidt		ret = wpas_p2p_group_delete(group, P2P_GROUP_REMOVAL_SILENT);
711804949598a23f501be6eec21697465fd46a28840aDmitry Shmidt	wpa_dbg(wpa_s, MSG_DEBUG, "P2P: Fall back to GO Negotiation");
711904949598a23f501be6eec21697465fd46a28840aDmitry Shmidt	wpas_p2p_connect(wpa_s, wpa_s->pending_join_dev_addr, wpa_s->p2p_pin,
712004949598a23f501be6eec21697465fd46a28840aDmitry Shmidt			 wpa_s->p2p_wps_method, wpa_s->p2p_persistent_group, 0,
712104949598a23f501be6eec21697465fd46a28840aDmitry Shmidt			 0, 0, wpa_s->p2p_go_intent, wpa_s->p2p_connect_freq,
712204949598a23f501be6eec21697465fd46a28840aDmitry Shmidt			 wpa_s->p2p_persistent_id,
712361d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt			 wpa_s->p2p_pd_before_go_neg,
712468d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt			 wpa_s->p2p_go_ht40,
712568d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt			 wpa_s->p2p_go_vht);
71267f65602d49069f96a7bb44da8bd79ffe8d4c6a98Dmitry Shmidt	return ret;
712704949598a23f501be6eec21697465fd46a28840aDmitry Shmidt}
712804949598a23f501be6eec21697465fd46a28840aDmitry Shmidt
712904949598a23f501be6eec21697465fd46a28840aDmitry Shmidt
713004949598a23f501be6eec21697465fd46a28840aDmitry Shmidtint wpas_p2p_scan_no_go_seen(struct wpa_supplicant *wpa_s)
713104949598a23f501be6eec21697465fd46a28840aDmitry Shmidt{
71327f65602d49069f96a7bb44da8bd79ffe8d4c6a98Dmitry Shmidt	int res;
71337f65602d49069f96a7bb44da8bd79ffe8d4c6a98Dmitry Shmidt
713404949598a23f501be6eec21697465fd46a28840aDmitry Shmidt	if (!wpa_s->p2p_fallback_to_go_neg ||
713504949598a23f501be6eec21697465fd46a28840aDmitry Shmidt	    wpa_s->p2p_in_provisioning <= 5)
713604949598a23f501be6eec21697465fd46a28840aDmitry Shmidt		return 0;
713704949598a23f501be6eec21697465fd46a28840aDmitry Shmidt
713804949598a23f501be6eec21697465fd46a28840aDmitry Shmidt	if (wpas_p2p_peer_go(wpa_s, wpa_s->pending_join_dev_addr) > 0)
713904949598a23f501be6eec21697465fd46a28840aDmitry Shmidt		return 0; /* peer operating as a GO */
714004949598a23f501be6eec21697465fd46a28840aDmitry Shmidt
714104949598a23f501be6eec21697465fd46a28840aDmitry Shmidt	wpa_dbg(wpa_s, MSG_DEBUG, "P2P: GO not found for p2p_connect-auto - "
714204949598a23f501be6eec21697465fd46a28840aDmitry Shmidt		"fallback to GO Negotiation");
71437f65602d49069f96a7bb44da8bd79ffe8d4c6a98Dmitry Shmidt	wpa_msg_global(wpa_s->parent, MSG_INFO, P2P_EVENT_FALLBACK_TO_GO_NEG
71447f65602d49069f96a7bb44da8bd79ffe8d4c6a98Dmitry Shmidt		       "reason=GO-not-found");
71457f65602d49069f96a7bb44da8bd79ffe8d4c6a98Dmitry Shmidt	res = wpas_p2p_fallback_to_go_neg(wpa_s, 1);
714604949598a23f501be6eec21697465fd46a28840aDmitry Shmidt
71477f65602d49069f96a7bb44da8bd79ffe8d4c6a98Dmitry Shmidt	return res == 1 ? 2 : 1;
714804949598a23f501be6eec21697465fd46a28840aDmitry Shmidt}
714904949598a23f501be6eec21697465fd46a28840aDmitry Shmidt
715061d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt
715161d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidtunsigned int wpas_p2p_search_delay(struct wpa_supplicant *wpa_s)
715261d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt{
715361d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt	struct wpa_supplicant *ifs;
715461d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt
715561d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt	if (wpa_s->wpa_state > WPA_SCANNING) {
715661d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt		wpa_dbg(wpa_s, MSG_DEBUG, "P2P: Use %u ms search delay due to "
715761d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt			"concurrent operation",
715809f57babfc1e4473db20ced4f58a4c9f082c8ed8Dmitry Shmidt			wpa_s->conf->p2p_search_delay);
715909f57babfc1e4473db20ced4f58a4c9f082c8ed8Dmitry Shmidt		return wpa_s->conf->p2p_search_delay;
716061d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt	}
716161d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt
716201904cfafd75a70b9f29c0220b90bdef45595491Dmitry Shmidt	dl_list_for_each(ifs, &wpa_s->radio->ifaces, struct wpa_supplicant,
716301904cfafd75a70b9f29c0220b90bdef45595491Dmitry Shmidt			 radio_list) {
716401904cfafd75a70b9f29c0220b90bdef45595491Dmitry Shmidt		if (ifs != wpa_s && ifs->wpa_state > WPA_SCANNING) {
716561d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt			wpa_dbg(wpa_s, MSG_DEBUG, "P2P: Use %u ms search "
716661d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt				"delay due to concurrent operation on "
716761d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt				"interface %s",
716809f57babfc1e4473db20ced4f58a4c9f082c8ed8Dmitry Shmidt				wpa_s->conf->p2p_search_delay,
716909f57babfc1e4473db20ced4f58a4c9f082c8ed8Dmitry Shmidt				ifs->ifname);
717009f57babfc1e4473db20ced4f58a4c9f082c8ed8Dmitry Shmidt			return wpa_s->conf->p2p_search_delay;
717161d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt		}
717261d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt	}
717361d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt
717461d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt	return 0;
717561d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt}
717661d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt
717737d4d6a4efea4ef4f864347ac8ed8d62a9e19f90Dmitry Shmidt
7178391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidtstatic int wpas_p2p_remove_psk_entry(struct wpa_supplicant *wpa_s,
7179391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt				     struct wpa_ssid *s, const u8 *addr,
7180391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt				     int iface_addr)
7181391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt{
7182391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt	struct psk_list_entry *psk, *tmp;
7183391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt	int changed = 0;
7184391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt
7185391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt	dl_list_for_each_safe(psk, tmp, &s->psk_list, struct psk_list_entry,
7186391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt			      list) {
7187391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt		if ((iface_addr && !psk->p2p &&
7188391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt		     os_memcmp(addr, psk->addr, ETH_ALEN) == 0) ||
7189391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt		    (!iface_addr && psk->p2p &&
7190391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt		     os_memcmp(addr, psk->addr, ETH_ALEN) == 0)) {
7191391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt			wpa_dbg(wpa_s, MSG_DEBUG,
7192391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt				"P2P: Remove persistent group PSK list entry for "
7193391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt				MACSTR " p2p=%u",
7194391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt				MAC2STR(psk->addr), psk->p2p);
7195391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt			dl_list_del(&psk->list);
7196391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt			os_free(psk);
7197391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt			changed++;
7198391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt		}
7199391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt	}
7200391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt
7201391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt	return changed;
7202391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt}
7203391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt
7204391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt
7205391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidtvoid wpas_p2p_new_psk_cb(struct wpa_supplicant *wpa_s, const u8 *mac_addr,
7206391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt			 const u8 *p2p_dev_addr,
7207391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt			 const u8 *psk, size_t psk_len)
7208391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt{
7209391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt	struct wpa_ssid *ssid = wpa_s->current_ssid;
7210391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt	struct wpa_ssid *persistent;
72117832adbbd72a1b784b7fb74a71a5d4085b0cb0d3Dmitry Shmidt	struct psk_list_entry *p, *last;
7212391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt
7213391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt	if (psk_len != sizeof(p->psk))
7214391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt		return;
7215391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt
7216391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt	if (p2p_dev_addr) {
7217391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt		wpa_dbg(wpa_s, MSG_DEBUG, "P2P: New PSK for addr=" MACSTR
7218391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt			" p2p_dev_addr=" MACSTR,
7219391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt			MAC2STR(mac_addr), MAC2STR(p2p_dev_addr));
7220391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt		if (is_zero_ether_addr(p2p_dev_addr))
7221391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt			p2p_dev_addr = NULL;
7222391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt	} else {
7223391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt		wpa_dbg(wpa_s, MSG_DEBUG, "P2P: New PSK for addr=" MACSTR,
7224391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt			MAC2STR(mac_addr));
7225391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt	}
7226391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt
7227391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt	if (ssid->mode == WPAS_MODE_P2P_GROUP_FORMATION) {
7228391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt		wpa_dbg(wpa_s, MSG_DEBUG, "P2P: new_psk_cb during group formation");
7229391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt		/* To be added to persistent group once created */
7230391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt		if (wpa_s->global->add_psk == NULL) {
7231391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt			wpa_s->global->add_psk = os_zalloc(sizeof(*p));
7232391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt			if (wpa_s->global->add_psk == NULL)
7233391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt				return;
7234391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt		}
7235391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt		p = wpa_s->global->add_psk;
7236391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt		if (p2p_dev_addr) {
7237391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt			p->p2p = 1;
7238391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt			os_memcpy(p->addr, p2p_dev_addr, ETH_ALEN);
7239391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt		} else {
7240391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt			p->p2p = 0;
7241391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt			os_memcpy(p->addr, mac_addr, ETH_ALEN);
7242391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt		}
7243391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt		os_memcpy(p->psk, psk, psk_len);
7244391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt		return;
7245391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt	}
7246391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt
7247391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt	if (ssid->mode != WPAS_MODE_P2P_GO || !ssid->p2p_persistent_group) {
7248391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt		wpa_dbg(wpa_s, MSG_DEBUG, "P2P: Ignore new_psk_cb on not-persistent GO");
7249391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt		return;
7250391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt	}
7251391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt
7252391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt	persistent = wpas_p2p_get_persistent(wpa_s->parent, NULL, ssid->ssid,
7253391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt					     ssid->ssid_len);
7254391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt	if (!persistent) {
7255391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt		wpa_dbg(wpa_s, MSG_DEBUG, "P2P: Could not find persistent group information to store the new PSK");
7256391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt		return;
7257391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt	}
7258391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt
7259391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt	p = os_zalloc(sizeof(*p));
7260391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt	if (p == NULL)
7261391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt		return;
7262391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt	if (p2p_dev_addr) {
7263391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt		p->p2p = 1;
7264391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt		os_memcpy(p->addr, p2p_dev_addr, ETH_ALEN);
7265391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt	} else {
7266391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt		p->p2p = 0;
7267391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt		os_memcpy(p->addr, mac_addr, ETH_ALEN);
7268391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt	}
7269391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt	os_memcpy(p->psk, psk, psk_len);
7270391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt
72717832adbbd72a1b784b7fb74a71a5d4085b0cb0d3Dmitry Shmidt	if (dl_list_len(&persistent->psk_list) > P2P_MAX_STORED_CLIENTS &&
72727832adbbd72a1b784b7fb74a71a5d4085b0cb0d3Dmitry Shmidt	    (last = dl_list_last(&persistent->psk_list,
72737832adbbd72a1b784b7fb74a71a5d4085b0cb0d3Dmitry Shmidt				 struct psk_list_entry, list))) {
7274391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt		wpa_dbg(wpa_s, MSG_DEBUG, "P2P: Remove oldest PSK entry for "
7275391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt			MACSTR " (p2p=%u) to make room for a new one",
7276391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt			MAC2STR(last->addr), last->p2p);
7277391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt		dl_list_del(&last->list);
7278391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt		os_free(last);
7279391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt	}
7280391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt
7281391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt	wpas_p2p_remove_psk_entry(wpa_s->parent, persistent,
7282391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt				  p2p_dev_addr ? p2p_dev_addr : mac_addr,
7283391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt				  p2p_dev_addr == NULL);
7284391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt	if (p2p_dev_addr) {
7285391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt		wpa_dbg(wpa_s, MSG_DEBUG, "P2P: Add new PSK for p2p_dev_addr="
7286391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt			MACSTR, MAC2STR(p2p_dev_addr));
7287391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt	} else {
7288391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt		wpa_dbg(wpa_s, MSG_DEBUG, "P2P: Add new PSK for addr=" MACSTR,
7289391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt			MAC2STR(mac_addr));
7290391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt	}
7291391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt	dl_list_add(&persistent->psk_list, &p->list);
7292391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt
7293391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt	if (wpa_s->parent->conf->update_config &&
7294391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt	    wpa_config_write(wpa_s->parent->confname, wpa_s->parent->conf))
7295391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt		wpa_printf(MSG_DEBUG, "P2P: Failed to update configuration");
7296391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt}
7297391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt
7298391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt
7299391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidtstatic void wpas_p2p_remove_psk(struct wpa_supplicant *wpa_s,
7300391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt				struct wpa_ssid *s, const u8 *addr,
7301391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt				int iface_addr)
7302391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt{
7303391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt	int res;
7304391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt
7305391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt	res = wpas_p2p_remove_psk_entry(wpa_s, s, addr, iface_addr);
7306f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt	if (res > 0 && wpa_s->conf->update_config &&
7307f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt	    wpa_config_write(wpa_s->confname, wpa_s->conf))
7308f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt		wpa_dbg(wpa_s, MSG_DEBUG,
7309f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt			"P2P: Failed to update configuration");
7310391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt}
7311391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt
7312391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt
7313391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidtstatic void wpas_p2p_remove_client_go(struct wpa_supplicant *wpa_s,
7314391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt				      const u8 *peer, int iface_addr)
7315391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt{
7316391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt	struct hostapd_data *hapd;
7317391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt	struct hostapd_wpa_psk *psk, *prev, *rem;
7318391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt	struct sta_info *sta;
7319391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt
7320391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt	if (wpa_s->ap_iface == NULL || wpa_s->current_ssid == NULL ||
7321391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt	    wpa_s->current_ssid->mode != WPAS_MODE_P2P_GO)
7322391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt		return;
7323391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt
7324391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt	/* Remove per-station PSK entry */
7325391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt	hapd = wpa_s->ap_iface->bss[0];
7326391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt	prev = NULL;
7327391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt	psk = hapd->conf->ssid.wpa_psk;
7328391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt	while (psk) {
7329391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt		if ((iface_addr && os_memcmp(peer, psk->addr, ETH_ALEN) == 0) ||
7330391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt		    (!iface_addr &&
7331391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt		     os_memcmp(peer, psk->p2p_dev_addr, ETH_ALEN) == 0)) {
7332391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt			wpa_dbg(wpa_s, MSG_DEBUG, "P2P: Remove operating group PSK entry for "
7333391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt				MACSTR " iface_addr=%d",
7334391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt				MAC2STR(peer), iface_addr);
7335391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt			if (prev)
7336391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt				prev->next = psk->next;
7337391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt			else
7338391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt				hapd->conf->ssid.wpa_psk = psk->next;
7339391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt			rem = psk;
7340391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt			psk = psk->next;
7341391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt			os_free(rem);
7342391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt		} else {
7343391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt			prev = psk;
7344391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt			psk = psk->next;
7345391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt		}
7346391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt	}
7347391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt
7348391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt	/* Disconnect from group */
7349391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt	if (iface_addr)
7350391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt		sta = ap_get_sta(hapd, peer);
7351391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt	else
7352391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt		sta = ap_get_sta_p2p(hapd, peer);
7353391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt	if (sta) {
7354391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt		wpa_dbg(wpa_s, MSG_DEBUG, "P2P: Disconnect peer " MACSTR
7355391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt			" (iface_addr=%d) from group",
7356391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt			MAC2STR(peer), iface_addr);
7357391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt		hostapd_drv_sta_deauth(hapd, sta->addr,
7358391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt				       WLAN_REASON_DEAUTH_LEAVING);
7359391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt		ap_sta_deauthenticate(hapd, sta, WLAN_REASON_DEAUTH_LEAVING);
7360391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt	}
7361391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt}
7362391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt
7363391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt
7364391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidtvoid wpas_p2p_remove_client(struct wpa_supplicant *wpa_s, const u8 *peer,
7365391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt			    int iface_addr)
7366391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt{
7367391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt	struct wpa_ssid *s;
7368391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt	struct wpa_supplicant *w;
73698bd70b7d6ba220544ee2f0e201e5df23e277fa1dDmitry Shmidt	struct wpa_supplicant *p2p_wpa_s = wpa_s->global->p2p_init_wpa_s;
7370391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt
7371391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt	wpa_dbg(wpa_s, MSG_DEBUG, "P2P: Remove client " MACSTR, MAC2STR(peer));
7372391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt
7373391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt	/* Remove from any persistent group */
73748bd70b7d6ba220544ee2f0e201e5df23e277fa1dDmitry Shmidt	for (s = p2p_wpa_s->conf->ssid; s; s = s->next) {
7375391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt		if (s->disabled != 2 || s->mode != WPAS_MODE_P2P_GO)
7376391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt			continue;
7377391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt		if (!iface_addr)
73788bd70b7d6ba220544ee2f0e201e5df23e277fa1dDmitry Shmidt			wpas_remove_persistent_peer(p2p_wpa_s, s, peer, 0);
73798bd70b7d6ba220544ee2f0e201e5df23e277fa1dDmitry Shmidt		wpas_p2p_remove_psk(p2p_wpa_s, s, peer, iface_addr);
7380391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt	}
7381391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt
7382391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt	/* Remove from any operating group */
7383391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt	for (w = wpa_s->global->ifaces; w; w = w->next)
7384391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt		wpas_p2p_remove_client_go(w, peer, iface_addr);
7385391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt}
7386391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt
7387391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt
7388391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidtstatic void wpas_p2p_psk_failure_removal(void *eloop_ctx, void *timeout_ctx)
7389391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt{
7390391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt	struct wpa_supplicant *wpa_s = eloop_ctx;
7391391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt	wpas_p2p_group_delete(wpa_s, P2P_GROUP_REMOVAL_PSK_FAILURE);
7392391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt}
7393391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt
7394391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt
739504f534e89ed127da4077485376f24debc50d80d5Dmitry Shmidtstatic void wpas_p2p_group_freq_conflict(void *eloop_ctx, void *timeout_ctx)
739604f534e89ed127da4077485376f24debc50d80d5Dmitry Shmidt{
739704f534e89ed127da4077485376f24debc50d80d5Dmitry Shmidt	struct wpa_supplicant *wpa_s = eloop_ctx;
739804f534e89ed127da4077485376f24debc50d80d5Dmitry Shmidt
739904f534e89ed127da4077485376f24debc50d80d5Dmitry Shmidt	wpa_printf(MSG_DEBUG, "P2P: Frequency conflict - terminate group");
740004f534e89ed127da4077485376f24debc50d80d5Dmitry Shmidt	wpas_p2p_group_delete(wpa_s, P2P_GROUP_REMOVAL_FREQ_CONFLICT);
740104f534e89ed127da4077485376f24debc50d80d5Dmitry Shmidt}
740204f534e89ed127da4077485376f24debc50d80d5Dmitry Shmidt
740304f534e89ed127da4077485376f24debc50d80d5Dmitry Shmidt
740404f534e89ed127da4077485376f24debc50d80d5Dmitry Shmidtint wpas_p2p_handle_frequency_conflicts(struct wpa_supplicant *wpa_s, int freq,
740504f534e89ed127da4077485376f24debc50d80d5Dmitry Shmidt					struct wpa_ssid *ssid)
740604f534e89ed127da4077485376f24debc50d80d5Dmitry Shmidt{
740704f534e89ed127da4077485376f24debc50d80d5Dmitry Shmidt	struct wpa_supplicant *iface;
740804f534e89ed127da4077485376f24debc50d80d5Dmitry Shmidt
740904f534e89ed127da4077485376f24debc50d80d5Dmitry Shmidt	for (iface = wpa_s->global->ifaces; iface; iface = iface->next) {
741004f534e89ed127da4077485376f24debc50d80d5Dmitry Shmidt		if (!iface->current_ssid ||
741104f534e89ed127da4077485376f24debc50d80d5Dmitry Shmidt		    iface->current_ssid->frequency == freq ||
741204f534e89ed127da4077485376f24debc50d80d5Dmitry Shmidt		    (iface->p2p_group_interface == NOT_P2P_GROUP_INTERFACE &&
741304f534e89ed127da4077485376f24debc50d80d5Dmitry Shmidt		     !iface->current_ssid->p2p_group))
741404f534e89ed127da4077485376f24debc50d80d5Dmitry Shmidt			continue;
741504f534e89ed127da4077485376f24debc50d80d5Dmitry Shmidt
741604f534e89ed127da4077485376f24debc50d80d5Dmitry Shmidt		/* Remove the connection with least priority */
741704f534e89ed127da4077485376f24debc50d80d5Dmitry Shmidt		if (!wpas_is_p2p_prioritized(iface)) {
741804f534e89ed127da4077485376f24debc50d80d5Dmitry Shmidt			/* STA connection has priority over existing
741904f534e89ed127da4077485376f24debc50d80d5Dmitry Shmidt			 * P2P connection, so remove the interface. */
742004f534e89ed127da4077485376f24debc50d80d5Dmitry Shmidt			wpa_printf(MSG_DEBUG, "P2P: Removing P2P connection due to single channel concurrent mode frequency conflict");
742104f534e89ed127da4077485376f24debc50d80d5Dmitry Shmidt			eloop_register_timeout(0, 0,
742204f534e89ed127da4077485376f24debc50d80d5Dmitry Shmidt					       wpas_p2p_group_freq_conflict,
742304f534e89ed127da4077485376f24debc50d80d5Dmitry Shmidt					       iface, NULL);
742404f534e89ed127da4077485376f24debc50d80d5Dmitry Shmidt			/* If connection in progress is P2P connection, do not
742504f534e89ed127da4077485376f24debc50d80d5Dmitry Shmidt			 * proceed for the connection. */
742604f534e89ed127da4077485376f24debc50d80d5Dmitry Shmidt			if (wpa_s == iface)
742704f534e89ed127da4077485376f24debc50d80d5Dmitry Shmidt				return -1;
742804f534e89ed127da4077485376f24debc50d80d5Dmitry Shmidt			else
742904f534e89ed127da4077485376f24debc50d80d5Dmitry Shmidt				return 0;
743004f534e89ed127da4077485376f24debc50d80d5Dmitry Shmidt		} else {
743104f534e89ed127da4077485376f24debc50d80d5Dmitry Shmidt			/* P2P connection has priority, disable the STA network
743204f534e89ed127da4077485376f24debc50d80d5Dmitry Shmidt			 */
743304f534e89ed127da4077485376f24debc50d80d5Dmitry Shmidt			wpa_supplicant_disable_network(wpa_s->global->ifaces,
743404f534e89ed127da4077485376f24debc50d80d5Dmitry Shmidt						       ssid);
743504f534e89ed127da4077485376f24debc50d80d5Dmitry Shmidt			wpa_msg(wpa_s->global->ifaces, MSG_INFO,
743604f534e89ed127da4077485376f24debc50d80d5Dmitry Shmidt				WPA_EVENT_FREQ_CONFLICT " id=%d", ssid->id);
743704f534e89ed127da4077485376f24debc50d80d5Dmitry Shmidt			os_memset(wpa_s->global->ifaces->pending_bssid, 0,
743804f534e89ed127da4077485376f24debc50d80d5Dmitry Shmidt				  ETH_ALEN);
743904f534e89ed127da4077485376f24debc50d80d5Dmitry Shmidt			/* If P2P connection is in progress, continue
744004f534e89ed127da4077485376f24debc50d80d5Dmitry Shmidt			 * connecting...*/
744104f534e89ed127da4077485376f24debc50d80d5Dmitry Shmidt			if (wpa_s == iface)
744204f534e89ed127da4077485376f24debc50d80d5Dmitry Shmidt				return 0;
744304f534e89ed127da4077485376f24debc50d80d5Dmitry Shmidt			else
744404f534e89ed127da4077485376f24debc50d80d5Dmitry Shmidt				return -1;
744504f534e89ed127da4077485376f24debc50d80d5Dmitry Shmidt		}
744604f534e89ed127da4077485376f24debc50d80d5Dmitry Shmidt	}
744704f534e89ed127da4077485376f24debc50d80d5Dmitry Shmidt
744804f534e89ed127da4077485376f24debc50d80d5Dmitry Shmidt	return 0;
744904f534e89ed127da4077485376f24debc50d80d5Dmitry Shmidt}
745004f534e89ed127da4077485376f24debc50d80d5Dmitry Shmidt
745104f534e89ed127da4077485376f24debc50d80d5Dmitry Shmidt
7452391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidtint wpas_p2p_4way_hs_failed(struct wpa_supplicant *wpa_s)
7453391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt{
7454391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt	struct wpa_ssid *ssid = wpa_s->current_ssid;
7455391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt
7456391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt	if (ssid == NULL || !ssid->p2p_group)
7457391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt		return 0;
7458391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt
7459391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt	if (wpa_s->p2p_last_4way_hs_fail &&
7460391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt	    wpa_s->p2p_last_4way_hs_fail == ssid) {
7461391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt		u8 go_dev_addr[ETH_ALEN];
7462391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt		struct wpa_ssid *persistent;
7463391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt
7464391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt		if (wpas_p2p_persistent_group(wpa_s, go_dev_addr,
7465391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt					      ssid->ssid,
7466391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt					      ssid->ssid_len) <= 0) {
7467391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt			wpa_dbg(wpa_s, MSG_DEBUG, "P2P: Could not determine whether 4-way handshake failures were for a persistent group");
7468391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt			goto disconnect;
7469391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt		}
7470391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt
7471391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt		wpa_dbg(wpa_s, MSG_DEBUG, "P2P: Two 4-way handshake failures for a P2P group - go_dev_addr="
7472391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt			MACSTR, MAC2STR(go_dev_addr));
7473391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt		persistent = wpas_p2p_get_persistent(wpa_s->parent, go_dev_addr,
7474391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt						     ssid->ssid,
7475391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt						     ssid->ssid_len);
7476391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt		if (persistent == NULL || persistent->mode != WPAS_MODE_INFRA) {
7477391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt			wpa_dbg(wpa_s, MSG_DEBUG, "P2P: No matching persistent group stored");
7478391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt			goto disconnect;
7479391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt		}
7480391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt		wpa_msg_global(wpa_s->parent, MSG_INFO,
7481391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt			       P2P_EVENT_PERSISTENT_PSK_FAIL "%d",
7482391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt			       persistent->id);
7483391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt	disconnect:
7484391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt		wpa_s->p2p_last_4way_hs_fail = NULL;
7485391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt		/*
7486391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt		 * Remove the group from a timeout to avoid issues with caller
7487391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt		 * continuing to use the interface if this is on a P2P group
7488391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt		 * interface.
7489391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt		 */
7490391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt		eloop_register_timeout(0, 0, wpas_p2p_psk_failure_removal,
7491391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt				       wpa_s, NULL);
7492391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt		return 1;
7493391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt	}
7494391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt
7495391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt	wpa_s->p2p_last_4way_hs_fail = ssid;
7496391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt	return 0;
7497391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt}
7498cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt
7499cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt
7500cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt#ifdef CONFIG_WPS_NFC
7501cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt
7502cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidtstatic struct wpabuf * wpas_p2p_nfc_handover(int ndef, struct wpabuf *wsc,
7503cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt					     struct wpabuf *p2p)
7504cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt{
7505cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt	struct wpabuf *ret;
7506cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt	size_t wsc_len;
7507cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt
7508cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt	if (p2p == NULL) {
7509cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt		wpabuf_free(wsc);
7510cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt		wpa_printf(MSG_DEBUG, "P2P: No p2p buffer for handover");
7511cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt		return NULL;
7512cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt	}
7513cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt
7514cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt	wsc_len = wsc ? wpabuf_len(wsc) : 0;
7515cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt	ret = wpabuf_alloc(2 + wsc_len + 2 + wpabuf_len(p2p));
7516cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt	if (ret == NULL) {
7517cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt		wpabuf_free(wsc);
7518cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt		wpabuf_free(p2p);
7519cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt		return NULL;
7520cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt	}
7521cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt
7522cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt	wpabuf_put_be16(ret, wsc_len);
7523cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt	if (wsc)
7524cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt		wpabuf_put_buf(ret, wsc);
7525cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt	wpabuf_put_be16(ret, wpabuf_len(p2p));
7526cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt	wpabuf_put_buf(ret, p2p);
7527cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt
7528cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt	wpabuf_free(wsc);
7529cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt	wpabuf_free(p2p);
7530cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt	wpa_hexdump_buf(MSG_DEBUG,
7531cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt			"P2P: Generated NFC connection handover message", ret);
7532cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt
7533cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt	if (ndef && ret) {
7534cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt		struct wpabuf *tmp;
7535cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt		tmp = ndef_build_p2p(ret);
7536cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt		wpabuf_free(ret);
7537cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt		if (tmp == NULL) {
7538cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt			wpa_printf(MSG_DEBUG, "P2P: Failed to NDEF encapsulate handover request");
7539cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt			return NULL;
7540cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt		}
7541cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt		ret = tmp;
7542cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt	}
7543cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt
7544cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt	return ret;
7545cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt}
7546cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt
7547cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt
7548cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidtstatic int wpas_p2p_cli_freq(struct wpa_supplicant *wpa_s,
7549cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt			     struct wpa_ssid **ssid, u8 *go_dev_addr)
7550cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt{
7551cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt	struct wpa_supplicant *iface;
7552cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt
7553cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt	if (go_dev_addr)
7554cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt		os_memset(go_dev_addr, 0, ETH_ALEN);
7555cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt	if (ssid)
7556cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt		*ssid = NULL;
7557cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt	for (iface = wpa_s->global->ifaces; iface; iface = iface->next) {
7558cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt		if (iface->wpa_state < WPA_ASSOCIATING ||
7559cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt		    iface->current_ssid == NULL || iface->assoc_freq == 0 ||
7560cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt		    !iface->current_ssid->p2p_group ||
7561cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt		    iface->current_ssid->mode != WPAS_MODE_INFRA)
7562cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt			continue;
7563cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt		if (ssid)
7564cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt			*ssid = iface->current_ssid;
7565cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt		if (go_dev_addr)
7566cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt			os_memcpy(go_dev_addr, iface->go_dev_addr, ETH_ALEN);
7567cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt		return iface->assoc_freq;
7568cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt	}
7569cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt	return 0;
7570cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt}
7571cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt
7572cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt
7573cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidtstruct wpabuf * wpas_p2p_nfc_handover_req(struct wpa_supplicant *wpa_s,
7574cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt					  int ndef)
7575cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt{
7576cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt	struct wpabuf *wsc, *p2p;
7577cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt	struct wpa_ssid *ssid;
7578cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt	u8 go_dev_addr[ETH_ALEN];
7579cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt	int cli_freq = wpas_p2p_cli_freq(wpa_s, &ssid, go_dev_addr);
7580cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt
7581cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt	if (wpa_s->global->p2p_disabled || wpa_s->global->p2p == NULL) {
7582cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt		wpa_printf(MSG_DEBUG, "P2P: P2P disabled - cannot build handover request");
7583cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt		return NULL;
7584cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt	}
7585cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt
7586cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt	if (wpa_s->conf->wps_nfc_dh_pubkey == NULL &&
7587cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt	    wps_nfc_gen_dh(&wpa_s->conf->wps_nfc_dh_pubkey,
7588cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt			   &wpa_s->conf->wps_nfc_dh_privkey) < 0) {
7589cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt		wpa_dbg(wpa_s, MSG_DEBUG, "P2P: No DH key available for handover request");
7590cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt		return NULL;
7591cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt	}
7592cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt
7593cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt	if (cli_freq == 0) {
7594cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt		wsc = wps_build_nfc_handover_req_p2p(
7595cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt			wpa_s->parent->wps, wpa_s->conf->wps_nfc_dh_pubkey);
7596cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt	} else
7597cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt		wsc = NULL;
7598cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt	p2p = p2p_build_nfc_handover_req(wpa_s->global->p2p, cli_freq,
7599cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt					 go_dev_addr, ssid ? ssid->ssid : NULL,
7600cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt					 ssid ? ssid->ssid_len : 0);
7601cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt
7602cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt	return wpas_p2p_nfc_handover(ndef, wsc, p2p);
7603cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt}
7604cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt
7605cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt
7606cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidtstruct wpabuf * wpas_p2p_nfc_handover_sel(struct wpa_supplicant *wpa_s,
7607cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt					  int ndef, int tag)
7608cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt{
7609cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt	struct wpabuf *wsc, *p2p;
7610cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt	struct wpa_ssid *ssid;
7611cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt	u8 go_dev_addr[ETH_ALEN];
7612cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt	int cli_freq = wpas_p2p_cli_freq(wpa_s, &ssid, go_dev_addr);
7613cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt
7614cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt	if (wpa_s->global->p2p_disabled || wpa_s->global->p2p == NULL)
7615cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt		return NULL;
7616cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt
7617cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt	if (!tag && wpa_s->conf->wps_nfc_dh_pubkey == NULL &&
7618cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt	    wps_nfc_gen_dh(&wpa_s->conf->wps_nfc_dh_pubkey,
7619cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt			   &wpa_s->conf->wps_nfc_dh_privkey) < 0)
7620cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt		return NULL;
7621cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt
7622cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt	if (cli_freq == 0) {
7623cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt		wsc = wps_build_nfc_handover_sel_p2p(
7624cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt			wpa_s->parent->wps,
7625cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt			tag ? wpa_s->conf->wps_nfc_dev_pw_id :
7626cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt			DEV_PW_NFC_CONNECTION_HANDOVER,
7627cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt			wpa_s->conf->wps_nfc_dh_pubkey,
7628cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt			tag ? wpa_s->conf->wps_nfc_dev_pw : NULL);
7629cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt	} else
7630cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt		wsc = NULL;
7631cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt	p2p = p2p_build_nfc_handover_sel(wpa_s->global->p2p, cli_freq,
7632cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt					 go_dev_addr, ssid ? ssid->ssid : NULL,
7633cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt					 ssid ? ssid->ssid_len : 0);
7634cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt
7635cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt	return wpas_p2p_nfc_handover(ndef, wsc, p2p);
7636cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt}
7637cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt
7638cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt
7639cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidtstatic int wpas_p2p_nfc_join_group(struct wpa_supplicant *wpa_s,
7640cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt				   struct p2p_nfc_params *params)
7641cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt{
7642cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt	wpa_printf(MSG_DEBUG, "P2P: Initiate join-group based on NFC "
7643cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt		   "connection handover (freq=%d)",
7644cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt		   params->go_freq);
7645cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt
7646cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt	if (params->go_freq && params->go_ssid_len) {
7647cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt		wpa_s->p2p_wps_method = WPS_NFC;
7648cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt		wpa_s->pending_join_wps_method = WPS_NFC;
7649cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt		os_memset(wpa_s->pending_join_iface_addr, 0, ETH_ALEN);
7650cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt		os_memcpy(wpa_s->pending_join_dev_addr, params->go_dev_addr,
7651cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt			  ETH_ALEN);
7652cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt		return wpas_p2p_join_start(wpa_s, params->go_freq,
7653cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt					   params->go_ssid,
7654cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt					   params->go_ssid_len);
7655cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt	}
7656cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt
7657cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt	return wpas_p2p_connect(wpa_s, params->peer->p2p_device_addr, NULL,
7658cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt				WPS_NFC, 0, 0, 1, 0, wpa_s->conf->p2p_go_intent,
7659cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt				params->go_freq, -1, 0, 1, 1);
7660cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt}
7661cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt
7662cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt
7663cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidtstatic int wpas_p2p_nfc_auth_join(struct wpa_supplicant *wpa_s,
7664cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt				  struct p2p_nfc_params *params, int tag)
7665cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt{
7666cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt	int res, persistent;
7667cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt	struct wpa_ssid *ssid;
7668cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt
7669cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt	wpa_printf(MSG_DEBUG, "P2P: Authorize join-group based on NFC "
7670cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt		   "connection handover");
7671cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt	for (wpa_s = wpa_s->global->ifaces; wpa_s; wpa_s = wpa_s->next) {
7672cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt		ssid = wpa_s->current_ssid;
7673cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt		if (ssid == NULL)
7674cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt			continue;
7675cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt		if (ssid->mode != WPAS_MODE_P2P_GO)
7676cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt			continue;
7677cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt		if (wpa_s->ap_iface == NULL)
7678cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt			continue;
7679cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt		break;
7680cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt	}
7681cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt	if (wpa_s == NULL) {
7682cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt		wpa_printf(MSG_DEBUG, "P2P: Could not find GO interface");
7683cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt		return -1;
7684cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt	}
7685cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt
7686cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt	if (wpa_s->parent->p2p_oob_dev_pw_id !=
7687cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt	    DEV_PW_NFC_CONNECTION_HANDOVER &&
7688cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt	    !wpa_s->parent->p2p_oob_dev_pw) {
7689cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt		wpa_printf(MSG_DEBUG, "P2P: No NFC Dev Pw known");
7690cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt		return -1;
7691cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt	}
7692cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt	res = wpas_ap_wps_add_nfc_pw(
7693cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt		wpa_s, wpa_s->parent->p2p_oob_dev_pw_id,
7694cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt		wpa_s->parent->p2p_oob_dev_pw,
7695cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt		wpa_s->parent->p2p_peer_oob_pk_hash_known ?
7696cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt		wpa_s->parent->p2p_peer_oob_pubkey_hash : NULL);
7697cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt	if (res)
7698cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt		return res;
7699cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt
7700cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt	if (!tag) {
7701cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt		wpa_printf(MSG_DEBUG, "P2P: Negotiated handover - wait for peer to join without invitation");
7702cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt		return 0;
7703cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt	}
7704cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt
7705cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt	if (!params->peer ||
7706cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt	    !(params->peer->dev_capab & P2P_DEV_CAPAB_INVITATION_PROCEDURE))
7707cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt		return 0;
7708cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt
7709cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt	wpa_printf(MSG_DEBUG, "P2P: Static handover - invite peer " MACSTR
7710cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt		   " to join", MAC2STR(params->peer->p2p_device_addr));
7711cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt
7712cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt	wpa_s->global->p2p_invite_group = wpa_s;
7713cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt	persistent = ssid->p2p_persistent_group &&
7714cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt		wpas_p2p_get_persistent(wpa_s->parent,
7715cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt					params->peer->p2p_device_addr,
7716cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt					ssid->ssid, ssid->ssid_len);
7717cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt	wpa_s->parent->pending_invite_ssid_id = -1;
7718cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt
7719cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt	return p2p_invite(wpa_s->global->p2p, params->peer->p2p_device_addr,
7720cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt			  P2P_INVITE_ROLE_ACTIVE_GO, wpa_s->own_addr,
7721cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt			  ssid->ssid, ssid->ssid_len, ssid->frequency,
7722cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt			  wpa_s->global->p2p_dev_addr, persistent, 0,
7723cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt			  wpa_s->parent->p2p_oob_dev_pw_id);
7724cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt}
7725cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt
7726cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt
7727cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidtstatic int wpas_p2p_nfc_init_go_neg(struct wpa_supplicant *wpa_s,
7728cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt				    struct p2p_nfc_params *params,
7729cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt				    int forced_freq)
7730cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt{
7731cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt	wpa_printf(MSG_DEBUG, "P2P: Initiate GO Negotiation based on NFC "
7732cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt		   "connection handover");
7733cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt	return wpas_p2p_connect(wpa_s, params->peer->p2p_device_addr, NULL,
7734cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt				WPS_NFC, 0, 0, 0, 0, wpa_s->conf->p2p_go_intent,
7735cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt				forced_freq, -1, 0, 1, 1);
7736cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt}
7737cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt
7738cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt
7739cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidtstatic int wpas_p2p_nfc_resp_go_neg(struct wpa_supplicant *wpa_s,
7740cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt				    struct p2p_nfc_params *params,
7741cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt				    int forced_freq)
7742cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt{
7743cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt	int res;
7744cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt
7745cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt	wpa_printf(MSG_DEBUG, "P2P: Authorize GO Negotiation based on NFC "
7746cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt		   "connection handover");
7747cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt	res = wpas_p2p_connect(wpa_s, params->peer->p2p_device_addr, NULL,
7748cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt			       WPS_NFC, 0, 0, 0, 1, wpa_s->conf->p2p_go_intent,
7749cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt			       forced_freq, -1, 0, 1, 1);
7750cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt	if (res)
7751cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt		return res;
7752cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt
7753cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt	res = wpas_p2p_listen(wpa_s, 60);
7754cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt	if (res) {
7755cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt		p2p_unauthorize(wpa_s->global->p2p,
7756cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt				params->peer->p2p_device_addr);
7757cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt	}
7758cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt
7759cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt	return res;
7760cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt}
7761cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt
7762cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt
7763cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidtstatic int wpas_p2p_nfc_connection_handover(struct wpa_supplicant *wpa_s,
7764cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt					    const struct wpabuf *data,
7765cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt					    int sel, int tag, int forced_freq)
7766cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt{
7767cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt	const u8 *pos, *end;
7768cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt	u16 len, id;
7769cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt	struct p2p_nfc_params params;
7770cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt	int res;
7771cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt
7772cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt	os_memset(&params, 0, sizeof(params));
7773cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt	params.sel = sel;
7774cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt
7775cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt	wpa_hexdump_buf(MSG_DEBUG, "P2P: Received NFC tag payload", data);
7776cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt
7777cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt	pos = wpabuf_head(data);
7778cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt	end = pos + wpabuf_len(data);
7779cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt
7780cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt	if (end - pos < 2) {
7781cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt		wpa_printf(MSG_DEBUG, "P2P: Not enough data for Length of WSC "
7782cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt			   "attributes");
7783cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt		return -1;
7784cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt	}
7785cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt	len = WPA_GET_BE16(pos);
7786cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt	pos += 2;
77876c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt	if (len > end - pos) {
7788cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt		wpa_printf(MSG_DEBUG, "P2P: Not enough data for WSC "
7789cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt			   "attributes");
7790cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt		return -1;
7791cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt	}
7792cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt	params.wsc_attr = pos;
7793cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt	params.wsc_len = len;
7794cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt	pos += len;
7795cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt
7796cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt	if (end - pos < 2) {
7797cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt		wpa_printf(MSG_DEBUG, "P2P: Not enough data for Length of P2P "
7798cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt			   "attributes");
7799cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt		return -1;
7800cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt	}
7801cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt	len = WPA_GET_BE16(pos);
7802cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt	pos += 2;
78036c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt	if (len > end - pos) {
7804cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt		wpa_printf(MSG_DEBUG, "P2P: Not enough data for P2P "
7805cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt			   "attributes");
7806cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt		return -1;
7807cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt	}
7808cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt	params.p2p_attr = pos;
7809cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt	params.p2p_len = len;
7810cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt	pos += len;
7811cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt
7812cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt	wpa_hexdump(MSG_DEBUG, "P2P: WSC attributes",
7813cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt		    params.wsc_attr, params.wsc_len);
7814cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt	wpa_hexdump(MSG_DEBUG, "P2P: P2P attributes",
7815cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt		    params.p2p_attr, params.p2p_len);
7816cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt	if (pos < end) {
7817cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt		wpa_hexdump(MSG_DEBUG,
7818cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt			    "P2P: Ignored extra data after P2P attributes",
7819cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt			    pos, end - pos);
7820cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt	}
7821cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt
7822cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt	res = p2p_process_nfc_connection_handover(wpa_s->global->p2p, &params);
7823cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt	if (res)
7824cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt		return res;
7825cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt
7826cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt	if (params.next_step == NO_ACTION)
7827cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt		return 0;
7828cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt
7829cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt	if (params.next_step == BOTH_GO) {
7830cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt		wpa_msg(wpa_s, MSG_INFO, P2P_EVENT_NFC_BOTH_GO "peer=" MACSTR,
7831cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt			MAC2STR(params.peer->p2p_device_addr));
7832cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt		return 0;
7833cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt	}
7834cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt
7835cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt	if (params.next_step == PEER_CLIENT) {
7836cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt		if (!is_zero_ether_addr(params.go_dev_addr)) {
7837cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt			wpa_msg(wpa_s, MSG_INFO, P2P_EVENT_NFC_PEER_CLIENT
7838cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt				"peer=" MACSTR " freq=%d go_dev_addr=" MACSTR
7839cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt				" ssid=\"%s\"",
7840cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt				MAC2STR(params.peer->p2p_device_addr),
7841cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt				params.go_freq,
7842cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt				MAC2STR(params.go_dev_addr),
7843cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt				wpa_ssid_txt(params.go_ssid,
7844cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt					     params.go_ssid_len));
7845cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt		} else {
7846cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt			wpa_msg(wpa_s, MSG_INFO, P2P_EVENT_NFC_PEER_CLIENT
7847cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt				"peer=" MACSTR " freq=%d",
7848cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt				MAC2STR(params.peer->p2p_device_addr),
7849cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt				params.go_freq);
7850cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt		}
7851cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt		return 0;
7852cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt	}
7853cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt
7854cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt	if (wpas_p2p_cli_freq(wpa_s, NULL, NULL)) {
7855cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt		wpa_msg(wpa_s, MSG_INFO, P2P_EVENT_NFC_WHILE_CLIENT "peer="
7856cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt			MACSTR, MAC2STR(params.peer->p2p_device_addr));
7857cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt		return 0;
7858cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt	}
7859cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt
7860cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt	wpabuf_free(wpa_s->p2p_oob_dev_pw);
7861cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt	wpa_s->p2p_oob_dev_pw = NULL;
7862cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt
7863cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt	if (params.oob_dev_pw_len < WPS_OOB_PUBKEY_HASH_LEN + 2) {
7864cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt		wpa_printf(MSG_DEBUG, "P2P: No peer OOB Dev Pw "
7865cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt			   "received");
7866cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt		return -1;
7867cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt	}
7868cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt
7869cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt	id = WPA_GET_BE16(params.oob_dev_pw + WPS_OOB_PUBKEY_HASH_LEN);
7870cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt	wpa_printf(MSG_DEBUG, "P2P: Peer OOB Dev Pw %u", id);
7871cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt	wpa_hexdump(MSG_DEBUG, "P2P: Peer OOB Public Key hash",
7872cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt		    params.oob_dev_pw, WPS_OOB_PUBKEY_HASH_LEN);
7873cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt	os_memcpy(wpa_s->p2p_peer_oob_pubkey_hash,
7874cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt		  params.oob_dev_pw, WPS_OOB_PUBKEY_HASH_LEN);
7875cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt	wpa_s->p2p_peer_oob_pk_hash_known = 1;
7876cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt
7877cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt	if (tag) {
7878cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt		if (id < 0x10) {
7879cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt			wpa_printf(MSG_DEBUG, "P2P: Static handover - invalid "
7880cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt				   "peer OOB Device Password Id %u", id);
7881cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt			return -1;
7882cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt		}
7883cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt		wpa_printf(MSG_DEBUG, "P2P: Static handover - use peer OOB "
7884cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt			   "Device Password Id %u", id);
7885cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt		wpa_hexdump_key(MSG_DEBUG, "P2P: Peer OOB Device Password",
7886cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt				params.oob_dev_pw + WPS_OOB_PUBKEY_HASH_LEN + 2,
7887cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt				params.oob_dev_pw_len -
7888cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt				WPS_OOB_PUBKEY_HASH_LEN - 2);
7889cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt		wpa_s->p2p_oob_dev_pw_id = id;
7890cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt		wpa_s->p2p_oob_dev_pw = wpabuf_alloc_copy(
7891cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt			params.oob_dev_pw + WPS_OOB_PUBKEY_HASH_LEN + 2,
7892cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt			params.oob_dev_pw_len -
7893cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt			WPS_OOB_PUBKEY_HASH_LEN - 2);
7894cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt		if (wpa_s->p2p_oob_dev_pw == NULL)
7895cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt			return -1;
7896cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt
7897cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt		if (wpa_s->conf->wps_nfc_dh_pubkey == NULL &&
7898cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt		    wps_nfc_gen_dh(&wpa_s->conf->wps_nfc_dh_pubkey,
7899cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt				   &wpa_s->conf->wps_nfc_dh_privkey) < 0)
7900cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt			return -1;
7901cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt	} else {
7902cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt		wpa_printf(MSG_DEBUG, "P2P: Using abbreviated WPS handshake "
7903cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt			   "without Device Password");
7904cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt		wpa_s->p2p_oob_dev_pw_id = DEV_PW_NFC_CONNECTION_HANDOVER;
7905cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt	}
7906cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt
7907cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt	switch (params.next_step) {
7908cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt	case NO_ACTION:
7909cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt	case BOTH_GO:
7910cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt	case PEER_CLIENT:
7911cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt		/* already covered above */
7912cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt		return 0;
7913cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt	case JOIN_GROUP:
7914cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt		return wpas_p2p_nfc_join_group(wpa_s, &params);
7915cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt	case AUTH_JOIN:
7916cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt		return wpas_p2p_nfc_auth_join(wpa_s, &params, tag);
7917cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt	case INIT_GO_NEG:
7918cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt		return wpas_p2p_nfc_init_go_neg(wpa_s, &params, forced_freq);
7919cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt	case RESP_GO_NEG:
7920cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt		/* TODO: use own OOB Dev Pw */
7921cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt		return wpas_p2p_nfc_resp_go_neg(wpa_s, &params, forced_freq);
7922cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt	}
7923cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt
7924cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt	return -1;
7925cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt}
7926cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt
7927cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt
7928cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidtint wpas_p2p_nfc_tag_process(struct wpa_supplicant *wpa_s,
7929cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt			     const struct wpabuf *data, int forced_freq)
7930cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt{
7931cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt	if (wpa_s->global->p2p_disabled || wpa_s->global->p2p == NULL)
7932cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt		return -1;
7933cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt
7934cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt	return wpas_p2p_nfc_connection_handover(wpa_s, data, 1, 1, forced_freq);
7935cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt}
7936cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt
7937cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt
7938cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidtint wpas_p2p_nfc_report_handover(struct wpa_supplicant *wpa_s, int init,
7939cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt				 const struct wpabuf *req,
7940cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt				 const struct wpabuf *sel, int forced_freq)
7941cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt{
7942cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt	struct wpabuf *tmp;
7943cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt	int ret;
7944cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt
7945cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt	if (wpa_s->global->p2p_disabled || wpa_s->global->p2p == NULL)
7946cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt		return -1;
7947cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt
7948cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt	wpa_printf(MSG_DEBUG, "NFC: P2P connection handover reported");
7949cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt
7950cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt	wpa_hexdump_ascii(MSG_DEBUG, "NFC: Req",
7951cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt			  wpabuf_head(req), wpabuf_len(req));
7952cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt	wpa_hexdump_ascii(MSG_DEBUG, "NFC: Sel",
7953cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt			  wpabuf_head(sel), wpabuf_len(sel));
7954cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt	if (forced_freq)
7955cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt		wpa_printf(MSG_DEBUG, "NFC: Forced freq %d", forced_freq);
7956cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt	tmp = ndef_parse_p2p(init ? sel : req);
7957cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt	if (tmp == NULL) {
7958cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt		wpa_printf(MSG_DEBUG, "P2P: Could not parse NDEF");
7959cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt		return -1;
7960cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt	}
7961cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt
7962cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt	ret = wpas_p2p_nfc_connection_handover(wpa_s, tmp, init, 0,
7963cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt					       forced_freq);
7964cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt	wpabuf_free(tmp);
7965cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt
7966cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt	return ret;
7967cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt}
7968cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt
7969cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt
7970cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidtint wpas_p2p_nfc_tag_enabled(struct wpa_supplicant *wpa_s, int enabled)
7971cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt{
7972cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt	const u8 *if_addr;
7973cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt	int go_intent = wpa_s->conf->p2p_go_intent;
7974cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt	struct wpa_supplicant *iface;
7975cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt
7976cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt	if (wpa_s->global->p2p == NULL)
7977cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt		return -1;
7978cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt
7979cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt	if (!enabled) {
7980cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt		wpa_printf(MSG_DEBUG, "P2P: Disable use of own NFC Tag");
7981cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt		for (iface = wpa_s->global->ifaces; iface; iface = iface->next)
7982cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt		{
7983cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt			if (!iface->ap_iface)
7984cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt				continue;
7985cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt			hostapd_wps_nfc_token_disable(iface->ap_iface->bss[0]);
7986cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt		}
7987cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt		p2p_set_authorized_oob_dev_pw_id(wpa_s->global->p2p, 0,
7988cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt						 0, NULL);
7989cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt		if (wpa_s->p2p_nfc_tag_enabled)
7990cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt			wpas_p2p_remove_pending_group_interface(wpa_s);
7991cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt		wpa_s->p2p_nfc_tag_enabled = 0;
7992cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt		return 0;
7993cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt	}
7994cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt
7995cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt	if (wpa_s->global->p2p_disabled)
7996cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt		return -1;
7997cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt
7998cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt	if (wpa_s->conf->wps_nfc_dh_pubkey == NULL ||
7999cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt	    wpa_s->conf->wps_nfc_dh_privkey == NULL ||
8000cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt	    wpa_s->conf->wps_nfc_dev_pw == NULL ||
8001cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt	    wpa_s->conf->wps_nfc_dev_pw_id < 0x10) {
8002cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt		wpa_printf(MSG_DEBUG, "P2P: NFC password token not configured "
8003cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt			   "to allow static handover cases");
8004cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt		return -1;
8005cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt	}
8006cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt
8007cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt	wpa_printf(MSG_DEBUG, "P2P: Enable use of own NFC Tag");
8008cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt
8009cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt	wpa_s->p2p_oob_dev_pw_id = wpa_s->conf->wps_nfc_dev_pw_id;
8010cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt	wpabuf_free(wpa_s->p2p_oob_dev_pw);
8011cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt	wpa_s->p2p_oob_dev_pw = wpabuf_dup(wpa_s->conf->wps_nfc_dev_pw);
8012cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt	if (wpa_s->p2p_oob_dev_pw == NULL)
8013cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt		return -1;
8014cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt	wpa_s->p2p_peer_oob_pk_hash_known = 0;
8015cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt
8016b36ed7cd946148d829f311de8fe53ea3ffaaffe3Dmitry Shmidt	if (wpa_s->p2p_group_interface == P2P_GROUP_INTERFACE_GO ||
8017b36ed7cd946148d829f311de8fe53ea3ffaaffe3Dmitry Shmidt	    wpa_s->p2p_group_interface == P2P_GROUP_INTERFACE_CLIENT) {
8018b36ed7cd946148d829f311de8fe53ea3ffaaffe3Dmitry Shmidt		/*
8019b36ed7cd946148d829f311de8fe53ea3ffaaffe3Dmitry Shmidt		 * P2P Group Interface present and the command came on group
8020b36ed7cd946148d829f311de8fe53ea3ffaaffe3Dmitry Shmidt		 * interface, so enable the token for the current interface.
8021b36ed7cd946148d829f311de8fe53ea3ffaaffe3Dmitry Shmidt		 */
8022b36ed7cd946148d829f311de8fe53ea3ffaaffe3Dmitry Shmidt		wpa_s->create_p2p_iface = 0;
8023b36ed7cd946148d829f311de8fe53ea3ffaaffe3Dmitry Shmidt	} else {
8024b36ed7cd946148d829f311de8fe53ea3ffaaffe3Dmitry Shmidt		wpa_s->create_p2p_iface = wpas_p2p_create_iface(wpa_s);
8025b36ed7cd946148d829f311de8fe53ea3ffaaffe3Dmitry Shmidt	}
8026cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt
8027cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt	if (wpa_s->create_p2p_iface) {
8028cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt		enum wpa_driver_if_type iftype;
8029cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt		/* Prepare to add a new interface for the group */
8030cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt		iftype = WPA_IF_P2P_GROUP;
8031cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt		if (go_intent == 15)
8032cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt			iftype = WPA_IF_P2P_GO;
8033cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt		if (wpas_p2p_add_group_interface(wpa_s, iftype) < 0) {
8034cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt			wpa_printf(MSG_ERROR, "P2P: Failed to allocate a new "
8035cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt				   "interface for the group");
8036cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt			return -1;
8037cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt		}
8038cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt
8039cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt		if_addr = wpa_s->pending_interface_addr;
8040cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt	} else
8041cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt		if_addr = wpa_s->own_addr;
8042cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt
8043cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt	wpa_s->p2p_nfc_tag_enabled = enabled;
8044cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt
8045cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt	for (iface = wpa_s->global->ifaces; iface; iface = iface->next) {
8046cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt		struct hostapd_data *hapd;
8047cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt		if (iface->ap_iface == NULL)
8048cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt			continue;
8049cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt		hapd = iface->ap_iface->bss[0];
8050cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt		wpabuf_free(hapd->conf->wps_nfc_dh_pubkey);
8051cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt		hapd->conf->wps_nfc_dh_pubkey =
8052cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt			wpabuf_dup(wpa_s->conf->wps_nfc_dh_pubkey);
8053cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt		wpabuf_free(hapd->conf->wps_nfc_dh_privkey);
8054cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt		hapd->conf->wps_nfc_dh_privkey =
8055cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt			wpabuf_dup(wpa_s->conf->wps_nfc_dh_privkey);
8056cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt		wpabuf_free(hapd->conf->wps_nfc_dev_pw);
8057cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt		hapd->conf->wps_nfc_dev_pw =
8058cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt			wpabuf_dup(wpa_s->conf->wps_nfc_dev_pw);
8059cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt		hapd->conf->wps_nfc_dev_pw_id = wpa_s->conf->wps_nfc_dev_pw_id;
8060cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt
8061cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt		if (hostapd_wps_nfc_token_enable(iface->ap_iface->bss[0]) < 0) {
8062cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt			wpa_dbg(iface, MSG_DEBUG,
8063cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt				"P2P: Failed to enable NFC Tag for GO");
8064cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt		}
8065cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt	}
8066cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt	p2p_set_authorized_oob_dev_pw_id(
8067cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt		wpa_s->global->p2p, wpa_s->conf->wps_nfc_dev_pw_id, go_intent,
8068cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt		if_addr);
8069cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt
8070cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt	return 0;
8071cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt}
8072cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt
8073cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt#endif /* CONFIG_WPS_NFC */
807443cb578dfe2c492257636f6234a24178ed27789eDmitry Shmidt
807543cb578dfe2c492257636f6234a24178ed27789eDmitry Shmidt
807643cb578dfe2c492257636f6234a24178ed27789eDmitry Shmidtstatic void wpas_p2p_optimize_listen_channel(struct wpa_supplicant *wpa_s,
807743cb578dfe2c492257636f6234a24178ed27789eDmitry Shmidt					     struct wpa_used_freq_data *freqs,
807843cb578dfe2c492257636f6234a24178ed27789eDmitry Shmidt					     unsigned int num)
807943cb578dfe2c492257636f6234a24178ed27789eDmitry Shmidt{
808043cb578dfe2c492257636f6234a24178ed27789eDmitry Shmidt	u8 curr_chan, cand, chan;
808143cb578dfe2c492257636f6234a24178ed27789eDmitry Shmidt	unsigned int i;
808243cb578dfe2c492257636f6234a24178ed27789eDmitry Shmidt
808343cb578dfe2c492257636f6234a24178ed27789eDmitry Shmidt	curr_chan = p2p_get_listen_channel(wpa_s->global->p2p);
808443cb578dfe2c492257636f6234a24178ed27789eDmitry Shmidt	for (i = 0, cand = 0; i < num; i++) {
808543cb578dfe2c492257636f6234a24178ed27789eDmitry Shmidt		ieee80211_freq_to_chan(freqs[i].freq, &chan);
808643cb578dfe2c492257636f6234a24178ed27789eDmitry Shmidt		if (curr_chan == chan) {
808743cb578dfe2c492257636f6234a24178ed27789eDmitry Shmidt			cand = 0;
808843cb578dfe2c492257636f6234a24178ed27789eDmitry Shmidt			break;
808943cb578dfe2c492257636f6234a24178ed27789eDmitry Shmidt		}
809043cb578dfe2c492257636f6234a24178ed27789eDmitry Shmidt
809143cb578dfe2c492257636f6234a24178ed27789eDmitry Shmidt		if (chan == 1 || chan == 6 || chan == 11)
809243cb578dfe2c492257636f6234a24178ed27789eDmitry Shmidt			cand = chan;
809343cb578dfe2c492257636f6234a24178ed27789eDmitry Shmidt	}
809443cb578dfe2c492257636f6234a24178ed27789eDmitry Shmidt
809543cb578dfe2c492257636f6234a24178ed27789eDmitry Shmidt	if (cand) {
809643cb578dfe2c492257636f6234a24178ed27789eDmitry Shmidt		wpa_dbg(wpa_s, MSG_DEBUG,
8097216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt			"P2P: Update Listen channel to %u based on operating channel",
809843cb578dfe2c492257636f6234a24178ed27789eDmitry Shmidt			cand);
809943cb578dfe2c492257636f6234a24178ed27789eDmitry Shmidt		p2p_set_listen_channel(wpa_s->global->p2p, 81, cand, 0);
810043cb578dfe2c492257636f6234a24178ed27789eDmitry Shmidt	}
810143cb578dfe2c492257636f6234a24178ed27789eDmitry Shmidt}
810243cb578dfe2c492257636f6234a24178ed27789eDmitry Shmidt
810343cb578dfe2c492257636f6234a24178ed27789eDmitry Shmidt
810443cb578dfe2c492257636f6234a24178ed27789eDmitry Shmidtvoid wpas_p2p_indicate_state_change(struct wpa_supplicant *wpa_s)
810543cb578dfe2c492257636f6234a24178ed27789eDmitry Shmidt{
810643cb578dfe2c492257636f6234a24178ed27789eDmitry Shmidt	struct wpa_used_freq_data *freqs;
810743cb578dfe2c492257636f6234a24178ed27789eDmitry Shmidt	unsigned int num = wpa_s->num_multichan_concurrent;
810843cb578dfe2c492257636f6234a24178ed27789eDmitry Shmidt
810943cb578dfe2c492257636f6234a24178ed27789eDmitry Shmidt	if (wpa_s->global->p2p_disabled || wpa_s->global->p2p == NULL)
811043cb578dfe2c492257636f6234a24178ed27789eDmitry Shmidt		return;
811143cb578dfe2c492257636f6234a24178ed27789eDmitry Shmidt
811243cb578dfe2c492257636f6234a24178ed27789eDmitry Shmidt	/*
811343cb578dfe2c492257636f6234a24178ed27789eDmitry Shmidt	 * If possible, optimize the Listen channel to be a channel that is
811443cb578dfe2c492257636f6234a24178ed27789eDmitry Shmidt	 * already used by one of the other interfaces.
811543cb578dfe2c492257636f6234a24178ed27789eDmitry Shmidt	 */
811643cb578dfe2c492257636f6234a24178ed27789eDmitry Shmidt	if (!wpa_s->conf->p2p_optimize_listen_chan)
811743cb578dfe2c492257636f6234a24178ed27789eDmitry Shmidt		return;
811843cb578dfe2c492257636f6234a24178ed27789eDmitry Shmidt
811943cb578dfe2c492257636f6234a24178ed27789eDmitry Shmidt	if (!wpa_s->current_ssid || wpa_s->wpa_state != WPA_COMPLETED)
812043cb578dfe2c492257636f6234a24178ed27789eDmitry Shmidt		return;
812143cb578dfe2c492257636f6234a24178ed27789eDmitry Shmidt
812243cb578dfe2c492257636f6234a24178ed27789eDmitry Shmidt	freqs = os_calloc(num, sizeof(struct wpa_used_freq_data));
812343cb578dfe2c492257636f6234a24178ed27789eDmitry Shmidt	if (!freqs)
812443cb578dfe2c492257636f6234a24178ed27789eDmitry Shmidt		return;
812543cb578dfe2c492257636f6234a24178ed27789eDmitry Shmidt
812643cb578dfe2c492257636f6234a24178ed27789eDmitry Shmidt	num = get_shared_radio_freqs_data(wpa_s, freqs, num);
812743cb578dfe2c492257636f6234a24178ed27789eDmitry Shmidt
812843cb578dfe2c492257636f6234a24178ed27789eDmitry Shmidt	wpas_p2p_optimize_listen_channel(wpa_s, freqs, num);
812943cb578dfe2c492257636f6234a24178ed27789eDmitry Shmidt	os_free(freqs);
813043cb578dfe2c492257636f6234a24178ed27789eDmitry Shmidt}
813143cb578dfe2c492257636f6234a24178ed27789eDmitry Shmidt
813243cb578dfe2c492257636f6234a24178ed27789eDmitry Shmidt
813343cb578dfe2c492257636f6234a24178ed27789eDmitry Shmidtvoid wpas_p2p_deinit_iface(struct wpa_supplicant *wpa_s)
813443cb578dfe2c492257636f6234a24178ed27789eDmitry Shmidt{
813543cb578dfe2c492257636f6234a24178ed27789eDmitry Shmidt	if (wpa_s == wpa_s->global->p2p_init_wpa_s && wpa_s->global->p2p) {
813643cb578dfe2c492257636f6234a24178ed27789eDmitry Shmidt		wpa_dbg(wpa_s, MSG_DEBUG, "P2P: Disable P2P since removing "
813743cb578dfe2c492257636f6234a24178ed27789eDmitry Shmidt			"the management interface is being removed");
813843cb578dfe2c492257636f6234a24178ed27789eDmitry Shmidt		wpas_p2p_deinit_global(wpa_s->global);
813943cb578dfe2c492257636f6234a24178ed27789eDmitry Shmidt	}
814043cb578dfe2c492257636f6234a24178ed27789eDmitry Shmidt}
814143cb578dfe2c492257636f6234a24178ed27789eDmitry Shmidt
814243cb578dfe2c492257636f6234a24178ed27789eDmitry Shmidt
814343cb578dfe2c492257636f6234a24178ed27789eDmitry Shmidtvoid wpas_p2p_ap_deinit(struct wpa_supplicant *wpa_s)
814443cb578dfe2c492257636f6234a24178ed27789eDmitry Shmidt{
814543cb578dfe2c492257636f6234a24178ed27789eDmitry Shmidt	if (wpa_s->ap_iface->bss)
814643cb578dfe2c492257636f6234a24178ed27789eDmitry Shmidt		wpa_s->ap_iface->bss[0]->p2p_group = NULL;
814743cb578dfe2c492257636f6234a24178ed27789eDmitry Shmidt	wpas_p2p_group_deinit(wpa_s);
814843cb578dfe2c492257636f6234a24178ed27789eDmitry Shmidt}
8149