p2p_go_neg.c revision 4ce9c87407c036fc83eb5a6044ddf976c86f53fc
18d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt/*
28d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * Wi-Fi Direct - P2P Group Owner Negotiation
38d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * Copyright (c) 2009-2010, Atheros Communications
48d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt *
5c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt * This software may be distributed under the terms of the BSD license.
6c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt * See README for more details.
78d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */
88d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
98d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include "includes.h"
108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include "common.h"
128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include "common/ieee802_11_defs.h"
138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include "wps/wps_defs.h"
148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include "p2p_i.h"
158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include "p2p.h"
168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic int p2p_go_det(u8 own_intent, u8 peer_value)
198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{
208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	u8 peer_intent = peer_value >> 1;
218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (own_intent == peer_intent) {
228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		if (own_intent == P2P_MAX_GO_INTENT)
238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			return -1; /* both devices want to become GO */
248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		/* Use tie breaker bit to determine GO */
268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return (peer_value & 0x01) ? 0 : 1;
278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	return own_intent > peer_intent;
308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt}
318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtint p2p_peer_channels_check(struct p2p_data *p2p, struct p2p_channels *own,
348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			    struct p2p_device *dev,
358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			    const u8 *channel_list, size_t channel_list_len)
368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{
378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	const u8 *pos, *end;
388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	struct p2p_channels *ch;
398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	size_t channels;
408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	struct p2p_channels intersection;
418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	ch = &dev->channels;
438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	os_memset(ch, 0, sizeof(*ch));
448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	pos = channel_list;
458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	end = channel_list + channel_list_len;
468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (end - pos < 3)
488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return -1;
498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	os_memcpy(dev->country, pos, 3);
508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	wpa_hexdump_ascii(MSG_DEBUG, "P2P: Peer country", pos, 3);
518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (pos[2] != 0x04 && os_memcmp(pos, p2p->cfg->country, 2) != 0) {
52b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt		p2p_info(p2p, "Mismatching country (ours=%c%c peer's=%c%c)",
538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			p2p->cfg->country[0], p2p->cfg->country[1],
548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			pos[0], pos[1]);
558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return -1;
568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	pos += 3;
588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	while (pos + 2 < end) {
608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		struct p2p_reg_class *cl = &ch->reg_class[ch->reg_classes];
618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		cl->reg_class = *pos++;
628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		if (pos + 1 + pos[0] > end) {
63b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt			p2p_info(p2p, "Invalid peer Channel List");
648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			return -1;
658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		}
668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		channels = *pos++;
678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		cl->channels = channels > P2P_MAX_REG_CLASS_CHANNELS ?
688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			P2P_MAX_REG_CLASS_CHANNELS : channels;
698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		os_memcpy(cl->channel, pos, cl->channels);
708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		pos += channels;
718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		ch->reg_classes++;
728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		if (ch->reg_classes == P2P_MAX_REG_CLASSES)
738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			break;
748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	p2p_channels_intersect(own, &dev->channels, &intersection);
77b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt	p2p_dbg(p2p, "Own reg_classes %d peer reg_classes %d intersection reg_classes %d",
788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		(int) own->reg_classes,
798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		(int) dev->channels.reg_classes,
808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		(int) intersection.reg_classes);
818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (intersection.reg_classes == 0) {
82b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt		p2p_info(p2p, "No common channels found");
838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return -1;
848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	return 0;
868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt}
878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic int p2p_peer_channels(struct p2p_data *p2p, struct p2p_device *dev,
908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			     const u8 *channel_list, size_t channel_list_len)
918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{
928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	return p2p_peer_channels_check(p2p, &p2p->channels, dev,
938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt				       channel_list, channel_list_len);
948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt}
958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
9704949598a23f501be6eec21697465fd46a28840aDmitry Shmidtu16 p2p_wps_method_pw_id(enum p2p_wps_method wps_method)
988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{
998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	switch (wps_method) {
1008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	case WPS_PIN_DISPLAY:
1018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return DEV_PW_REGISTRAR_SPECIFIED;
1028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	case WPS_PIN_KEYPAD:
1038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return DEV_PW_USER_SPECIFIED;
1048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	case WPS_PBC:
1058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return DEV_PW_PUSHBUTTON;
1068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	default:
1078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return DEV_PW_DEFAULT;
1088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
1098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt}
1108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
1118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
1128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic const char * p2p_wps_method_str(enum p2p_wps_method wps_method)
1138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{
1148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	switch (wps_method) {
1158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	case WPS_PIN_DISPLAY:
1168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return "Display";
1178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	case WPS_PIN_KEYPAD:
1188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return "Keypad";
1198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	case WPS_PBC:
1208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return "PBC";
1218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	default:
1228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return "??";
1238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
1248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt}
1258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
1268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
1278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic struct wpabuf * p2p_build_go_neg_req(struct p2p_data *p2p,
1288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt					    struct p2p_device *peer)
1298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{
1308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	struct wpabuf *buf;
1318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	u8 *len;
1328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	u8 group_capab;
13361d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt	size_t extra = 0;
1348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
13561d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt#ifdef CONFIG_WIFI_DISPLAY
13661d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt	if (p2p->wfd_ie_go_neg)
13761d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt		extra = wpabuf_len(p2p->wfd_ie_go_neg);
13861d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt#endif /* CONFIG_WIFI_DISPLAY */
13961d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt
14061d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt	buf = wpabuf_alloc(1000 + extra);
1418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (buf == NULL)
1428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return NULL;
1438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
1448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	p2p_buf_add_public_action_hdr(buf, P2P_GO_NEG_REQ, peer->dialog_token);
1458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
1468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	len = p2p_buf_add_ie_hdr(buf);
1478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	group_capab = 0;
1481f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt	if (peer->flags & P2P_DEV_PREFER_PERSISTENT_GROUP) {
1498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		group_capab |= P2P_GROUP_CAPAB_PERSISTENT_GROUP;
1501f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt		if (peer->flags & P2P_DEV_PREFER_PERSISTENT_RECONN)
1511f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt			group_capab |= P2P_GROUP_CAPAB_PERSISTENT_RECONN;
1521f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt	}
1538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (p2p->cross_connect)
1548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		group_capab |= P2P_GROUP_CAPAB_CROSS_CONN;
1558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (p2p->cfg->p2p_intra_bss)
1568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		group_capab |= P2P_GROUP_CAPAB_INTRA_BSS_DIST;
15704949598a23f501be6eec21697465fd46a28840aDmitry Shmidt	p2p_buf_add_capability(buf, p2p->dev_capab &
15804949598a23f501be6eec21697465fd46a28840aDmitry Shmidt			       ~P2P_DEV_CAPAB_CLIENT_DISCOVERABILITY,
15904949598a23f501be6eec21697465fd46a28840aDmitry Shmidt			       group_capab);
1609cdf1b905fae57dea42506a1af67f6ece544b261Dmitry Shmidt	p2p_buf_add_go_intent(buf, (p2p->go_intent << 1) | peer->tie_breaker);
16161d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt	p2p_buf_add_config_timeout(buf, p2p->go_timeout, p2p->client_timeout);
1628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	p2p_buf_add_listen_channel(buf, p2p->cfg->country, p2p->cfg->reg_class,
1638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt				   p2p->cfg->channel);
1648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (p2p->ext_listen_interval)
1658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		p2p_buf_add_ext_listen_timing(buf, p2p->ext_listen_period,
1668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt					      p2p->ext_listen_interval);
1678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	p2p_buf_add_intended_addr(buf, p2p->intended_addr);
168069fa2c39ec7120656a2ea8cca83c5ee41ddab60Irfan Sheriff	p2p_buf_add_channel_list(buf, p2p->cfg->country, &p2p->channels);
1698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	p2p_buf_add_device_info(buf, p2p, peer);
1708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	p2p_buf_add_operating_channel(buf, p2p->cfg->country,
1718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt				      p2p->op_reg_class, p2p->op_channel);
1728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	p2p_buf_update_ie_hdr(buf, len);
1738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
1748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	/* WPS IE with Device Password ID attribute */
1758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	p2p_build_wps_ie(p2p, buf, p2p_wps_method_pw_id(peer->wps_method), 0);
1768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
17761d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt#ifdef CONFIG_WIFI_DISPLAY
17861d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt	if (p2p->wfd_ie_go_neg)
17961d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt		wpabuf_put_buf(buf, p2p->wfd_ie_go_neg);
18061d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt#endif /* CONFIG_WIFI_DISPLAY */
18161d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt
1828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	return buf;
1838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt}
1848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
1858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
1868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtint p2p_connect_send(struct p2p_data *p2p, struct p2p_device *dev)
1878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{
1888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	struct wpabuf *req;
1898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	int freq;
1908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
19104949598a23f501be6eec21697465fd46a28840aDmitry Shmidt	if (dev->flags & P2P_DEV_PD_BEFORE_GO_NEG) {
19204949598a23f501be6eec21697465fd46a28840aDmitry Shmidt		u16 config_method;
193b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt		p2p_dbg(p2p, "Use PD-before-GO-Neg workaround for " MACSTR,
19404949598a23f501be6eec21697465fd46a28840aDmitry Shmidt			MAC2STR(dev->info.p2p_device_addr));
19504949598a23f501be6eec21697465fd46a28840aDmitry Shmidt		if (dev->wps_method == WPS_PIN_DISPLAY)
19604949598a23f501be6eec21697465fd46a28840aDmitry Shmidt			config_method = WPS_CONFIG_KEYPAD;
19704949598a23f501be6eec21697465fd46a28840aDmitry Shmidt		else if (dev->wps_method == WPS_PIN_KEYPAD)
19804949598a23f501be6eec21697465fd46a28840aDmitry Shmidt			config_method = WPS_CONFIG_DISPLAY;
19904949598a23f501be6eec21697465fd46a28840aDmitry Shmidt		else if (dev->wps_method == WPS_PBC)
20004949598a23f501be6eec21697465fd46a28840aDmitry Shmidt			config_method = WPS_CONFIG_PUSHBUTTON;
20104949598a23f501be6eec21697465fd46a28840aDmitry Shmidt		else
20204949598a23f501be6eec21697465fd46a28840aDmitry Shmidt			return -1;
20304949598a23f501be6eec21697465fd46a28840aDmitry Shmidt		return p2p_prov_disc_req(p2p, dev->info.p2p_device_addr,
204d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt					 config_method, 0, 0, 1);
20504949598a23f501be6eec21697465fd46a28840aDmitry Shmidt	}
20604949598a23f501be6eec21697465fd46a28840aDmitry Shmidt
2078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	freq = dev->listen_freq > 0 ? dev->listen_freq : dev->oper_freq;
2088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (freq <= 0) {
209b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt		p2p_dbg(p2p, "No Listen/Operating frequency known for the peer "
210b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt			MACSTR " to send GO Negotiation Request",
2118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			MAC2STR(dev->info.p2p_device_addr));
2128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return -1;
2138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
2148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
2158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	req = p2p_build_go_neg_req(p2p, dev);
2168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (req == NULL)
2178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return -1;
218b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt	p2p_dbg(p2p, "Sending GO Negotiation Request");
2198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	p2p_set_state(p2p, P2P_CONNECT);
2208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	p2p->pending_action_state = P2P_PENDING_GO_NEG_REQUEST;
2218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	p2p->go_neg_peer = dev;
2228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	dev->flags |= P2P_DEV_WAIT_GO_NEG_RESPONSE;
2238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	dev->connect_reqs++;
2248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (p2p_send_action(p2p, freq, dev->info.p2p_device_addr,
2258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			    p2p->cfg->dev_addr, dev->info.p2p_device_addr,
2268c65289885e84727226d81b3d32856f79c31ee5fDmitry Shmidt			    wpabuf_head(req), wpabuf_len(req), 500) < 0) {
227b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt		p2p_dbg(p2p, "Failed to send Action frame");
2288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		/* Use P2P find to recover and retry */
2298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		p2p_set_timeout(p2p, 0, 0);
23004949598a23f501be6eec21697465fd46a28840aDmitry Shmidt	} else
23104949598a23f501be6eec21697465fd46a28840aDmitry Shmidt		dev->go_neg_req_sent++;
2328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
2338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	wpabuf_free(req);
2348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
2358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	return 0;
2368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt}
2378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
2388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
2398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic struct wpabuf * p2p_build_go_neg_resp(struct p2p_data *p2p,
2408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt					     struct p2p_device *peer,
2418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt					     u8 dialog_token, u8 status,
2428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt					     u8 tie_breaker)
2438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{
2448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	struct wpabuf *buf;
2458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	u8 *len;
2468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	u8 group_capab;
24761d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt	size_t extra = 0;
2488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
249b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt	p2p_dbg(p2p, "Building GO Negotiation Response");
25061d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt
25161d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt#ifdef CONFIG_WIFI_DISPLAY
25261d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt	if (p2p->wfd_ie_go_neg)
25361d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt		extra = wpabuf_len(p2p->wfd_ie_go_neg);
25461d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt#endif /* CONFIG_WIFI_DISPLAY */
25561d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt
25661d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt	buf = wpabuf_alloc(1000 + extra);
2578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (buf == NULL)
2588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return NULL;
2598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
2608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	p2p_buf_add_public_action_hdr(buf, P2P_GO_NEG_RESP, dialog_token);
2618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
2628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	len = p2p_buf_add_ie_hdr(buf);
2638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	p2p_buf_add_status(buf, status);
2648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	group_capab = 0;
2658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (peer && peer->go_state == LOCAL_GO) {
2661f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt		if (peer->flags & P2P_DEV_PREFER_PERSISTENT_GROUP) {
2678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			group_capab |= P2P_GROUP_CAPAB_PERSISTENT_GROUP;
2681f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt			if (peer->flags & P2P_DEV_PREFER_PERSISTENT_RECONN)
2691f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt				group_capab |=
2701f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt					P2P_GROUP_CAPAB_PERSISTENT_RECONN;
2711f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt		}
2728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		if (p2p->cross_connect)
2738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			group_capab |= P2P_GROUP_CAPAB_CROSS_CONN;
2748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		if (p2p->cfg->p2p_intra_bss)
2758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			group_capab |= P2P_GROUP_CAPAB_INTRA_BSS_DIST;
2768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
27704949598a23f501be6eec21697465fd46a28840aDmitry Shmidt	p2p_buf_add_capability(buf, p2p->dev_capab &
27804949598a23f501be6eec21697465fd46a28840aDmitry Shmidt			       ~P2P_DEV_CAPAB_CLIENT_DISCOVERABILITY,
27904949598a23f501be6eec21697465fd46a28840aDmitry Shmidt			       group_capab);
2808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	p2p_buf_add_go_intent(buf, (p2p->go_intent << 1) | tie_breaker);
28161d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt	p2p_buf_add_config_timeout(buf, p2p->go_timeout, p2p->client_timeout);
2828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (peer && peer->go_state == REMOTE_GO) {
283b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt		p2p_dbg(p2p, "Omit Operating Channel attribute");
2848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	} else {
2858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		p2p_buf_add_operating_channel(buf, p2p->cfg->country,
2868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt					      p2p->op_reg_class,
2878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt					      p2p->op_channel);
2888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
2898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	p2p_buf_add_intended_addr(buf, p2p->intended_addr);
290069fa2c39ec7120656a2ea8cca83c5ee41ddab60Irfan Sheriff	if (status || peer == NULL) {
291069fa2c39ec7120656a2ea8cca83c5ee41ddab60Irfan Sheriff		p2p_buf_add_channel_list(buf, p2p->cfg->country,
292069fa2c39ec7120656a2ea8cca83c5ee41ddab60Irfan Sheriff					 &p2p->channels);
293069fa2c39ec7120656a2ea8cca83c5ee41ddab60Irfan Sheriff	} else if (peer->go_state == REMOTE_GO) {
294069fa2c39ec7120656a2ea8cca83c5ee41ddab60Irfan Sheriff		p2p_buf_add_channel_list(buf, p2p->cfg->country,
295069fa2c39ec7120656a2ea8cca83c5ee41ddab60Irfan Sheriff					 &p2p->channels);
2968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	} else {
297069fa2c39ec7120656a2ea8cca83c5ee41ddab60Irfan Sheriff		struct p2p_channels res;
298069fa2c39ec7120656a2ea8cca83c5ee41ddab60Irfan Sheriff		p2p_channels_intersect(&p2p->channels, &peer->channels,
299069fa2c39ec7120656a2ea8cca83c5ee41ddab60Irfan Sheriff				       &res);
300069fa2c39ec7120656a2ea8cca83c5ee41ddab60Irfan Sheriff		p2p_buf_add_channel_list(buf, p2p->cfg->country, &res);
3018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
3028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	p2p_buf_add_device_info(buf, p2p, peer);
3038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (peer && peer->go_state == LOCAL_GO) {
3048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		p2p_buf_add_group_id(buf, p2p->cfg->dev_addr, p2p->ssid,
3058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt				     p2p->ssid_len);
3068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
3078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	p2p_buf_update_ie_hdr(buf, len);
3088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
3098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	/* WPS IE with Device Password ID attribute */
3108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	p2p_build_wps_ie(p2p, buf,
3118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			 p2p_wps_method_pw_id(peer ? peer->wps_method :
3128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt					      WPS_NOT_READY), 0);
3138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
31461d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt#ifdef CONFIG_WIFI_DISPLAY
31561d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt	if (p2p->wfd_ie_go_neg)
31661d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt		wpabuf_put_buf(buf, p2p->wfd_ie_go_neg);
31761d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt#endif /* CONFIG_WIFI_DISPLAY */
31861d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt
31961d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt
3208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	return buf;
3218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt}
3228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
3238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
324a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt/**
325a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt * p2p_reselect_channel - Re-select operating channel based on peer information
326a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt * @p2p: P2P module context from p2p_init()
327a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt * @intersection: Support channel list intersection from local and peer
328a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt *
329a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt * This function is used to re-select the best channel after having received
330a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt * information from the peer to allow supported channel lists to be intersected.
331a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt * This can be used to improve initial channel selection done in
332a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt * p2p_prepare_channel() prior to the start of GO Negotiation. In addition, this
333a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt * can be used for Invitation case.
334a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt */
33591c40cdce17424d9a4718876becf0b7811cf68f2Dmitry Shmidtvoid p2p_reselect_channel(struct p2p_data *p2p,
33691c40cdce17424d9a4718876becf0b7811cf68f2Dmitry Shmidt			  struct p2p_channels *intersection)
3378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{
3388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	struct p2p_reg_class *cl;
3398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	int freq;
3408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	u8 op_reg_class, op_channel;
34104949598a23f501be6eec21697465fd46a28840aDmitry Shmidt	unsigned int i;
3428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
343700a137ab366edc72e371da68ba187b4717ee660Dmitry Shmidt	if (p2p->own_freq_preference > 0 &&
3444b06059785b935dd1f4f09314e4e12c417d2c6a4Dmitry Shmidt	    p2p_freq_to_channel(p2p->own_freq_preference,
345700a137ab366edc72e371da68ba187b4717ee660Dmitry Shmidt				&op_reg_class, &op_channel) == 0 &&
346700a137ab366edc72e371da68ba187b4717ee660Dmitry Shmidt	    p2p_channels_includes(intersection, op_reg_class, op_channel)) {
347b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt		p2p_dbg(p2p, "Pick own channel preference (reg_class %u channel %u) from intersection",
348b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt			op_reg_class, op_channel);
349700a137ab366edc72e371da68ba187b4717ee660Dmitry Shmidt		p2p->op_reg_class = op_reg_class;
350700a137ab366edc72e371da68ba187b4717ee660Dmitry Shmidt		p2p->op_channel = op_channel;
351700a137ab366edc72e371da68ba187b4717ee660Dmitry Shmidt		return;
352700a137ab366edc72e371da68ba187b4717ee660Dmitry Shmidt	}
353700a137ab366edc72e371da68ba187b4717ee660Dmitry Shmidt
354700a137ab366edc72e371da68ba187b4717ee660Dmitry Shmidt	if (p2p->best_freq_overall > 0 &&
3554b06059785b935dd1f4f09314e4e12c417d2c6a4Dmitry Shmidt	    p2p_freq_to_channel(p2p->best_freq_overall,
356700a137ab366edc72e371da68ba187b4717ee660Dmitry Shmidt				&op_reg_class, &op_channel) == 0 &&
357700a137ab366edc72e371da68ba187b4717ee660Dmitry Shmidt	    p2p_channels_includes(intersection, op_reg_class, op_channel)) {
358b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt		p2p_dbg(p2p, "Pick best overall channel (reg_class %u channel %u) from intersection",
359700a137ab366edc72e371da68ba187b4717ee660Dmitry Shmidt			op_reg_class, op_channel);
360700a137ab366edc72e371da68ba187b4717ee660Dmitry Shmidt		p2p->op_reg_class = op_reg_class;
361700a137ab366edc72e371da68ba187b4717ee660Dmitry Shmidt		p2p->op_channel = op_channel;
362700a137ab366edc72e371da68ba187b4717ee660Dmitry Shmidt		return;
363700a137ab366edc72e371da68ba187b4717ee660Dmitry Shmidt	}
3648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
3658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	/* First, try to pick the best channel from another band */
3664b06059785b935dd1f4f09314e4e12c417d2c6a4Dmitry Shmidt	freq = p2p_channel_to_freq(p2p->op_reg_class, p2p->op_channel);
3678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (freq >= 2400 && freq < 2500 && p2p->best_freq_5 > 0 &&
368700a137ab366edc72e371da68ba187b4717ee660Dmitry Shmidt	    !p2p_channels_includes(intersection, p2p->op_reg_class,
369700a137ab366edc72e371da68ba187b4717ee660Dmitry Shmidt				   p2p->op_channel) &&
3704b06059785b935dd1f4f09314e4e12c417d2c6a4Dmitry Shmidt	    p2p_freq_to_channel(p2p->best_freq_5,
3718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt				&op_reg_class, &op_channel) == 0 &&
3728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	    p2p_channels_includes(intersection, op_reg_class, op_channel)) {
373b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt		p2p_dbg(p2p, "Pick best 5 GHz channel (reg_class %u channel %u) from intersection",
3748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			op_reg_class, op_channel);
3758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		p2p->op_reg_class = op_reg_class;
3768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		p2p->op_channel = op_channel;
3778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return;
3788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
3798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
3808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (freq >= 4900 && freq < 6000 && p2p->best_freq_24 > 0 &&
381700a137ab366edc72e371da68ba187b4717ee660Dmitry Shmidt	    !p2p_channels_includes(intersection, p2p->op_reg_class,
382700a137ab366edc72e371da68ba187b4717ee660Dmitry Shmidt				   p2p->op_channel) &&
3834b06059785b935dd1f4f09314e4e12c417d2c6a4Dmitry Shmidt	    p2p_freq_to_channel(p2p->best_freq_24,
3848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt				&op_reg_class, &op_channel) == 0 &&
3858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	    p2p_channels_includes(intersection, op_reg_class, op_channel)) {
386b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt		p2p_dbg(p2p, "Pick best 2.4 GHz channel (reg_class %u channel %u) from intersection",
3878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			op_reg_class, op_channel);
3888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		p2p->op_reg_class = op_reg_class;
3898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		p2p->op_channel = op_channel;
3908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return;
3918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
3928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
39304949598a23f501be6eec21697465fd46a28840aDmitry Shmidt	/* Select channel with highest preference if the peer supports it */
39404949598a23f501be6eec21697465fd46a28840aDmitry Shmidt	for (i = 0; p2p->cfg->pref_chan && i < p2p->cfg->num_pref_chan; i++) {
39504949598a23f501be6eec21697465fd46a28840aDmitry Shmidt		if (p2p_channels_includes(intersection,
39604949598a23f501be6eec21697465fd46a28840aDmitry Shmidt					  p2p->cfg->pref_chan[i].op_class,
39704949598a23f501be6eec21697465fd46a28840aDmitry Shmidt					  p2p->cfg->pref_chan[i].chan)) {
39804949598a23f501be6eec21697465fd46a28840aDmitry Shmidt			p2p->op_reg_class = p2p->cfg->pref_chan[i].op_class;
39904949598a23f501be6eec21697465fd46a28840aDmitry Shmidt			p2p->op_channel = p2p->cfg->pref_chan[i].chan;
400b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt			p2p_dbg(p2p, "Pick highest preferred channel (op_class %u channel %u) from intersection",
40104949598a23f501be6eec21697465fd46a28840aDmitry Shmidt				p2p->op_reg_class, p2p->op_channel);
40204949598a23f501be6eec21697465fd46a28840aDmitry Shmidt			return;
40304949598a23f501be6eec21697465fd46a28840aDmitry Shmidt		}
40404949598a23f501be6eec21697465fd46a28840aDmitry Shmidt	}
40504949598a23f501be6eec21697465fd46a28840aDmitry Shmidt
406a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt	/* Try a channel where we might be able to use HT40 */
407a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt	for (i = 0; i < intersection->reg_classes; i++) {
408a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt		struct p2p_reg_class *c = &intersection->reg_class[i];
409a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt		if (c->reg_class == 116 || c->reg_class == 117 ||
410a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt		    c->reg_class == 126 || c->reg_class == 127) {
411b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt			p2p_dbg(p2p, "Pick possible HT40 channel (reg_class %u channel %u) from intersection",
412a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt				c->reg_class, c->channel[0]);
413a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt			p2p->op_reg_class = c->reg_class;
414a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt			p2p->op_channel = c->channel[0];
415a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt			return;
416a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt		}
417a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt	}
418a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt
41903b5cdf515ae7259d67b33c22d829495ac80e631Hardik Kantilal Patel	/* Prefer a 5 GHz channel */
42003b5cdf515ae7259d67b33c22d829495ac80e631Hardik Kantilal Patel	for (i = 0; i < intersection->reg_classes; i++) {
421edcc8d627804a0c1140542da2380c83a8c03b7a9Dmitry Shmidt#ifdef ANDROID_P2P
422edcc8d627804a0c1140542da2380c83a8c03b7a9Dmitry Shmidt		struct p2p_reg_class prc;
423edcc8d627804a0c1140542da2380c83a8c03b7a9Dmitry Shmidt		struct p2p_reg_class *c = &prc;
424edcc8d627804a0c1140542da2380c83a8c03b7a9Dmitry Shmidt		p2p_copy_reg_class(c, &intersection->reg_class[i]);
425edcc8d627804a0c1140542da2380c83a8c03b7a9Dmitry Shmidt#else
42603b5cdf515ae7259d67b33c22d829495ac80e631Hardik Kantilal Patel		struct p2p_reg_class *c = &intersection->reg_class[i];
427edcc8d627804a0c1140542da2380c83a8c03b7a9Dmitry Shmidt#endif
42803b5cdf515ae7259d67b33c22d829495ac80e631Hardik Kantilal Patel		if ((c->reg_class == 115 || c->reg_class == 124) &&
42903b5cdf515ae7259d67b33c22d829495ac80e631Hardik Kantilal Patel		    c->channels) {
43003b5cdf515ae7259d67b33c22d829495ac80e631Hardik Kantilal Patel			unsigned int r;
43103b5cdf515ae7259d67b33c22d829495ac80e631Hardik Kantilal Patel
43203b5cdf515ae7259d67b33c22d829495ac80e631Hardik Kantilal Patel			/*
43303b5cdf515ae7259d67b33c22d829495ac80e631Hardik Kantilal Patel			 * Pick one of the available channels in the operating
43403b5cdf515ae7259d67b33c22d829495ac80e631Hardik Kantilal Patel			 * class at random.
43503b5cdf515ae7259d67b33c22d829495ac80e631Hardik Kantilal Patel			 */
43603b5cdf515ae7259d67b33c22d829495ac80e631Hardik Kantilal Patel			os_get_random((u8 *) &r, sizeof(r));
43703b5cdf515ae7259d67b33c22d829495ac80e631Hardik Kantilal Patel			r %= c->channels;
43803b5cdf515ae7259d67b33c22d829495ac80e631Hardik Kantilal Patel			p2p_dbg(p2p, "Pick possible 5 GHz channel (op_class %u channel %u) from intersection",
43903b5cdf515ae7259d67b33c22d829495ac80e631Hardik Kantilal Patel				c->reg_class, c->channel[r]);
44003b5cdf515ae7259d67b33c22d829495ac80e631Hardik Kantilal Patel			p2p->op_reg_class = c->reg_class;
44103b5cdf515ae7259d67b33c22d829495ac80e631Hardik Kantilal Patel			p2p->op_channel = c->channel[r];
44203b5cdf515ae7259d67b33c22d829495ac80e631Hardik Kantilal Patel			return;
44303b5cdf515ae7259d67b33c22d829495ac80e631Hardik Kantilal Patel		}
44403b5cdf515ae7259d67b33c22d829495ac80e631Hardik Kantilal Patel	}
44503b5cdf515ae7259d67b33c22d829495ac80e631Hardik Kantilal Patel
446a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt	/*
447a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt	 * Try to see if the original channel is in the intersection. If
448a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt	 * so, no need to change anything, as it already contains some
449a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt	 * randomness.
450a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt	 */
451a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt	if (p2p_channels_includes(intersection, p2p->op_reg_class,
452a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt				  p2p->op_channel)) {
453b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt		p2p_dbg(p2p, "Using original operating class and channel (op_class %u channel %u) from intersection",
454a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt			p2p->op_reg_class, p2p->op_channel);
455a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt		return;
456a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt	}
457a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt
4588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	/*
4598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	 * Fall back to whatever is included in the channel intersection since
4608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	 * no better options seems to be available.
4618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	 */
4628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	cl = &intersection->reg_class[0];
463b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt	p2p_dbg(p2p, "Pick another channel (reg_class %u channel %u) from intersection",
4648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		cl->reg_class, cl->channel[0]);
4658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	p2p->op_reg_class = cl->reg_class;
4668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	p2p->op_channel = cl->channel[0];
4678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt}
4688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
4698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
470a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidtstatic int p2p_go_select_channel(struct p2p_data *p2p, struct p2p_device *dev,
471a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt				 u8 *status)
472a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt{
473a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt	struct p2p_channels intersection;
474a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt
4754ce9c87407c036fc83eb5a6044ddf976c86f53fcDmitry Shmidt	p2p_channels_dump(p2p, "own channels", &p2p->channels);
4764ce9c87407c036fc83eb5a6044ddf976c86f53fcDmitry Shmidt	p2p_channels_dump(p2p, "peer channels", &dev->channels);
477a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt	p2p_channels_intersect(&p2p->channels, &dev->channels, &intersection);
4784ce9c87407c036fc83eb5a6044ddf976c86f53fcDmitry Shmidt	p2p_channels_dump(p2p, "intersection", &intersection);
479a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt	if (intersection.reg_classes == 0 ||
480a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt	    intersection.reg_class[0].channels == 0) {
481a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt		*status = P2P_SC_FAIL_NO_COMMON_CHANNELS;
482b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt		p2p_dbg(p2p, "No common channels found");
483a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt		return -1;
484a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt	}
485a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt
486a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt	if (!p2p_channels_includes(&intersection, p2p->op_reg_class,
487a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt				   p2p->op_channel)) {
488a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt		if (dev->flags & P2P_DEV_FORCE_FREQ) {
489a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt			*status = P2P_SC_FAIL_NO_COMMON_CHANNELS;
490b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt			p2p_dbg(p2p, "Peer does not support the forced channel");
491a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt			return -1;
492a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt		}
493a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt
494b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt		p2p_dbg(p2p, "Selected operating channel (op_class %u channel %u) not acceptable to the peer",
495b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt			p2p->op_reg_class, p2p->op_channel);
496a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt		p2p_reselect_channel(p2p, &intersection);
497a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt	} else if (!(dev->flags & P2P_DEV_FORCE_FREQ) &&
498a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt		   !p2p->cfg->cfg_op_channel) {
499b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt		p2p_dbg(p2p, "Try to optimize channel selection with peer information received; previously selected op_class %u channel %u",
500a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt			p2p->op_reg_class, p2p->op_channel);
501a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt		p2p_reselect_channel(p2p, &intersection);
502a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt	}
503a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt
504a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt	if (!p2p->ssid_set) {
505a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt		p2p_build_ssid(p2p, p2p->ssid, &p2p->ssid_len);
506a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt		p2p->ssid_set = 1;
507a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt	}
508a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt
509a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt	return 0;
510a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt}
511a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt
512a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt
5138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtvoid p2p_process_go_neg_req(struct p2p_data *p2p, const u8 *sa,
5148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			    const u8 *data, size_t len, int rx_freq)
5158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{
5168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	struct p2p_device *dev = NULL;
5178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	struct wpabuf *resp;
5188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	struct p2p_message msg;
5198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	u8 status = P2P_SC_FAIL_INVALID_PARAMS;
5208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	int tie_breaker = 0;
5218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	int freq;
5228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
523b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt	p2p_dbg(p2p, "Received GO Negotiation Request from " MACSTR "(freq=%d)",
524b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt		MAC2STR(sa), rx_freq);
5258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
5268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (p2p_parse(data, len, &msg))
5278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return;
5288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
5298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (!msg.capability) {
530b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt		p2p_dbg(p2p, "Mandatory Capability attribute missing from GO Negotiation Request");
5318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#ifdef CONFIG_P2P_STRICT
5328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		goto fail;
5338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#endif /* CONFIG_P2P_STRICT */
5348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
5358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
5368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (msg.go_intent)
5378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		tie_breaker = *msg.go_intent & 0x01;
5388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	else {
539b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt		p2p_dbg(p2p, "Mandatory GO Intent attribute missing from GO Negotiation Request");
5408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#ifdef CONFIG_P2P_STRICT
5418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		goto fail;
5428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#endif /* CONFIG_P2P_STRICT */
5438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
5448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
5458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (!msg.config_timeout) {
546b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt		p2p_dbg(p2p, "Mandatory Configuration Timeout attribute missing from GO Negotiation Request");
5478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#ifdef CONFIG_P2P_STRICT
5488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		goto fail;
5498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#endif /* CONFIG_P2P_STRICT */
5508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
5518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
5528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (!msg.listen_channel) {
553b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt		p2p_dbg(p2p, "No Listen Channel attribute received");
5548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		goto fail;
5558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
5568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (!msg.operating_channel) {
557b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt		p2p_dbg(p2p, "No Operating Channel attribute received");
5588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		goto fail;
5598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
5608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (!msg.channel_list) {
561b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt		p2p_dbg(p2p, "No Channel List attribute received");
5628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		goto fail;
5638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
5648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (!msg.intended_addr) {
565b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt		p2p_dbg(p2p, "No Intended P2P Interface Address attribute received");
5668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		goto fail;
5678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
5688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (!msg.p2p_device_info) {
569b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt		p2p_dbg(p2p, "No P2P Device Info attribute received");
5708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		goto fail;
5718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
5728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
5738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (os_memcmp(msg.p2p_device_addr, sa, ETH_ALEN) != 0) {
574b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt		p2p_dbg(p2p, "Unexpected GO Negotiation Request SA=" MACSTR
5758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			" != dev_addr=" MACSTR,
5768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			MAC2STR(sa), MAC2STR(msg.p2p_device_addr));
5778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		goto fail;
5788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
5798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
5808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	dev = p2p_get_device(p2p, sa);
5818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
5828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (msg.status && *msg.status) {
583b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt		p2p_dbg(p2p, "Unexpected Status attribute (%d) in GO Negotiation Request",
584b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt			*msg.status);
5858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		goto fail;
5868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
5878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
5888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (dev == NULL)
5898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		dev = p2p_add_dev_from_go_neg_req(p2p, sa, &msg);
5908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	else if (dev->flags & P2P_DEV_PROBE_REQ_ONLY)
5918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		p2p_add_dev_info(p2p, sa, dev, &msg);
5928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (dev && dev->flags & P2P_DEV_USER_REJECTED) {
593b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt		p2p_dbg(p2p, "User has rejected this peer");
5948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		status = P2P_SC_FAIL_REJECTED_BY_USER;
5958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	} else if (dev == NULL || dev->wps_method == WPS_NOT_READY) {
596b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt		p2p_dbg(p2p, "Not ready for GO negotiation with " MACSTR,
5978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			MAC2STR(sa));
5988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		status = P2P_SC_FAIL_INFO_CURRENTLY_UNAVAILABLE;
5998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		p2p->cfg->go_neg_req_rx(p2p->cfg->cb_ctx, sa,
6008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt					msg.dev_password_id);
6018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	} else if (p2p->go_neg_peer && p2p->go_neg_peer != dev) {
602b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt		p2p_dbg(p2p, "Already in Group Formation with another peer");
6038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		status = P2P_SC_FAIL_UNABLE_TO_ACCOMMODATE;
6048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	} else {
6058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		int go;
6068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
6078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		if (!p2p->go_neg_peer) {
608b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt			p2p_dbg(p2p, "Starting GO Negotiation with previously authorized peer");
6098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			if (!(dev->flags & P2P_DEV_FORCE_FREQ)) {
610b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt				p2p_dbg(p2p, "Use default channel settings");
6118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt				p2p->op_reg_class = p2p->cfg->op_reg_class;
6128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt				p2p->op_channel = p2p->cfg->op_channel;
6138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt				os_memcpy(&p2p->channels, &p2p->cfg->channels,
6148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt					  sizeof(struct p2p_channels));
6158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			} else {
616b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt				p2p_dbg(p2p, "Use previously configured forced channel settings");
6178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			}
6188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		}
6198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
6208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		dev->flags &= ~P2P_DEV_NOT_YET_READY;
6218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
6228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		if (!msg.go_intent) {
623b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt			p2p_dbg(p2p, "No GO Intent attribute received");
6248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			goto fail;
6258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		}
6268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		if ((*msg.go_intent >> 1) > P2P_MAX_GO_INTENT) {
627b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt			p2p_dbg(p2p, "Invalid GO Intent value (%u) received",
6288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt				*msg.go_intent >> 1);
6298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			goto fail;
6308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		}
6318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
6328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		if (dev->go_neg_req_sent &&
6338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		    os_memcmp(sa, p2p->cfg->dev_addr, ETH_ALEN) > 0) {
634b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt			p2p_dbg(p2p, "Do not reply since peer has higher address and GO Neg Request already sent");
6358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			p2p_parse_free(&msg);
6368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			return;
6378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		}
6388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
6398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		go = p2p_go_det(p2p->go_intent, *msg.go_intent);
6408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		if (go < 0) {
641b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt			p2p_dbg(p2p, "Incompatible GO Intent");
6428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			status = P2P_SC_FAIL_BOTH_GO_INTENT_15;
6438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			goto fail;
6448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		}
6458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
6468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		if (p2p_peer_channels(p2p, dev, msg.channel_list,
6478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt				      msg.channel_list_len) < 0) {
648b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt			p2p_dbg(p2p, "No common channels found");
6498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			status = P2P_SC_FAIL_NO_COMMON_CHANNELS;
6508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			goto fail;
6518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		}
6528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
6538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		switch (msg.dev_password_id) {
6548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		case DEV_PW_REGISTRAR_SPECIFIED:
655b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt			p2p_dbg(p2p, "PIN from peer Display");
6568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			if (dev->wps_method != WPS_PIN_KEYPAD) {
657b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt				p2p_dbg(p2p, "We have wps_method=%s -> incompatible",
6588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt					p2p_wps_method_str(dev->wps_method));
6598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt				status = P2P_SC_FAIL_INCOMPATIBLE_PROV_METHOD;
6608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt				goto fail;
6618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			}
6628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			break;
6638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		case DEV_PW_USER_SPECIFIED:
664b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt			p2p_dbg(p2p, "Peer entered PIN on Keypad");
6651f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt			if (dev->wps_method != WPS_PIN_DISPLAY) {
666b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt				p2p_dbg(p2p, "We have wps_method=%s -> incompatible",
6678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt					p2p_wps_method_str(dev->wps_method));
6688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt				status = P2P_SC_FAIL_INCOMPATIBLE_PROV_METHOD;
6698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt				goto fail;
6708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			}
6718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			break;
6728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		case DEV_PW_PUSHBUTTON:
673b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt			p2p_dbg(p2p, "Peer using pushbutton");
6748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			if (dev->wps_method != WPS_PBC) {
675b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt				p2p_dbg(p2p, "We have wps_method=%s -> incompatible",
6768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt					p2p_wps_method_str(dev->wps_method));
6778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt				status = P2P_SC_FAIL_INCOMPATIBLE_PROV_METHOD;
6788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt				goto fail;
6798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			}
6808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			break;
6818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		default:
682b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt			p2p_dbg(p2p, "Unsupported Device Password ID %d",
6838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt				msg.dev_password_id);
6848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			status = P2P_SC_FAIL_INCOMPATIBLE_PROV_METHOD;
6858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			goto fail;
6868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		}
6878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
688a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt		if (go && p2p_go_select_channel(p2p, dev, &status) < 0)
689a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt			goto fail;
6908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
6918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		dev->go_state = go ? LOCAL_GO : REMOTE_GO;
6924b06059785b935dd1f4f09314e4e12c417d2c6a4Dmitry Shmidt		dev->oper_freq = p2p_channel_to_freq(msg.operating_channel[3],
6938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt						     msg.operating_channel[4]);
694b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt		p2p_dbg(p2p, "Peer operating channel preference: %d MHz",
695b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt			dev->oper_freq);
6968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
6978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		if (msg.config_timeout) {
6988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			dev->go_timeout = msg.config_timeout[0];
6998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			dev->client_timeout = msg.config_timeout[1];
7008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		}
7018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
702b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt		p2p_dbg(p2p, "GO Negotiation with " MACSTR, MAC2STR(sa));
7038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		if (p2p->state != P2P_IDLE)
7048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			p2p_stop_find_for_freq(p2p, rx_freq);
7058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		p2p_set_state(p2p, P2P_GO_NEG);
7068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		p2p_clear_timeout(p2p);
7078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		dev->dialog_token = msg.dialog_token;
7088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		os_memcpy(dev->intended_addr, msg.intended_addr, ETH_ALEN);
7098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		p2p->go_neg_peer = dev;
7108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		status = P2P_SC_SUCCESS;
7118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
7128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
7138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtfail:
7148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (dev)
7158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		dev->status = status;
7168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	resp = p2p_build_go_neg_resp(p2p, dev, msg.dialog_token, status,
7178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt				     !tie_breaker);
7188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	p2p_parse_free(&msg);
7198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (resp == NULL)
7208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return;
721b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt	p2p_dbg(p2p, "Sending GO Negotiation Response");
7228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (rx_freq > 0)
7238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		freq = rx_freq;
7248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	else
7254b06059785b935dd1f4f09314e4e12c417d2c6a4Dmitry Shmidt		freq = p2p_channel_to_freq(p2p->cfg->reg_class,
7268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt					   p2p->cfg->channel);
7278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (freq < 0) {
728b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt		p2p_dbg(p2p, "Unknown regulatory class/channel");
7298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		wpabuf_free(resp);
7308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return;
7318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
7328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (status == P2P_SC_SUCCESS) {
7338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		p2p->pending_action_state = P2P_PENDING_GO_NEG_RESPONSE;
7348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		dev->flags |= P2P_DEV_WAIT_GO_NEG_CONFIRM;
73504949598a23f501be6eec21697465fd46a28840aDmitry Shmidt		if (os_memcmp(sa, p2p->cfg->dev_addr, ETH_ALEN) < 0) {
73604949598a23f501be6eec21697465fd46a28840aDmitry Shmidt			/*
73704949598a23f501be6eec21697465fd46a28840aDmitry Shmidt			 * Peer has smaller address, so the GO Negotiation
73804949598a23f501be6eec21697465fd46a28840aDmitry Shmidt			 * Response from us is expected to complete
73904949598a23f501be6eec21697465fd46a28840aDmitry Shmidt			 * negotiation. Ignore a GO Negotiation Response from
74004949598a23f501be6eec21697465fd46a28840aDmitry Shmidt			 * the peer if it happens to be received after this
74104949598a23f501be6eec21697465fd46a28840aDmitry Shmidt			 * point due to a race condition in GO Negotiation
74204949598a23f501be6eec21697465fd46a28840aDmitry Shmidt			 * Request transmission and processing.
74304949598a23f501be6eec21697465fd46a28840aDmitry Shmidt			 */
74404949598a23f501be6eec21697465fd46a28840aDmitry Shmidt			dev->flags &= ~P2P_DEV_WAIT_GO_NEG_RESPONSE;
74504949598a23f501be6eec21697465fd46a28840aDmitry Shmidt		}
7468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	} else
7478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		p2p->pending_action_state =
7488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			P2P_PENDING_GO_NEG_RESPONSE_FAILURE;
7498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (p2p_send_action(p2p, freq, sa, p2p->cfg->dev_addr,
7508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			    p2p->cfg->dev_addr,
7518c65289885e84727226d81b3d32856f79c31ee5fDmitry Shmidt			    wpabuf_head(resp), wpabuf_len(resp), 500) < 0) {
752b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt		p2p_dbg(p2p, "Failed to send Action frame");
7538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
7548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
7558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	wpabuf_free(resp);
7568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt}
7578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
7588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
7598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic struct wpabuf * p2p_build_go_neg_conf(struct p2p_data *p2p,
7608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt					     struct p2p_device *peer,
7618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt					     u8 dialog_token, u8 status,
7628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt					     const u8 *resp_chan, int go)
7638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{
7648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	struct wpabuf *buf;
7658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	u8 *len;
7668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	struct p2p_channels res;
7678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	u8 group_capab;
76861d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt	size_t extra = 0;
7698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
770b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt	p2p_dbg(p2p, "Building GO Negotiation Confirm");
77161d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt
77261d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt#ifdef CONFIG_WIFI_DISPLAY
77361d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt	if (p2p->wfd_ie_go_neg)
77461d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt		extra = wpabuf_len(p2p->wfd_ie_go_neg);
77561d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt#endif /* CONFIG_WIFI_DISPLAY */
77661d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt
77761d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt	buf = wpabuf_alloc(1000 + extra);
7788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (buf == NULL)
7798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return NULL;
7808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
7818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	p2p_buf_add_public_action_hdr(buf, P2P_GO_NEG_CONF, dialog_token);
7828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
7838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	len = p2p_buf_add_ie_hdr(buf);
7848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	p2p_buf_add_status(buf, status);
7858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	group_capab = 0;
7868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (peer->go_state == LOCAL_GO) {
7871f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt		if (peer->flags & P2P_DEV_PREFER_PERSISTENT_GROUP) {
7888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			group_capab |= P2P_GROUP_CAPAB_PERSISTENT_GROUP;
7891f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt			if (peer->flags & P2P_DEV_PREFER_PERSISTENT_RECONN)
7901f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt				group_capab |=
7911f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt					P2P_GROUP_CAPAB_PERSISTENT_RECONN;
7921f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt		}
7938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		if (p2p->cross_connect)
7948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			group_capab |= P2P_GROUP_CAPAB_CROSS_CONN;
7958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		if (p2p->cfg->p2p_intra_bss)
7968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			group_capab |= P2P_GROUP_CAPAB_INTRA_BSS_DIST;
7978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
79804949598a23f501be6eec21697465fd46a28840aDmitry Shmidt	p2p_buf_add_capability(buf, p2p->dev_capab &
79904949598a23f501be6eec21697465fd46a28840aDmitry Shmidt			       ~P2P_DEV_CAPAB_CLIENT_DISCOVERABILITY,
80004949598a23f501be6eec21697465fd46a28840aDmitry Shmidt			       group_capab);
8018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (go || resp_chan == NULL)
8028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		p2p_buf_add_operating_channel(buf, p2p->cfg->country,
8038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt					      p2p->op_reg_class,
8048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt					      p2p->op_channel);
8058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	else
8068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		p2p_buf_add_operating_channel(buf, (const char *) resp_chan,
8078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt					      resp_chan[3], resp_chan[4]);
8088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	p2p_channels_intersect(&p2p->channels, &peer->channels, &res);
8098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	p2p_buf_add_channel_list(buf, p2p->cfg->country, &res);
8108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (go) {
8118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		p2p_buf_add_group_id(buf, p2p->cfg->dev_addr, p2p->ssid,
8128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt				     p2p->ssid_len);
8138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
8148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	p2p_buf_update_ie_hdr(buf, len);
8158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
81661d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt#ifdef CONFIG_WIFI_DISPLAY
81761d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt	if (p2p->wfd_ie_go_neg)
81861d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt		wpabuf_put_buf(buf, p2p->wfd_ie_go_neg);
81961d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt#endif /* CONFIG_WIFI_DISPLAY */
82061d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt
8218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	return buf;
8228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt}
8238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
8248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
8258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtvoid p2p_process_go_neg_resp(struct p2p_data *p2p, const u8 *sa,
8268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			     const u8 *data, size_t len, int rx_freq)
8278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{
8288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	struct p2p_device *dev;
8298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	struct wpabuf *conf;
8308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	int go = -1;
8318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	struct p2p_message msg;
8328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	u8 status = P2P_SC_SUCCESS;
8338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	int freq;
8348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
835b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt	p2p_dbg(p2p, "Received GO Negotiation Response from " MACSTR
8368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		" (freq=%d)", MAC2STR(sa), rx_freq);
8378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	dev = p2p_get_device(p2p, sa);
8388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (dev == NULL || dev->wps_method == WPS_NOT_READY ||
8398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	    dev != p2p->go_neg_peer) {
840b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt		p2p_dbg(p2p, "Not ready for GO negotiation with " MACSTR,
8418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			MAC2STR(sa));
8428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return;
8438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
8448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
8458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (p2p_parse(data, len, &msg))
8468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return;
8478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
8488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (!(dev->flags & P2P_DEV_WAIT_GO_NEG_RESPONSE)) {
849b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt		p2p_dbg(p2p, "Was not expecting GO Negotiation Response - ignore");
8508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		p2p_parse_free(&msg);
8518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return;
8528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
8538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	dev->flags &= ~P2P_DEV_WAIT_GO_NEG_RESPONSE;
8548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
8558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (msg.dialog_token != dev->dialog_token) {
856b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt		p2p_dbg(p2p, "Unexpected Dialog Token %u (expected %u)",
8578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			msg.dialog_token, dev->dialog_token);
8588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		p2p_parse_free(&msg);
8598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return;
8608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
8618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
8628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (!msg.status) {
863b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt		p2p_dbg(p2p, "No Status attribute received");
8648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		status = P2P_SC_FAIL_INVALID_PARAMS;
8658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		goto fail;
8668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
8678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (*msg.status) {
868b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt		p2p_dbg(p2p, "GO Negotiation rejected: status %d", *msg.status);
8698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		dev->go_neg_req_sent = 0;
8708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		if (*msg.status == P2P_SC_FAIL_INFO_CURRENTLY_UNAVAILABLE) {
871b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt			p2p_dbg(p2p, "Wait for the peer to become ready for GO Negotiation");
8728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			dev->flags |= P2P_DEV_NOT_YET_READY;
8738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			dev->wait_count = 0;
8748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			p2p_set_state(p2p, P2P_WAIT_PEER_IDLE);
8758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			p2p_set_timeout(p2p, 0, 0);
8768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		} else {
877b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt			p2p_dbg(p2p, "Stop GO Negotiation attempt");
8788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			p2p_go_neg_failed(p2p, dev, *msg.status);
8798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		}
8808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		p2p->cfg->send_action_done(p2p->cfg->cb_ctx);
8818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		p2p_parse_free(&msg);
8828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return;
8838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
8848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
8858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (!msg.capability) {
886b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt		p2p_dbg(p2p, "Mandatory Capability attribute missing from GO Negotiation Response");
8878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#ifdef CONFIG_P2P_STRICT
8888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		status = P2P_SC_FAIL_INVALID_PARAMS;
8898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		goto fail;
8908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#endif /* CONFIG_P2P_STRICT */
8918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
8928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
8938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (!msg.p2p_device_info) {
894b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt		p2p_dbg(p2p, "Mandatory P2P Device Info attribute missing from GO Negotiation Response");
8958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#ifdef CONFIG_P2P_STRICT
8968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		status = P2P_SC_FAIL_INVALID_PARAMS;
8978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		goto fail;
8988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#endif /* CONFIG_P2P_STRICT */
8998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
9008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
9018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (!msg.intended_addr) {
902b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt		p2p_dbg(p2p, "No Intended P2P Interface Address attribute received");
9038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		status = P2P_SC_FAIL_INVALID_PARAMS;
9048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		goto fail;
9058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
9068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
9078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (!msg.go_intent) {
908b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt		p2p_dbg(p2p, "No GO Intent attribute received");
9098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		status = P2P_SC_FAIL_INVALID_PARAMS;
9108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		goto fail;
9118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
9128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if ((*msg.go_intent >> 1) > P2P_MAX_GO_INTENT) {
913b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt		p2p_dbg(p2p, "Invalid GO Intent value (%u) received",
9148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			*msg.go_intent >> 1);
9158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		status = P2P_SC_FAIL_INVALID_PARAMS;
9168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		goto fail;
9178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
9188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
9198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	go = p2p_go_det(p2p->go_intent, *msg.go_intent);
9208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (go < 0) {
921b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt		p2p_dbg(p2p, "Incompatible GO Intent");
9228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		status = P2P_SC_FAIL_INCOMPATIBLE_PARAMS;
9238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		goto fail;
9248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
9258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
9268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (!go && msg.group_id) {
9278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		/* Store SSID for Provisioning step */
9288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		p2p->ssid_len = msg.group_id_len - ETH_ALEN;
9298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		os_memcpy(p2p->ssid, msg.group_id + ETH_ALEN, p2p->ssid_len);
9308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	} else if (!go) {
931b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt		p2p_dbg(p2p, "Mandatory P2P Group ID attribute missing from GO Negotiation Response");
9328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		p2p->ssid_len = 0;
9338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		status = P2P_SC_FAIL_INVALID_PARAMS;
9348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		goto fail;
9358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
9368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
9378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (!msg.config_timeout) {
938b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt		p2p_dbg(p2p, "Mandatory Configuration Timeout attribute missing from GO Negotiation Response");
9398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#ifdef CONFIG_P2P_STRICT
9408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		status = P2P_SC_FAIL_INVALID_PARAMS;
9418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		goto fail;
9428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#endif /* CONFIG_P2P_STRICT */
9438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	} else {
9448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		dev->go_timeout = msg.config_timeout[0];
9458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		dev->client_timeout = msg.config_timeout[1];
9468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
9478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
9488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (!msg.operating_channel && !go) {
9498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		/*
9508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		 * Note: P2P Client may omit Operating Channel attribute to
9518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		 * indicate it does not have a preference.
9528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		 */
953b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt		p2p_dbg(p2p, "No Operating Channel attribute received");
9548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		status = P2P_SC_FAIL_INVALID_PARAMS;
9558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		goto fail;
9568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
9578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (!msg.channel_list) {
958b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt		p2p_dbg(p2p, "No Channel List attribute received");
9598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		status = P2P_SC_FAIL_INVALID_PARAMS;
9608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		goto fail;
9618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
9628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
9638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (p2p_peer_channels(p2p, dev, msg.channel_list,
9648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			      msg.channel_list_len) < 0) {
965b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt		p2p_dbg(p2p, "No common channels found");
9668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		status = P2P_SC_FAIL_NO_COMMON_CHANNELS;
9678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		goto fail;
9688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
9698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
9708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (msg.operating_channel) {
9714b06059785b935dd1f4f09314e4e12c417d2c6a4Dmitry Shmidt		dev->oper_freq = p2p_channel_to_freq(msg.operating_channel[3],
9728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt						     msg.operating_channel[4]);
973b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt		p2p_dbg(p2p, "Peer operating channel preference: %d MHz",
974b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt			dev->oper_freq);
9758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	} else
9768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		dev->oper_freq = 0;
9778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
9788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	switch (msg.dev_password_id) {
9798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	case DEV_PW_REGISTRAR_SPECIFIED:
980b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt		p2p_dbg(p2p, "PIN from peer Display");
9818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		if (dev->wps_method != WPS_PIN_KEYPAD) {
982b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt			p2p_dbg(p2p, "We have wps_method=%s -> incompatible",
9838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt				p2p_wps_method_str(dev->wps_method));
9848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			status = P2P_SC_FAIL_INCOMPATIBLE_PROV_METHOD;
9858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			goto fail;
9868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		}
9878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		break;
9888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	case DEV_PW_USER_SPECIFIED:
989b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt		p2p_dbg(p2p, "Peer entered PIN on Keypad");
9901f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt		if (dev->wps_method != WPS_PIN_DISPLAY) {
991b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt			p2p_dbg(p2p, "We have wps_method=%s -> incompatible",
9928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt				p2p_wps_method_str(dev->wps_method));
9938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			status = P2P_SC_FAIL_INCOMPATIBLE_PROV_METHOD;
9948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			goto fail;
9958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		}
9968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		break;
9978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	case DEV_PW_PUSHBUTTON:
998b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt		p2p_dbg(p2p, "Peer using pushbutton");
9998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		if (dev->wps_method != WPS_PBC) {
1000b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt			p2p_dbg(p2p, "We have wps_method=%s -> incompatible",
10018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt				p2p_wps_method_str(dev->wps_method));
10028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			status = P2P_SC_FAIL_INCOMPATIBLE_PROV_METHOD;
10038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			goto fail;
10048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		}
10058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		break;
10068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	default:
1007b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt		p2p_dbg(p2p, "Unsupported Device Password ID %d",
10088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			msg.dev_password_id);
10098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		status = P2P_SC_FAIL_INCOMPATIBLE_PROV_METHOD;
10108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		goto fail;
10118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
10128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
1013a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt	if (go && p2p_go_select_channel(p2p, dev, &status) < 0)
1014a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt		goto fail;
10158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
10168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	p2p_set_state(p2p, P2P_GO_NEG);
10178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	p2p_clear_timeout(p2p);
10188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
1019b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt	p2p_dbg(p2p, "GO Negotiation with " MACSTR, MAC2STR(sa));
10208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	os_memcpy(dev->intended_addr, msg.intended_addr, ETH_ALEN);
10218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
10228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtfail:
10238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	conf = p2p_build_go_neg_conf(p2p, dev, msg.dialog_token, status,
10248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt				     msg.operating_channel, go);
10258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	p2p_parse_free(&msg);
10268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (conf == NULL)
10278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return;
1028b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt	p2p_dbg(p2p, "Sending GO Negotiation Confirm");
10298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (status == P2P_SC_SUCCESS) {
10308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		p2p->pending_action_state = P2P_PENDING_GO_NEG_CONFIRM;
10318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		dev->go_state = go ? LOCAL_GO : REMOTE_GO;
10328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	} else
10338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		p2p->pending_action_state = P2P_NO_PENDING_ACTION;
10348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (rx_freq > 0)
10358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		freq = rx_freq;
10368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	else
10378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		freq = dev->listen_freq;
10388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (p2p_send_action(p2p, freq, sa, p2p->cfg->dev_addr, sa,
103904949598a23f501be6eec21697465fd46a28840aDmitry Shmidt			    wpabuf_head(conf), wpabuf_len(conf), 0) < 0) {
1040b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt		p2p_dbg(p2p, "Failed to send Action frame");
10418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		p2p_go_neg_failed(p2p, dev, -1);
10428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
10438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	wpabuf_free(conf);
10449cdf1b905fae57dea42506a1af67f6ece544b261Dmitry Shmidt	if (status != P2P_SC_SUCCESS) {
1045b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt		p2p_dbg(p2p, "GO Negotiation failed");
10469cdf1b905fae57dea42506a1af67f6ece544b261Dmitry Shmidt		p2p_go_neg_failed(p2p, dev, status);
10479cdf1b905fae57dea42506a1af67f6ece544b261Dmitry Shmidt	}
10488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt}
10498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
10508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
10518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtvoid p2p_process_go_neg_conf(struct p2p_data *p2p, const u8 *sa,
10528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			     const u8 *data, size_t len)
10538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{
10548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	struct p2p_device *dev;
10558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	struct p2p_message msg;
10568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
1057b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt	p2p_dbg(p2p, "Received GO Negotiation Confirm from " MACSTR,
10588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		MAC2STR(sa));
10598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	dev = p2p_get_device(p2p, sa);
10608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (dev == NULL || dev->wps_method == WPS_NOT_READY ||
10618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	    dev != p2p->go_neg_peer) {
1062b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt		p2p_dbg(p2p, "Not ready for GO negotiation with " MACSTR,
10638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			MAC2STR(sa));
10648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return;
10658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
10668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
10678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (p2p->pending_action_state == P2P_PENDING_GO_NEG_RESPONSE) {
1068b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt		p2p_dbg(p2p, "Stopped waiting for TX status on GO Negotiation Response since we already received Confirmation");
10698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		p2p->pending_action_state = P2P_NO_PENDING_ACTION;
10708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
10718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
10728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (p2p_parse(data, len, &msg))
10738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return;
10748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
10758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (!(dev->flags & P2P_DEV_WAIT_GO_NEG_CONFIRM)) {
1076b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt		p2p_dbg(p2p, "Was not expecting GO Negotiation Confirm - ignore");
10778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return;
10788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
10798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	dev->flags &= ~P2P_DEV_WAIT_GO_NEG_CONFIRM;
10808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
10818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (msg.dialog_token != dev->dialog_token) {
1082b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt		p2p_dbg(p2p, "Unexpected Dialog Token %u (expected %u)",
10838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			msg.dialog_token, dev->dialog_token);
10848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		p2p_parse_free(&msg);
10858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return;
10868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
10878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
10888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (!msg.status) {
1089b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt		p2p_dbg(p2p, "No Status attribute received");
10908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		p2p_parse_free(&msg);
10918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return;
10928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
10938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (*msg.status) {
1094b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt		p2p_dbg(p2p, "GO Negotiation rejected: status %d", *msg.status);
10959cdf1b905fae57dea42506a1af67f6ece544b261Dmitry Shmidt		p2p_go_neg_failed(p2p, dev, *msg.status);
10968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		p2p_parse_free(&msg);
10978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return;
10988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
10998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
11008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (dev->go_state == REMOTE_GO && msg.group_id) {
11018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		/* Store SSID for Provisioning step */
11028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		p2p->ssid_len = msg.group_id_len - ETH_ALEN;
11038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		os_memcpy(p2p->ssid, msg.group_id + ETH_ALEN, p2p->ssid_len);
11048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	} else if (dev->go_state == REMOTE_GO) {
1105b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt		p2p_dbg(p2p, "Mandatory P2P Group ID attribute missing from GO Negotiation Confirmation");
11068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		p2p->ssid_len = 0;
11079cdf1b905fae57dea42506a1af67f6ece544b261Dmitry Shmidt		p2p_go_neg_failed(p2p, dev, P2P_SC_FAIL_INVALID_PARAMS);
11088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		p2p_parse_free(&msg);
11098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return;
11108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
11118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
11128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (!msg.operating_channel) {
1113b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt		p2p_dbg(p2p, "Mandatory Operating Channel attribute missing from GO Negotiation Confirmation");
11148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#ifdef CONFIG_P2P_STRICT
11158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		p2p_parse_free(&msg);
11168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return;
11178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#endif /* CONFIG_P2P_STRICT */
1118b7b4d0ec07161a6d76c40ba7ef1306e82fbb7e15Dmitry Shmidt	} else if (dev->go_state == REMOTE_GO) {
1119b7b4d0ec07161a6d76c40ba7ef1306e82fbb7e15Dmitry Shmidt		int oper_freq = p2p_channel_to_freq(msg.operating_channel[3],
1120b7b4d0ec07161a6d76c40ba7ef1306e82fbb7e15Dmitry Shmidt						    msg.operating_channel[4]);
1121b7b4d0ec07161a6d76c40ba7ef1306e82fbb7e15Dmitry Shmidt		if (oper_freq != dev->oper_freq) {
1122b7b4d0ec07161a6d76c40ba7ef1306e82fbb7e15Dmitry Shmidt			p2p_dbg(p2p, "Updated peer (GO) operating channel preference from %d MHz to %d MHz",
1123b7b4d0ec07161a6d76c40ba7ef1306e82fbb7e15Dmitry Shmidt				dev->oper_freq, oper_freq);
1124b7b4d0ec07161a6d76c40ba7ef1306e82fbb7e15Dmitry Shmidt			dev->oper_freq = oper_freq;
1125b7b4d0ec07161a6d76c40ba7ef1306e82fbb7e15Dmitry Shmidt		}
11268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
11278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
1128f06196652a3e12af00503f4a548c56d4e60f7246Irfan Sheriff#ifdef ANDROID_P2P
1129af84a575044f6556994fcc124a955fc0ac0a6736Irfan Sheriff	if (msg.operating_channel) {
11304b06059785b935dd1f4f09314e4e12c417d2c6a4Dmitry Shmidt		dev->oper_freq = p2p_channel_to_freq(msg.operating_channel[3],
1131af84a575044f6556994fcc124a955fc0ac0a6736Irfan Sheriff						     msg.operating_channel[4]);
1132b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt		p2p_dbg(p2p, "P2P: Peer operating channel preference: %d MHz",
1133b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt			dev->oper_freq);
1134af84a575044f6556994fcc124a955fc0ac0a6736Irfan Sheriff	} else
1135af84a575044f6556994fcc124a955fc0ac0a6736Irfan Sheriff		dev->oper_freq = 0;
1136f06196652a3e12af00503f4a548c56d4e60f7246Irfan Sheriff#endif
1137af84a575044f6556994fcc124a955fc0ac0a6736Irfan Sheriff
11388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (!msg.channel_list) {
1139b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt		p2p_dbg(p2p, "Mandatory Operating Channel attribute missing from GO Negotiation Confirmation");
11408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#ifdef CONFIG_P2P_STRICT
11418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		p2p_parse_free(&msg);
11428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return;
11438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#endif /* CONFIG_P2P_STRICT */
11448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
11458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
11468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	p2p_parse_free(&msg);
11478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
11488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (dev->go_state == UNKNOWN_GO) {
11498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		/*
11508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		 * This should not happen since GO negotiation has already
11518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		 * been completed.
11528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		 */
1153b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt		p2p_dbg(p2p, "Unexpected GO Neg state - do not know which end becomes GO");
11548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return;
11558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
11568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
11572c5b17df4c29abdf11a85216c2f6272af796c576Jouni Malinen	/*
11582c5b17df4c29abdf11a85216c2f6272af796c576Jouni Malinen	 * The peer could have missed our ctrl::ack frame for GO Negotiation
11592c5b17df4c29abdf11a85216c2f6272af796c576Jouni Malinen	 * Confirm and continue retransmitting the frame. To reduce the
11602c5b17df4c29abdf11a85216c2f6272af796c576Jouni Malinen	 * likelihood of the peer not getting successful TX status for the
11612c5b17df4c29abdf11a85216c2f6272af796c576Jouni Malinen	 * GO Negotiation Confirm frame, wait a short time here before starting
11622c5b17df4c29abdf11a85216c2f6272af796c576Jouni Malinen	 * the group so that we will remain on the current channel to
11632c5b17df4c29abdf11a85216c2f6272af796c576Jouni Malinen	 * acknowledge any possible retransmission from the peer.
11642c5b17df4c29abdf11a85216c2f6272af796c576Jouni Malinen	 */
1165b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt	p2p_dbg(p2p, "20 ms wait on current channel before starting group");
11662c5b17df4c29abdf11a85216c2f6272af796c576Jouni Malinen	os_sleep(0, 20000);
11672c5b17df4c29abdf11a85216c2f6272af796c576Jouni Malinen
11688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	p2p_go_complete(p2p, dev);
11698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt}
1170