xref: /freebsd/contrib/wpa/src/p2p/p2p_go_neg.c (revision f05cddf940dbfc5b657f5e9beb9de2c31e509e5b)
1*f05cddf9SRui Paulo /*
2*f05cddf9SRui Paulo  * Wi-Fi Direct - P2P Group Owner Negotiation
3*f05cddf9SRui Paulo  * Copyright (c) 2009-2010, Atheros Communications
4*f05cddf9SRui Paulo  *
5*f05cddf9SRui Paulo  * This software may be distributed under the terms of the BSD license.
6*f05cddf9SRui Paulo  * See README for more details.
7*f05cddf9SRui Paulo  */
8*f05cddf9SRui Paulo 
9*f05cddf9SRui Paulo #include "includes.h"
10*f05cddf9SRui Paulo 
11*f05cddf9SRui Paulo #include "common.h"
12*f05cddf9SRui Paulo #include "common/ieee802_11_defs.h"
13*f05cddf9SRui Paulo #include "wps/wps_defs.h"
14*f05cddf9SRui Paulo #include "p2p_i.h"
15*f05cddf9SRui Paulo #include "p2p.h"
16*f05cddf9SRui Paulo 
17*f05cddf9SRui Paulo 
18*f05cddf9SRui Paulo static int p2p_go_det(u8 own_intent, u8 peer_value)
19*f05cddf9SRui Paulo {
20*f05cddf9SRui Paulo 	u8 peer_intent = peer_value >> 1;
21*f05cddf9SRui Paulo 	if (own_intent == peer_intent) {
22*f05cddf9SRui Paulo 		if (own_intent == P2P_MAX_GO_INTENT)
23*f05cddf9SRui Paulo 			return -1; /* both devices want to become GO */
24*f05cddf9SRui Paulo 
25*f05cddf9SRui Paulo 		/* Use tie breaker bit to determine GO */
26*f05cddf9SRui Paulo 		return (peer_value & 0x01) ? 0 : 1;
27*f05cddf9SRui Paulo 	}
28*f05cddf9SRui Paulo 
29*f05cddf9SRui Paulo 	return own_intent > peer_intent;
30*f05cddf9SRui Paulo }
31*f05cddf9SRui Paulo 
32*f05cddf9SRui Paulo 
33*f05cddf9SRui Paulo int p2p_peer_channels_check(struct p2p_data *p2p, struct p2p_channels *own,
34*f05cddf9SRui Paulo 			    struct p2p_device *dev,
35*f05cddf9SRui Paulo 			    const u8 *channel_list, size_t channel_list_len)
36*f05cddf9SRui Paulo {
37*f05cddf9SRui Paulo 	const u8 *pos, *end;
38*f05cddf9SRui Paulo 	struct p2p_channels *ch;
39*f05cddf9SRui Paulo 	size_t channels;
40*f05cddf9SRui Paulo 	struct p2p_channels intersection;
41*f05cddf9SRui Paulo 
42*f05cddf9SRui Paulo 	ch = &dev->channels;
43*f05cddf9SRui Paulo 	os_memset(ch, 0, sizeof(*ch));
44*f05cddf9SRui Paulo 	pos = channel_list;
45*f05cddf9SRui Paulo 	end = channel_list + channel_list_len;
46*f05cddf9SRui Paulo 
47*f05cddf9SRui Paulo 	if (end - pos < 3)
48*f05cddf9SRui Paulo 		return -1;
49*f05cddf9SRui Paulo 	os_memcpy(dev->country, pos, 3);
50*f05cddf9SRui Paulo 	wpa_hexdump_ascii(MSG_DEBUG, "P2P: Peer country", pos, 3);
51*f05cddf9SRui Paulo 	if (pos[2] != 0x04 && os_memcmp(pos, p2p->cfg->country, 2) != 0) {
52*f05cddf9SRui Paulo 		wpa_msg(p2p->cfg->msg_ctx, MSG_INFO,
53*f05cddf9SRui Paulo 			"P2P: Mismatching country (ours=%c%c peer's=%c%c)",
54*f05cddf9SRui Paulo 			p2p->cfg->country[0], p2p->cfg->country[1],
55*f05cddf9SRui Paulo 			pos[0], pos[1]);
56*f05cddf9SRui Paulo 		return -1;
57*f05cddf9SRui Paulo 	}
58*f05cddf9SRui Paulo 	pos += 3;
59*f05cddf9SRui Paulo 
60*f05cddf9SRui Paulo 	while (pos + 2 < end) {
61*f05cddf9SRui Paulo 		struct p2p_reg_class *cl = &ch->reg_class[ch->reg_classes];
62*f05cddf9SRui Paulo 		cl->reg_class = *pos++;
63*f05cddf9SRui Paulo 		if (pos + 1 + pos[0] > end) {
64*f05cddf9SRui Paulo 			wpa_msg(p2p->cfg->msg_ctx, MSG_INFO,
65*f05cddf9SRui Paulo 				"P2P: Invalid peer Channel List");
66*f05cddf9SRui Paulo 			return -1;
67*f05cddf9SRui Paulo 		}
68*f05cddf9SRui Paulo 		channels = *pos++;
69*f05cddf9SRui Paulo 		cl->channels = channels > P2P_MAX_REG_CLASS_CHANNELS ?
70*f05cddf9SRui Paulo 			P2P_MAX_REG_CLASS_CHANNELS : channels;
71*f05cddf9SRui Paulo 		os_memcpy(cl->channel, pos, cl->channels);
72*f05cddf9SRui Paulo 		pos += channels;
73*f05cddf9SRui Paulo 		ch->reg_classes++;
74*f05cddf9SRui Paulo 		if (ch->reg_classes == P2P_MAX_REG_CLASSES)
75*f05cddf9SRui Paulo 			break;
76*f05cddf9SRui Paulo 	}
77*f05cddf9SRui Paulo 
78*f05cddf9SRui Paulo 	p2p_channels_intersect(own, &dev->channels, &intersection);
79*f05cddf9SRui Paulo 	wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG, "P2P: Own reg_classes %d "
80*f05cddf9SRui Paulo 		"peer reg_classes %d intersection reg_classes %d",
81*f05cddf9SRui Paulo 		(int) own->reg_classes,
82*f05cddf9SRui Paulo 		(int) dev->channels.reg_classes,
83*f05cddf9SRui Paulo 		(int) intersection.reg_classes);
84*f05cddf9SRui Paulo 	if (intersection.reg_classes == 0) {
85*f05cddf9SRui Paulo 		wpa_msg(p2p->cfg->msg_ctx, MSG_INFO,
86*f05cddf9SRui Paulo 			"P2P: No common channels found");
87*f05cddf9SRui Paulo 		return -1;
88*f05cddf9SRui Paulo 	}
89*f05cddf9SRui Paulo 	return 0;
90*f05cddf9SRui Paulo }
91*f05cddf9SRui Paulo 
92*f05cddf9SRui Paulo 
93*f05cddf9SRui Paulo static int p2p_peer_channels(struct p2p_data *p2p, struct p2p_device *dev,
94*f05cddf9SRui Paulo 			     const u8 *channel_list, size_t channel_list_len)
95*f05cddf9SRui Paulo {
96*f05cddf9SRui Paulo 	return p2p_peer_channels_check(p2p, &p2p->channels, dev,
97*f05cddf9SRui Paulo 				       channel_list, channel_list_len);
98*f05cddf9SRui Paulo }
99*f05cddf9SRui Paulo 
100*f05cddf9SRui Paulo 
101*f05cddf9SRui Paulo u16 p2p_wps_method_pw_id(enum p2p_wps_method wps_method)
102*f05cddf9SRui Paulo {
103*f05cddf9SRui Paulo 	switch (wps_method) {
104*f05cddf9SRui Paulo 	case WPS_PIN_DISPLAY:
105*f05cddf9SRui Paulo 		return DEV_PW_REGISTRAR_SPECIFIED;
106*f05cddf9SRui Paulo 	case WPS_PIN_KEYPAD:
107*f05cddf9SRui Paulo 		return DEV_PW_USER_SPECIFIED;
108*f05cddf9SRui Paulo 	case WPS_PBC:
109*f05cddf9SRui Paulo 		return DEV_PW_PUSHBUTTON;
110*f05cddf9SRui Paulo 	default:
111*f05cddf9SRui Paulo 		return DEV_PW_DEFAULT;
112*f05cddf9SRui Paulo 	}
113*f05cddf9SRui Paulo }
114*f05cddf9SRui Paulo 
115*f05cddf9SRui Paulo 
116*f05cddf9SRui Paulo static const char * p2p_wps_method_str(enum p2p_wps_method wps_method)
117*f05cddf9SRui Paulo {
118*f05cddf9SRui Paulo 	switch (wps_method) {
119*f05cddf9SRui Paulo 	case WPS_PIN_DISPLAY:
120*f05cddf9SRui Paulo 		return "Display";
121*f05cddf9SRui Paulo 	case WPS_PIN_KEYPAD:
122*f05cddf9SRui Paulo 		return "Keypad";
123*f05cddf9SRui Paulo 	case WPS_PBC:
124*f05cddf9SRui Paulo 		return "PBC";
125*f05cddf9SRui Paulo 	default:
126*f05cddf9SRui Paulo 		return "??";
127*f05cddf9SRui Paulo 	}
128*f05cddf9SRui Paulo }
129*f05cddf9SRui Paulo 
130*f05cddf9SRui Paulo 
131*f05cddf9SRui Paulo static struct wpabuf * p2p_build_go_neg_req(struct p2p_data *p2p,
132*f05cddf9SRui Paulo 					    struct p2p_device *peer)
133*f05cddf9SRui Paulo {
134*f05cddf9SRui Paulo 	struct wpabuf *buf;
135*f05cddf9SRui Paulo 	u8 *len;
136*f05cddf9SRui Paulo 	u8 group_capab;
137*f05cddf9SRui Paulo 	size_t extra = 0;
138*f05cddf9SRui Paulo 
139*f05cddf9SRui Paulo #ifdef CONFIG_WIFI_DISPLAY
140*f05cddf9SRui Paulo 	if (p2p->wfd_ie_go_neg)
141*f05cddf9SRui Paulo 		extra = wpabuf_len(p2p->wfd_ie_go_neg);
142*f05cddf9SRui Paulo #endif /* CONFIG_WIFI_DISPLAY */
143*f05cddf9SRui Paulo 
144*f05cddf9SRui Paulo 	buf = wpabuf_alloc(1000 + extra);
145*f05cddf9SRui Paulo 	if (buf == NULL)
146*f05cddf9SRui Paulo 		return NULL;
147*f05cddf9SRui Paulo 
148*f05cddf9SRui Paulo 	peer->dialog_token++;
149*f05cddf9SRui Paulo 	if (peer->dialog_token == 0)
150*f05cddf9SRui Paulo 		peer->dialog_token = 1;
151*f05cddf9SRui Paulo 	p2p_buf_add_public_action_hdr(buf, P2P_GO_NEG_REQ, peer->dialog_token);
152*f05cddf9SRui Paulo 
153*f05cddf9SRui Paulo 	len = p2p_buf_add_ie_hdr(buf);
154*f05cddf9SRui Paulo 	group_capab = 0;
155*f05cddf9SRui Paulo 	if (peer->flags & P2P_DEV_PREFER_PERSISTENT_GROUP) {
156*f05cddf9SRui Paulo 		group_capab |= P2P_GROUP_CAPAB_PERSISTENT_GROUP;
157*f05cddf9SRui Paulo 		if (peer->flags & P2P_DEV_PREFER_PERSISTENT_RECONN)
158*f05cddf9SRui Paulo 			group_capab |= P2P_GROUP_CAPAB_PERSISTENT_RECONN;
159*f05cddf9SRui Paulo 	}
160*f05cddf9SRui Paulo 	if (p2p->cross_connect)
161*f05cddf9SRui Paulo 		group_capab |= P2P_GROUP_CAPAB_CROSS_CONN;
162*f05cddf9SRui Paulo 	if (p2p->cfg->p2p_intra_bss)
163*f05cddf9SRui Paulo 		group_capab |= P2P_GROUP_CAPAB_INTRA_BSS_DIST;
164*f05cddf9SRui Paulo 	p2p_buf_add_capability(buf, p2p->dev_capab &
165*f05cddf9SRui Paulo 			       ~P2P_DEV_CAPAB_CLIENT_DISCOVERABILITY,
166*f05cddf9SRui Paulo 			       group_capab);
167*f05cddf9SRui Paulo 	p2p_buf_add_go_intent(buf, (p2p->go_intent << 1) |
168*f05cddf9SRui Paulo 			      p2p->next_tie_breaker);
169*f05cddf9SRui Paulo 	p2p->next_tie_breaker = !p2p->next_tie_breaker;
170*f05cddf9SRui Paulo 	p2p_buf_add_config_timeout(buf, p2p->go_timeout, p2p->client_timeout);
171*f05cddf9SRui Paulo 	p2p_buf_add_listen_channel(buf, p2p->cfg->country, p2p->cfg->reg_class,
172*f05cddf9SRui Paulo 				   p2p->cfg->channel);
173*f05cddf9SRui Paulo 	if (p2p->ext_listen_interval)
174*f05cddf9SRui Paulo 		p2p_buf_add_ext_listen_timing(buf, p2p->ext_listen_period,
175*f05cddf9SRui Paulo 					      p2p->ext_listen_interval);
176*f05cddf9SRui Paulo 	p2p_buf_add_intended_addr(buf, p2p->intended_addr);
177*f05cddf9SRui Paulo 	p2p_buf_add_channel_list(buf, p2p->cfg->country, &p2p->channels);
178*f05cddf9SRui Paulo 	p2p_buf_add_device_info(buf, p2p, peer);
179*f05cddf9SRui Paulo 	p2p_buf_add_operating_channel(buf, p2p->cfg->country,
180*f05cddf9SRui Paulo 				      p2p->op_reg_class, p2p->op_channel);
181*f05cddf9SRui Paulo 	p2p_buf_update_ie_hdr(buf, len);
182*f05cddf9SRui Paulo 
183*f05cddf9SRui Paulo 	/* WPS IE with Device Password ID attribute */
184*f05cddf9SRui Paulo 	p2p_build_wps_ie(p2p, buf, p2p_wps_method_pw_id(peer->wps_method), 0);
185*f05cddf9SRui Paulo 
186*f05cddf9SRui Paulo #ifdef CONFIG_WIFI_DISPLAY
187*f05cddf9SRui Paulo 	if (p2p->wfd_ie_go_neg)
188*f05cddf9SRui Paulo 		wpabuf_put_buf(buf, p2p->wfd_ie_go_neg);
189*f05cddf9SRui Paulo #endif /* CONFIG_WIFI_DISPLAY */
190*f05cddf9SRui Paulo 
191*f05cddf9SRui Paulo 	return buf;
192*f05cddf9SRui Paulo }
193*f05cddf9SRui Paulo 
194*f05cddf9SRui Paulo 
195*f05cddf9SRui Paulo int p2p_connect_send(struct p2p_data *p2p, struct p2p_device *dev)
196*f05cddf9SRui Paulo {
197*f05cddf9SRui Paulo 	struct wpabuf *req;
198*f05cddf9SRui Paulo 	int freq;
199*f05cddf9SRui Paulo 
200*f05cddf9SRui Paulo 	if (dev->flags & P2P_DEV_PD_BEFORE_GO_NEG) {
201*f05cddf9SRui Paulo 		u16 config_method;
202*f05cddf9SRui Paulo 		wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG,
203*f05cddf9SRui Paulo 			"P2P: Use PD-before-GO-Neg workaround for " MACSTR,
204*f05cddf9SRui Paulo 			MAC2STR(dev->info.p2p_device_addr));
205*f05cddf9SRui Paulo 		if (dev->wps_method == WPS_PIN_DISPLAY)
206*f05cddf9SRui Paulo 			config_method = WPS_CONFIG_KEYPAD;
207*f05cddf9SRui Paulo 		else if (dev->wps_method == WPS_PIN_KEYPAD)
208*f05cddf9SRui Paulo 			config_method = WPS_CONFIG_DISPLAY;
209*f05cddf9SRui Paulo 		else if (dev->wps_method == WPS_PBC)
210*f05cddf9SRui Paulo 			config_method = WPS_CONFIG_PUSHBUTTON;
211*f05cddf9SRui Paulo 		else
212*f05cddf9SRui Paulo 			return -1;
213*f05cddf9SRui Paulo 		return p2p_prov_disc_req(p2p, dev->info.p2p_device_addr,
214*f05cddf9SRui Paulo 					 config_method, 0, 0, 1);
215*f05cddf9SRui Paulo 	}
216*f05cddf9SRui Paulo 
217*f05cddf9SRui Paulo 	freq = dev->listen_freq > 0 ? dev->listen_freq : dev->oper_freq;
218*f05cddf9SRui Paulo 	if (freq <= 0) {
219*f05cddf9SRui Paulo 		wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG,
220*f05cddf9SRui Paulo 			"P2P: No Listen/Operating frequency known for the "
221*f05cddf9SRui Paulo 			"peer " MACSTR " to send GO Negotiation Request",
222*f05cddf9SRui Paulo 			MAC2STR(dev->info.p2p_device_addr));
223*f05cddf9SRui Paulo 		return -1;
224*f05cddf9SRui Paulo 	}
225*f05cddf9SRui Paulo 
226*f05cddf9SRui Paulo 	req = p2p_build_go_neg_req(p2p, dev);
227*f05cddf9SRui Paulo 	if (req == NULL)
228*f05cddf9SRui Paulo 		return -1;
229*f05cddf9SRui Paulo 	wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG,
230*f05cddf9SRui Paulo 		"P2P: Sending GO Negotiation Request");
231*f05cddf9SRui Paulo 	p2p_set_state(p2p, P2P_CONNECT);
232*f05cddf9SRui Paulo 	p2p->pending_action_state = P2P_PENDING_GO_NEG_REQUEST;
233*f05cddf9SRui Paulo 	p2p->go_neg_peer = dev;
234*f05cddf9SRui Paulo 	dev->flags |= P2P_DEV_WAIT_GO_NEG_RESPONSE;
235*f05cddf9SRui Paulo 	dev->connect_reqs++;
236*f05cddf9SRui Paulo 	if (p2p_send_action(p2p, freq, dev->info.p2p_device_addr,
237*f05cddf9SRui Paulo 			    p2p->cfg->dev_addr, dev->info.p2p_device_addr,
238*f05cddf9SRui Paulo 			    wpabuf_head(req), wpabuf_len(req), 200) < 0) {
239*f05cddf9SRui Paulo 		wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG,
240*f05cddf9SRui Paulo 			"P2P: Failed to send Action frame");
241*f05cddf9SRui Paulo 		/* Use P2P find to recover and retry */
242*f05cddf9SRui Paulo 		p2p_set_timeout(p2p, 0, 0);
243*f05cddf9SRui Paulo 	} else
244*f05cddf9SRui Paulo 		dev->go_neg_req_sent++;
245*f05cddf9SRui Paulo 
246*f05cddf9SRui Paulo 	wpabuf_free(req);
247*f05cddf9SRui Paulo 
248*f05cddf9SRui Paulo 	return 0;
249*f05cddf9SRui Paulo }
250*f05cddf9SRui Paulo 
251*f05cddf9SRui Paulo 
252*f05cddf9SRui Paulo static struct wpabuf * p2p_build_go_neg_resp(struct p2p_data *p2p,
253*f05cddf9SRui Paulo 					     struct p2p_device *peer,
254*f05cddf9SRui Paulo 					     u8 dialog_token, u8 status,
255*f05cddf9SRui Paulo 					     u8 tie_breaker)
256*f05cddf9SRui Paulo {
257*f05cddf9SRui Paulo 	struct wpabuf *buf;
258*f05cddf9SRui Paulo 	u8 *len;
259*f05cddf9SRui Paulo 	u8 group_capab;
260*f05cddf9SRui Paulo 	size_t extra = 0;
261*f05cddf9SRui Paulo 
262*f05cddf9SRui Paulo 	wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG,
263*f05cddf9SRui Paulo 		"P2P: Building GO Negotiation Response");
264*f05cddf9SRui Paulo 
265*f05cddf9SRui Paulo #ifdef CONFIG_WIFI_DISPLAY
266*f05cddf9SRui Paulo 	if (p2p->wfd_ie_go_neg)
267*f05cddf9SRui Paulo 		extra = wpabuf_len(p2p->wfd_ie_go_neg);
268*f05cddf9SRui Paulo #endif /* CONFIG_WIFI_DISPLAY */
269*f05cddf9SRui Paulo 
270*f05cddf9SRui Paulo 	buf = wpabuf_alloc(1000 + extra);
271*f05cddf9SRui Paulo 	if (buf == NULL)
272*f05cddf9SRui Paulo 		return NULL;
273*f05cddf9SRui Paulo 
274*f05cddf9SRui Paulo 	p2p_buf_add_public_action_hdr(buf, P2P_GO_NEG_RESP, dialog_token);
275*f05cddf9SRui Paulo 
276*f05cddf9SRui Paulo 	len = p2p_buf_add_ie_hdr(buf);
277*f05cddf9SRui Paulo 	p2p_buf_add_status(buf, status);
278*f05cddf9SRui Paulo 	group_capab = 0;
279*f05cddf9SRui Paulo 	if (peer && peer->go_state == LOCAL_GO) {
280*f05cddf9SRui Paulo 		if (peer->flags & P2P_DEV_PREFER_PERSISTENT_GROUP) {
281*f05cddf9SRui Paulo 			group_capab |= P2P_GROUP_CAPAB_PERSISTENT_GROUP;
282*f05cddf9SRui Paulo 			if (peer->flags & P2P_DEV_PREFER_PERSISTENT_RECONN)
283*f05cddf9SRui Paulo 				group_capab |=
284*f05cddf9SRui Paulo 					P2P_GROUP_CAPAB_PERSISTENT_RECONN;
285*f05cddf9SRui Paulo 		}
286*f05cddf9SRui Paulo 		if (p2p->cross_connect)
287*f05cddf9SRui Paulo 			group_capab |= P2P_GROUP_CAPAB_CROSS_CONN;
288*f05cddf9SRui Paulo 		if (p2p->cfg->p2p_intra_bss)
289*f05cddf9SRui Paulo 			group_capab |= P2P_GROUP_CAPAB_INTRA_BSS_DIST;
290*f05cddf9SRui Paulo 	}
291*f05cddf9SRui Paulo 	p2p_buf_add_capability(buf, p2p->dev_capab &
292*f05cddf9SRui Paulo 			       ~P2P_DEV_CAPAB_CLIENT_DISCOVERABILITY,
293*f05cddf9SRui Paulo 			       group_capab);
294*f05cddf9SRui Paulo 	p2p_buf_add_go_intent(buf, (p2p->go_intent << 1) | tie_breaker);
295*f05cddf9SRui Paulo 	p2p_buf_add_config_timeout(buf, p2p->go_timeout, p2p->client_timeout);
296*f05cddf9SRui Paulo 	if (peer && peer->go_state == REMOTE_GO) {
297*f05cddf9SRui Paulo 		wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG, "P2P: Omit Operating "
298*f05cddf9SRui Paulo 			"Channel attribute");
299*f05cddf9SRui Paulo 	} else {
300*f05cddf9SRui Paulo 		p2p_buf_add_operating_channel(buf, p2p->cfg->country,
301*f05cddf9SRui Paulo 					      p2p->op_reg_class,
302*f05cddf9SRui Paulo 					      p2p->op_channel);
303*f05cddf9SRui Paulo 	}
304*f05cddf9SRui Paulo 	p2p_buf_add_intended_addr(buf, p2p->intended_addr);
305*f05cddf9SRui Paulo 	if (status || peer == NULL) {
306*f05cddf9SRui Paulo 		p2p_buf_add_channel_list(buf, p2p->cfg->country,
307*f05cddf9SRui Paulo 					 &p2p->channels);
308*f05cddf9SRui Paulo 	} else if (peer->go_state == REMOTE_GO) {
309*f05cddf9SRui Paulo 		p2p_buf_add_channel_list(buf, p2p->cfg->country,
310*f05cddf9SRui Paulo 					 &p2p->channels);
311*f05cddf9SRui Paulo 	} else {
312*f05cddf9SRui Paulo 		struct p2p_channels res;
313*f05cddf9SRui Paulo 		p2p_channels_intersect(&p2p->channels, &peer->channels,
314*f05cddf9SRui Paulo 				       &res);
315*f05cddf9SRui Paulo 		p2p_buf_add_channel_list(buf, p2p->cfg->country, &res);
316*f05cddf9SRui Paulo 	}
317*f05cddf9SRui Paulo 	p2p_buf_add_device_info(buf, p2p, peer);
318*f05cddf9SRui Paulo 	if (peer && peer->go_state == LOCAL_GO) {
319*f05cddf9SRui Paulo 		p2p_buf_add_group_id(buf, p2p->cfg->dev_addr, p2p->ssid,
320*f05cddf9SRui Paulo 				     p2p->ssid_len);
321*f05cddf9SRui Paulo 	}
322*f05cddf9SRui Paulo 	p2p_buf_update_ie_hdr(buf, len);
323*f05cddf9SRui Paulo 
324*f05cddf9SRui Paulo 	/* WPS IE with Device Password ID attribute */
325*f05cddf9SRui Paulo 	p2p_build_wps_ie(p2p, buf,
326*f05cddf9SRui Paulo 			 p2p_wps_method_pw_id(peer ? peer->wps_method :
327*f05cddf9SRui Paulo 					      WPS_NOT_READY), 0);
328*f05cddf9SRui Paulo 
329*f05cddf9SRui Paulo #ifdef CONFIG_WIFI_DISPLAY
330*f05cddf9SRui Paulo 	if (p2p->wfd_ie_go_neg)
331*f05cddf9SRui Paulo 		wpabuf_put_buf(buf, p2p->wfd_ie_go_neg);
332*f05cddf9SRui Paulo #endif /* CONFIG_WIFI_DISPLAY */
333*f05cddf9SRui Paulo 
334*f05cddf9SRui Paulo 
335*f05cddf9SRui Paulo 	return buf;
336*f05cddf9SRui Paulo }
337*f05cddf9SRui Paulo 
338*f05cddf9SRui Paulo 
339*f05cddf9SRui Paulo /**
340*f05cddf9SRui Paulo  * p2p_reselect_channel - Re-select operating channel based on peer information
341*f05cddf9SRui Paulo  * @p2p: P2P module context from p2p_init()
342*f05cddf9SRui Paulo  * @intersection: Support channel list intersection from local and peer
343*f05cddf9SRui Paulo  *
344*f05cddf9SRui Paulo  * This function is used to re-select the best channel after having received
345*f05cddf9SRui Paulo  * information from the peer to allow supported channel lists to be intersected.
346*f05cddf9SRui Paulo  * This can be used to improve initial channel selection done in
347*f05cddf9SRui Paulo  * p2p_prepare_channel() prior to the start of GO Negotiation. In addition, this
348*f05cddf9SRui Paulo  * can be used for Invitation case.
349*f05cddf9SRui Paulo  */
350*f05cddf9SRui Paulo void p2p_reselect_channel(struct p2p_data *p2p,
351*f05cddf9SRui Paulo 			  struct p2p_channels *intersection)
352*f05cddf9SRui Paulo {
353*f05cddf9SRui Paulo 	struct p2p_reg_class *cl;
354*f05cddf9SRui Paulo 	int freq;
355*f05cddf9SRui Paulo 	u8 op_reg_class, op_channel;
356*f05cddf9SRui Paulo 	unsigned int i;
357*f05cddf9SRui Paulo 
358*f05cddf9SRui Paulo 	/* First, try to pick the best channel from another band */
359*f05cddf9SRui Paulo 	freq = p2p_channel_to_freq(p2p->cfg->country, p2p->op_reg_class,
360*f05cddf9SRui Paulo 				   p2p->op_channel);
361*f05cddf9SRui Paulo 	if (freq >= 2400 && freq < 2500 && p2p->best_freq_5 > 0 &&
362*f05cddf9SRui Paulo 	    p2p_freq_to_channel(p2p->cfg->country, p2p->best_freq_5,
363*f05cddf9SRui Paulo 				&op_reg_class, &op_channel) == 0 &&
364*f05cddf9SRui Paulo 	    p2p_channels_includes(intersection, op_reg_class, op_channel)) {
365*f05cddf9SRui Paulo 		wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG, "P2P: Pick best 5 GHz "
366*f05cddf9SRui Paulo 			"channel (reg_class %u channel %u) from intersection",
367*f05cddf9SRui Paulo 			op_reg_class, op_channel);
368*f05cddf9SRui Paulo 		p2p->op_reg_class = op_reg_class;
369*f05cddf9SRui Paulo 		p2p->op_channel = op_channel;
370*f05cddf9SRui Paulo 		return;
371*f05cddf9SRui Paulo 	}
372*f05cddf9SRui Paulo 
373*f05cddf9SRui Paulo 	if (freq >= 4900 && freq < 6000 && p2p->best_freq_24 > 0 &&
374*f05cddf9SRui Paulo 	    p2p_freq_to_channel(p2p->cfg->country, p2p->best_freq_24,
375*f05cddf9SRui Paulo 				&op_reg_class, &op_channel) == 0 &&
376*f05cddf9SRui Paulo 	    p2p_channels_includes(intersection, op_reg_class, op_channel)) {
377*f05cddf9SRui Paulo 		wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG, "P2P: Pick best 2.4 GHz "
378*f05cddf9SRui Paulo 			"channel (reg_class %u channel %u) from intersection",
379*f05cddf9SRui Paulo 			op_reg_class, op_channel);
380*f05cddf9SRui Paulo 		p2p->op_reg_class = op_reg_class;
381*f05cddf9SRui Paulo 		p2p->op_channel = op_channel;
382*f05cddf9SRui Paulo 		return;
383*f05cddf9SRui Paulo 	}
384*f05cddf9SRui Paulo 
385*f05cddf9SRui Paulo 	/* Select channel with highest preference if the peer supports it */
386*f05cddf9SRui Paulo 	for (i = 0; p2p->cfg->pref_chan && i < p2p->cfg->num_pref_chan; i++) {
387*f05cddf9SRui Paulo 		if (p2p_channels_includes(intersection,
388*f05cddf9SRui Paulo 					  p2p->cfg->pref_chan[i].op_class,
389*f05cddf9SRui Paulo 					  p2p->cfg->pref_chan[i].chan)) {
390*f05cddf9SRui Paulo 			p2p->op_reg_class = p2p->cfg->pref_chan[i].op_class;
391*f05cddf9SRui Paulo 			p2p->op_channel = p2p->cfg->pref_chan[i].chan;
392*f05cddf9SRui Paulo 			wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG, "P2P: Pick "
393*f05cddf9SRui Paulo 				"highest preferred chnnel (op_class %u "
394*f05cddf9SRui Paulo 				"channel %u) from intersection",
395*f05cddf9SRui Paulo 				p2p->op_reg_class, p2p->op_channel);
396*f05cddf9SRui Paulo 			return;
397*f05cddf9SRui Paulo 		}
398*f05cddf9SRui Paulo 	}
399*f05cddf9SRui Paulo 
400*f05cddf9SRui Paulo 	/* Try a channel where we might be able to use HT40 */
401*f05cddf9SRui Paulo 	for (i = 0; i < intersection->reg_classes; i++) {
402*f05cddf9SRui Paulo 		struct p2p_reg_class *c = &intersection->reg_class[i];
403*f05cddf9SRui Paulo 		if (c->reg_class == 116 || c->reg_class == 117 ||
404*f05cddf9SRui Paulo 		    c->reg_class == 126 || c->reg_class == 127) {
405*f05cddf9SRui Paulo 			wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG,
406*f05cddf9SRui Paulo 				"P2P: Pick possible HT40 channel (reg_class "
407*f05cddf9SRui Paulo 				"%u channel %u) from intersection",
408*f05cddf9SRui Paulo 				c->reg_class, c->channel[0]);
409*f05cddf9SRui Paulo 			p2p->op_reg_class = c->reg_class;
410*f05cddf9SRui Paulo 			p2p->op_channel = c->channel[0];
411*f05cddf9SRui Paulo 			return;
412*f05cddf9SRui Paulo 		}
413*f05cddf9SRui Paulo 	}
414*f05cddf9SRui Paulo 
415*f05cddf9SRui Paulo 	/*
416*f05cddf9SRui Paulo 	 * Try to see if the original channel is in the intersection. If
417*f05cddf9SRui Paulo 	 * so, no need to change anything, as it already contains some
418*f05cddf9SRui Paulo 	 * randomness.
419*f05cddf9SRui Paulo 	 */
420*f05cddf9SRui Paulo 	if (p2p_channels_includes(intersection, p2p->op_reg_class,
421*f05cddf9SRui Paulo 				  p2p->op_channel)) {
422*f05cddf9SRui Paulo 		wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG,
423*f05cddf9SRui Paulo 			"P2P: Using original operating class and channel "
424*f05cddf9SRui Paulo 			"(op_class %u channel %u) from intersection",
425*f05cddf9SRui Paulo 			p2p->op_reg_class, p2p->op_channel);
426*f05cddf9SRui Paulo 		return;
427*f05cddf9SRui Paulo 	}
428*f05cddf9SRui Paulo 
429*f05cddf9SRui Paulo 	/*
430*f05cddf9SRui Paulo 	 * Fall back to whatever is included in the channel intersection since
431*f05cddf9SRui Paulo 	 * no better options seems to be available.
432*f05cddf9SRui Paulo 	 */
433*f05cddf9SRui Paulo 	cl = &intersection->reg_class[0];
434*f05cddf9SRui Paulo 	wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG, "P2P: Pick another channel "
435*f05cddf9SRui Paulo 		"(reg_class %u channel %u) from intersection",
436*f05cddf9SRui Paulo 		cl->reg_class, cl->channel[0]);
437*f05cddf9SRui Paulo 	p2p->op_reg_class = cl->reg_class;
438*f05cddf9SRui Paulo 	p2p->op_channel = cl->channel[0];
439*f05cddf9SRui Paulo }
440*f05cddf9SRui Paulo 
441*f05cddf9SRui Paulo 
442*f05cddf9SRui Paulo static int p2p_go_select_channel(struct p2p_data *p2p, struct p2p_device *dev,
443*f05cddf9SRui Paulo 				 u8 *status)
444*f05cddf9SRui Paulo {
445*f05cddf9SRui Paulo 	struct p2p_channels intersection;
446*f05cddf9SRui Paulo 	size_t i;
447*f05cddf9SRui Paulo 
448*f05cddf9SRui Paulo 	p2p_channels_intersect(&p2p->channels, &dev->channels, &intersection);
449*f05cddf9SRui Paulo 	if (intersection.reg_classes == 0 ||
450*f05cddf9SRui Paulo 	    intersection.reg_class[0].channels == 0) {
451*f05cddf9SRui Paulo 		*status = P2P_SC_FAIL_NO_COMMON_CHANNELS;
452*f05cddf9SRui Paulo 		wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG,
453*f05cddf9SRui Paulo 			"P2P: No common channels found");
454*f05cddf9SRui Paulo 		return -1;
455*f05cddf9SRui Paulo 	}
456*f05cddf9SRui Paulo 
457*f05cddf9SRui Paulo 	for (i = 0; i < intersection.reg_classes; i++) {
458*f05cddf9SRui Paulo 		struct p2p_reg_class *c;
459*f05cddf9SRui Paulo 		c = &intersection.reg_class[i];
460*f05cddf9SRui Paulo 		wpa_printf(MSG_DEBUG, "P2P: reg_class %u", c->reg_class);
461*f05cddf9SRui Paulo 		wpa_hexdump(MSG_DEBUG, "P2P: channels",
462*f05cddf9SRui Paulo 			    c->channel, c->channels);
463*f05cddf9SRui Paulo 	}
464*f05cddf9SRui Paulo 
465*f05cddf9SRui Paulo 	if (!p2p_channels_includes(&intersection, p2p->op_reg_class,
466*f05cddf9SRui Paulo 				   p2p->op_channel)) {
467*f05cddf9SRui Paulo 		if (dev->flags & P2P_DEV_FORCE_FREQ) {
468*f05cddf9SRui Paulo 			*status = P2P_SC_FAIL_NO_COMMON_CHANNELS;
469*f05cddf9SRui Paulo 			wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG, "P2P: Peer does "
470*f05cddf9SRui Paulo 				"not support the forced channel");
471*f05cddf9SRui Paulo 			return -1;
472*f05cddf9SRui Paulo 		}
473*f05cddf9SRui Paulo 
474*f05cddf9SRui Paulo 		wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG, "P2P: Selected operating "
475*f05cddf9SRui Paulo 			"channel (op_class %u channel %u) not acceptable to "
476*f05cddf9SRui Paulo 			"the peer", p2p->op_reg_class, p2p->op_channel);
477*f05cddf9SRui Paulo 		p2p_reselect_channel(p2p, &intersection);
478*f05cddf9SRui Paulo 	} else if (!(dev->flags & P2P_DEV_FORCE_FREQ) &&
479*f05cddf9SRui Paulo 		   !p2p->cfg->cfg_op_channel) {
480*f05cddf9SRui Paulo 		wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG, "P2P: Try to optimize "
481*f05cddf9SRui Paulo 			"channel selection with peer information received; "
482*f05cddf9SRui Paulo 			"previously selected op_class %u channel %u",
483*f05cddf9SRui Paulo 			p2p->op_reg_class, p2p->op_channel);
484*f05cddf9SRui Paulo 		p2p_reselect_channel(p2p, &intersection);
485*f05cddf9SRui Paulo 	}
486*f05cddf9SRui Paulo 
487*f05cddf9SRui Paulo 	if (!p2p->ssid_set) {
488*f05cddf9SRui Paulo 		p2p_build_ssid(p2p, p2p->ssid, &p2p->ssid_len);
489*f05cddf9SRui Paulo 		p2p->ssid_set = 1;
490*f05cddf9SRui Paulo 	}
491*f05cddf9SRui Paulo 
492*f05cddf9SRui Paulo 	return 0;
493*f05cddf9SRui Paulo }
494*f05cddf9SRui Paulo 
495*f05cddf9SRui Paulo 
496*f05cddf9SRui Paulo void p2p_process_go_neg_req(struct p2p_data *p2p, const u8 *sa,
497*f05cddf9SRui Paulo 			    const u8 *data, size_t len, int rx_freq)
498*f05cddf9SRui Paulo {
499*f05cddf9SRui Paulo 	struct p2p_device *dev = NULL;
500*f05cddf9SRui Paulo 	struct wpabuf *resp;
501*f05cddf9SRui Paulo 	struct p2p_message msg;
502*f05cddf9SRui Paulo 	u8 status = P2P_SC_FAIL_INVALID_PARAMS;
503*f05cddf9SRui Paulo 	int tie_breaker = 0;
504*f05cddf9SRui Paulo 	int freq;
505*f05cddf9SRui Paulo 
506*f05cddf9SRui Paulo 	wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG,
507*f05cddf9SRui Paulo 		"P2P: Received GO Negotiation Request from " MACSTR
508*f05cddf9SRui Paulo 		"(freq=%d)", MAC2STR(sa), rx_freq);
509*f05cddf9SRui Paulo 
510*f05cddf9SRui Paulo 	if (p2p_parse(data, len, &msg))
511*f05cddf9SRui Paulo 		return;
512*f05cddf9SRui Paulo 
513*f05cddf9SRui Paulo 	if (!msg.capability) {
514*f05cddf9SRui Paulo 		wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG,
515*f05cddf9SRui Paulo 			"P2P: Mandatory Capability attribute missing from GO "
516*f05cddf9SRui Paulo 			"Negotiation Request");
517*f05cddf9SRui Paulo #ifdef CONFIG_P2P_STRICT
518*f05cddf9SRui Paulo 		goto fail;
519*f05cddf9SRui Paulo #endif /* CONFIG_P2P_STRICT */
520*f05cddf9SRui Paulo 	}
521*f05cddf9SRui Paulo 
522*f05cddf9SRui Paulo 	if (msg.go_intent)
523*f05cddf9SRui Paulo 		tie_breaker = *msg.go_intent & 0x01;
524*f05cddf9SRui Paulo 	else {
525*f05cddf9SRui Paulo 		wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG,
526*f05cddf9SRui Paulo 			"P2P: Mandatory GO Intent attribute missing from GO "
527*f05cddf9SRui Paulo 			"Negotiation Request");
528*f05cddf9SRui Paulo #ifdef CONFIG_P2P_STRICT
529*f05cddf9SRui Paulo 		goto fail;
530*f05cddf9SRui Paulo #endif /* CONFIG_P2P_STRICT */
531*f05cddf9SRui Paulo 	}
532*f05cddf9SRui Paulo 
533*f05cddf9SRui Paulo 	if (!msg.config_timeout) {
534*f05cddf9SRui Paulo 		wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG,
535*f05cddf9SRui Paulo 			"P2P: Mandatory Configuration Timeout attribute "
536*f05cddf9SRui Paulo 			"missing from GO Negotiation Request");
537*f05cddf9SRui Paulo #ifdef CONFIG_P2P_STRICT
538*f05cddf9SRui Paulo 		goto fail;
539*f05cddf9SRui Paulo #endif /* CONFIG_P2P_STRICT */
540*f05cddf9SRui Paulo 	}
541*f05cddf9SRui Paulo 
542*f05cddf9SRui Paulo 	if (!msg.listen_channel) {
543*f05cddf9SRui Paulo 		wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG,
544*f05cddf9SRui Paulo 			"P2P: No Listen Channel attribute received");
545*f05cddf9SRui Paulo 		goto fail;
546*f05cddf9SRui Paulo 	}
547*f05cddf9SRui Paulo 	if (!msg.operating_channel) {
548*f05cddf9SRui Paulo 		wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG,
549*f05cddf9SRui Paulo 			"P2P: No Operating Channel attribute received");
550*f05cddf9SRui Paulo 		goto fail;
551*f05cddf9SRui Paulo 	}
552*f05cddf9SRui Paulo 	if (!msg.channel_list) {
553*f05cddf9SRui Paulo 		wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG,
554*f05cddf9SRui Paulo 			"P2P: No Channel List attribute received");
555*f05cddf9SRui Paulo 		goto fail;
556*f05cddf9SRui Paulo 	}
557*f05cddf9SRui Paulo 	if (!msg.intended_addr) {
558*f05cddf9SRui Paulo 		wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG,
559*f05cddf9SRui Paulo 			"P2P: No Intended P2P Interface Address attribute "
560*f05cddf9SRui Paulo 			"received");
561*f05cddf9SRui Paulo 		goto fail;
562*f05cddf9SRui Paulo 	}
563*f05cddf9SRui Paulo 	if (!msg.p2p_device_info) {
564*f05cddf9SRui Paulo 		wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG,
565*f05cddf9SRui Paulo 			"P2P: No P2P Device Info attribute received");
566*f05cddf9SRui Paulo 		goto fail;
567*f05cddf9SRui Paulo 	}
568*f05cddf9SRui Paulo 
569*f05cddf9SRui Paulo 	if (os_memcmp(msg.p2p_device_addr, sa, ETH_ALEN) != 0) {
570*f05cddf9SRui Paulo 		wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG,
571*f05cddf9SRui Paulo 			"P2P: Unexpected GO Negotiation Request SA=" MACSTR
572*f05cddf9SRui Paulo 			" != dev_addr=" MACSTR,
573*f05cddf9SRui Paulo 			MAC2STR(sa), MAC2STR(msg.p2p_device_addr));
574*f05cddf9SRui Paulo 		goto fail;
575*f05cddf9SRui Paulo 	}
576*f05cddf9SRui Paulo 
577*f05cddf9SRui Paulo 	dev = p2p_get_device(p2p, sa);
578*f05cddf9SRui Paulo 
579*f05cddf9SRui Paulo 	if (msg.status && *msg.status) {
580*f05cddf9SRui Paulo 		wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG,
581*f05cddf9SRui Paulo 			"P2P: Unexpected Status attribute (%d) in GO "
582*f05cddf9SRui Paulo 			"Negotiation Request", *msg.status);
583*f05cddf9SRui Paulo 		goto fail;
584*f05cddf9SRui Paulo 	}
585*f05cddf9SRui Paulo 
586*f05cddf9SRui Paulo 	if (dev == NULL)
587*f05cddf9SRui Paulo 		dev = p2p_add_dev_from_go_neg_req(p2p, sa, &msg);
588*f05cddf9SRui Paulo 	else if (dev->flags & P2P_DEV_PROBE_REQ_ONLY)
589*f05cddf9SRui Paulo 		p2p_add_dev_info(p2p, sa, dev, &msg);
590*f05cddf9SRui Paulo 	if (dev && dev->flags & P2P_DEV_USER_REJECTED) {
591*f05cddf9SRui Paulo 		wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG,
592*f05cddf9SRui Paulo 			"P2P: User has rejected this peer");
593*f05cddf9SRui Paulo 		status = P2P_SC_FAIL_REJECTED_BY_USER;
594*f05cddf9SRui Paulo 	} else if (dev == NULL || dev->wps_method == WPS_NOT_READY) {
595*f05cddf9SRui Paulo 		wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG,
596*f05cddf9SRui Paulo 			"P2P: Not ready for GO negotiation with " MACSTR,
597*f05cddf9SRui Paulo 			MAC2STR(sa));
598*f05cddf9SRui Paulo 		status = P2P_SC_FAIL_INFO_CURRENTLY_UNAVAILABLE;
599*f05cddf9SRui Paulo 		if (dev)
600*f05cddf9SRui Paulo 			dev->flags |= P2P_DEV_PEER_WAITING_RESPONSE;
601*f05cddf9SRui Paulo 		p2p->cfg->go_neg_req_rx(p2p->cfg->cb_ctx, sa,
602*f05cddf9SRui Paulo 					msg.dev_password_id);
603*f05cddf9SRui Paulo 	} else if (p2p->go_neg_peer && p2p->go_neg_peer != dev) {
604*f05cddf9SRui Paulo 		wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG,
605*f05cddf9SRui Paulo 			"P2P: Already in Group Formation with another peer");
606*f05cddf9SRui Paulo 		status = P2P_SC_FAIL_UNABLE_TO_ACCOMMODATE;
607*f05cddf9SRui Paulo 	} else {
608*f05cddf9SRui Paulo 		int go;
609*f05cddf9SRui Paulo 
610*f05cddf9SRui Paulo 		if (!p2p->go_neg_peer) {
611*f05cddf9SRui Paulo 			wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG, "P2P: Starting "
612*f05cddf9SRui Paulo 				"GO Negotiation with previously authorized "
613*f05cddf9SRui Paulo 				"peer");
614*f05cddf9SRui Paulo 			if (!(dev->flags & P2P_DEV_FORCE_FREQ)) {
615*f05cddf9SRui Paulo 				wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG,
616*f05cddf9SRui Paulo 					"P2P: Use default channel settings");
617*f05cddf9SRui Paulo 				p2p->op_reg_class = p2p->cfg->op_reg_class;
618*f05cddf9SRui Paulo 				p2p->op_channel = p2p->cfg->op_channel;
619*f05cddf9SRui Paulo 				os_memcpy(&p2p->channels, &p2p->cfg->channels,
620*f05cddf9SRui Paulo 					  sizeof(struct p2p_channels));
621*f05cddf9SRui Paulo 			} else {
622*f05cddf9SRui Paulo 				wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG,
623*f05cddf9SRui Paulo 					"P2P: Use previously configured "
624*f05cddf9SRui Paulo 					"forced channel settings");
625*f05cddf9SRui Paulo 			}
626*f05cddf9SRui Paulo 		}
627*f05cddf9SRui Paulo 
628*f05cddf9SRui Paulo 		dev->flags &= ~P2P_DEV_NOT_YET_READY;
629*f05cddf9SRui Paulo 
630*f05cddf9SRui Paulo 		if (!msg.go_intent) {
631*f05cddf9SRui Paulo 			wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG,
632*f05cddf9SRui Paulo 				"P2P: No GO Intent attribute received");
633*f05cddf9SRui Paulo 			goto fail;
634*f05cddf9SRui Paulo 		}
635*f05cddf9SRui Paulo 		if ((*msg.go_intent >> 1) > P2P_MAX_GO_INTENT) {
636*f05cddf9SRui Paulo 			wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG,
637*f05cddf9SRui Paulo 				"P2P: Invalid GO Intent value (%u) received",
638*f05cddf9SRui Paulo 				*msg.go_intent >> 1);
639*f05cddf9SRui Paulo 			goto fail;
640*f05cddf9SRui Paulo 		}
641*f05cddf9SRui Paulo 
642*f05cddf9SRui Paulo 		if (dev->go_neg_req_sent &&
643*f05cddf9SRui Paulo 		    os_memcmp(sa, p2p->cfg->dev_addr, ETH_ALEN) > 0) {
644*f05cddf9SRui Paulo 			wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG,
645*f05cddf9SRui Paulo 				"P2P: Do not reply since peer has higher "
646*f05cddf9SRui Paulo 				"address and GO Neg Request already sent");
647*f05cddf9SRui Paulo 			p2p_parse_free(&msg);
648*f05cddf9SRui Paulo 			return;
649*f05cddf9SRui Paulo 		}
650*f05cddf9SRui Paulo 
651*f05cddf9SRui Paulo 		go = p2p_go_det(p2p->go_intent, *msg.go_intent);
652*f05cddf9SRui Paulo 		if (go < 0) {
653*f05cddf9SRui Paulo 			wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG,
654*f05cddf9SRui Paulo 				"P2P: Incompatible GO Intent");
655*f05cddf9SRui Paulo 			status = P2P_SC_FAIL_BOTH_GO_INTENT_15;
656*f05cddf9SRui Paulo 			goto fail;
657*f05cddf9SRui Paulo 		}
658*f05cddf9SRui Paulo 
659*f05cddf9SRui Paulo 		if (p2p_peer_channels(p2p, dev, msg.channel_list,
660*f05cddf9SRui Paulo 				      msg.channel_list_len) < 0) {
661*f05cddf9SRui Paulo 			wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG,
662*f05cddf9SRui Paulo 				"P2P: No common channels found");
663*f05cddf9SRui Paulo 			status = P2P_SC_FAIL_NO_COMMON_CHANNELS;
664*f05cddf9SRui Paulo 			goto fail;
665*f05cddf9SRui Paulo 		}
666*f05cddf9SRui Paulo 
667*f05cddf9SRui Paulo 		switch (msg.dev_password_id) {
668*f05cddf9SRui Paulo 		case DEV_PW_REGISTRAR_SPECIFIED:
669*f05cddf9SRui Paulo 			wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG,
670*f05cddf9SRui Paulo 				"P2P: PIN from peer Display");
671*f05cddf9SRui Paulo 			if (dev->wps_method != WPS_PIN_KEYPAD) {
672*f05cddf9SRui Paulo 				wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG,
673*f05cddf9SRui Paulo 					"P2P: We have wps_method=%s -> "
674*f05cddf9SRui Paulo 					"incompatible",
675*f05cddf9SRui Paulo 					p2p_wps_method_str(dev->wps_method));
676*f05cddf9SRui Paulo 				status = P2P_SC_FAIL_INCOMPATIBLE_PROV_METHOD;
677*f05cddf9SRui Paulo 				goto fail;
678*f05cddf9SRui Paulo 			}
679*f05cddf9SRui Paulo 			break;
680*f05cddf9SRui Paulo 		case DEV_PW_USER_SPECIFIED:
681*f05cddf9SRui Paulo 			wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG,
682*f05cddf9SRui Paulo 				"P2P: Peer entered PIN on Keypad");
683*f05cddf9SRui Paulo 			if (dev->wps_method != WPS_PIN_DISPLAY) {
684*f05cddf9SRui Paulo 				wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG,
685*f05cddf9SRui Paulo 					"P2P: We have wps_method=%s -> "
686*f05cddf9SRui Paulo 					"incompatible",
687*f05cddf9SRui Paulo 					p2p_wps_method_str(dev->wps_method));
688*f05cddf9SRui Paulo 				status = P2P_SC_FAIL_INCOMPATIBLE_PROV_METHOD;
689*f05cddf9SRui Paulo 				goto fail;
690*f05cddf9SRui Paulo 			}
691*f05cddf9SRui Paulo 			break;
692*f05cddf9SRui Paulo 		case DEV_PW_PUSHBUTTON:
693*f05cddf9SRui Paulo 			wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG,
694*f05cddf9SRui Paulo 				"P2P: Peer using pushbutton");
695*f05cddf9SRui Paulo 			if (dev->wps_method != WPS_PBC) {
696*f05cddf9SRui Paulo 				wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG,
697*f05cddf9SRui Paulo 					"P2P: We have wps_method=%s -> "
698*f05cddf9SRui Paulo 					"incompatible",
699*f05cddf9SRui Paulo 					p2p_wps_method_str(dev->wps_method));
700*f05cddf9SRui Paulo 				status = P2P_SC_FAIL_INCOMPATIBLE_PROV_METHOD;
701*f05cddf9SRui Paulo 				goto fail;
702*f05cddf9SRui Paulo 			}
703*f05cddf9SRui Paulo 			break;
704*f05cddf9SRui Paulo 		default:
705*f05cddf9SRui Paulo 			wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG,
706*f05cddf9SRui Paulo 				"P2P: Unsupported Device Password ID %d",
707*f05cddf9SRui Paulo 				msg.dev_password_id);
708*f05cddf9SRui Paulo 			status = P2P_SC_FAIL_INCOMPATIBLE_PROV_METHOD;
709*f05cddf9SRui Paulo 			goto fail;
710*f05cddf9SRui Paulo 		}
711*f05cddf9SRui Paulo 
712*f05cddf9SRui Paulo 		if (go && p2p_go_select_channel(p2p, dev, &status) < 0)
713*f05cddf9SRui Paulo 			goto fail;
714*f05cddf9SRui Paulo 
715*f05cddf9SRui Paulo 		dev->go_state = go ? LOCAL_GO : REMOTE_GO;
716*f05cddf9SRui Paulo 		dev->oper_freq = p2p_channel_to_freq((const char *)
717*f05cddf9SRui Paulo 						     msg.operating_channel,
718*f05cddf9SRui Paulo 						     msg.operating_channel[3],
719*f05cddf9SRui Paulo 						     msg.operating_channel[4]);
720*f05cddf9SRui Paulo 		wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG, "P2P: Peer operating "
721*f05cddf9SRui Paulo 			"channel preference: %d MHz", dev->oper_freq);
722*f05cddf9SRui Paulo 
723*f05cddf9SRui Paulo 		if (msg.config_timeout) {
724*f05cddf9SRui Paulo 			dev->go_timeout = msg.config_timeout[0];
725*f05cddf9SRui Paulo 			dev->client_timeout = msg.config_timeout[1];
726*f05cddf9SRui Paulo 		}
727*f05cddf9SRui Paulo 
728*f05cddf9SRui Paulo 		wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG,
729*f05cddf9SRui Paulo 			"P2P: GO Negotiation with " MACSTR, MAC2STR(sa));
730*f05cddf9SRui Paulo 		if (p2p->state != P2P_IDLE)
731*f05cddf9SRui Paulo 			p2p_stop_find_for_freq(p2p, rx_freq);
732*f05cddf9SRui Paulo 		p2p_set_state(p2p, P2P_GO_NEG);
733*f05cddf9SRui Paulo 		p2p_clear_timeout(p2p);
734*f05cddf9SRui Paulo 		dev->dialog_token = msg.dialog_token;
735*f05cddf9SRui Paulo 		os_memcpy(dev->intended_addr, msg.intended_addr, ETH_ALEN);
736*f05cddf9SRui Paulo 		p2p->go_neg_peer = dev;
737*f05cddf9SRui Paulo 		status = P2P_SC_SUCCESS;
738*f05cddf9SRui Paulo 	}
739*f05cddf9SRui Paulo 
740*f05cddf9SRui Paulo fail:
741*f05cddf9SRui Paulo 	if (dev)
742*f05cddf9SRui Paulo 		dev->status = status;
743*f05cddf9SRui Paulo 	resp = p2p_build_go_neg_resp(p2p, dev, msg.dialog_token, status,
744*f05cddf9SRui Paulo 				     !tie_breaker);
745*f05cddf9SRui Paulo 	p2p_parse_free(&msg);
746*f05cddf9SRui Paulo 	if (resp == NULL)
747*f05cddf9SRui Paulo 		return;
748*f05cddf9SRui Paulo 	wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG,
749*f05cddf9SRui Paulo 		"P2P: Sending GO Negotiation Response");
750*f05cddf9SRui Paulo 	if (rx_freq > 0)
751*f05cddf9SRui Paulo 		freq = rx_freq;
752*f05cddf9SRui Paulo 	else
753*f05cddf9SRui Paulo 		freq = p2p_channel_to_freq(p2p->cfg->country,
754*f05cddf9SRui Paulo 					   p2p->cfg->reg_class,
755*f05cddf9SRui Paulo 					   p2p->cfg->channel);
756*f05cddf9SRui Paulo 	if (freq < 0) {
757*f05cddf9SRui Paulo 		wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG,
758*f05cddf9SRui Paulo 			"P2P: Unknown regulatory class/channel");
759*f05cddf9SRui Paulo 		wpabuf_free(resp);
760*f05cddf9SRui Paulo 		return;
761*f05cddf9SRui Paulo 	}
762*f05cddf9SRui Paulo 	if (status == P2P_SC_SUCCESS) {
763*f05cddf9SRui Paulo 		p2p->pending_action_state = P2P_PENDING_GO_NEG_RESPONSE;
764*f05cddf9SRui Paulo 		dev->flags |= P2P_DEV_WAIT_GO_NEG_CONFIRM;
765*f05cddf9SRui Paulo 		if (os_memcmp(sa, p2p->cfg->dev_addr, ETH_ALEN) < 0) {
766*f05cddf9SRui Paulo 			/*
767*f05cddf9SRui Paulo 			 * Peer has smaller address, so the GO Negotiation
768*f05cddf9SRui Paulo 			 * Response from us is expected to complete
769*f05cddf9SRui Paulo 			 * negotiation. Ignore a GO Negotiation Response from
770*f05cddf9SRui Paulo 			 * the peer if it happens to be received after this
771*f05cddf9SRui Paulo 			 * point due to a race condition in GO Negotiation
772*f05cddf9SRui Paulo 			 * Request transmission and processing.
773*f05cddf9SRui Paulo 			 */
774*f05cddf9SRui Paulo 			dev->flags &= ~P2P_DEV_WAIT_GO_NEG_RESPONSE;
775*f05cddf9SRui Paulo 		}
776*f05cddf9SRui Paulo 	} else
777*f05cddf9SRui Paulo 		p2p->pending_action_state =
778*f05cddf9SRui Paulo 			P2P_PENDING_GO_NEG_RESPONSE_FAILURE;
779*f05cddf9SRui Paulo 	if (p2p_send_action(p2p, freq, sa, p2p->cfg->dev_addr,
780*f05cddf9SRui Paulo 			    p2p->cfg->dev_addr,
781*f05cddf9SRui Paulo 			    wpabuf_head(resp), wpabuf_len(resp), 250) < 0) {
782*f05cddf9SRui Paulo 		wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG,
783*f05cddf9SRui Paulo 			"P2P: Failed to send Action frame");
784*f05cddf9SRui Paulo 	}
785*f05cddf9SRui Paulo 
786*f05cddf9SRui Paulo 	wpabuf_free(resp);
787*f05cddf9SRui Paulo }
788*f05cddf9SRui Paulo 
789*f05cddf9SRui Paulo 
790*f05cddf9SRui Paulo static struct wpabuf * p2p_build_go_neg_conf(struct p2p_data *p2p,
791*f05cddf9SRui Paulo 					     struct p2p_device *peer,
792*f05cddf9SRui Paulo 					     u8 dialog_token, u8 status,
793*f05cddf9SRui Paulo 					     const u8 *resp_chan, int go)
794*f05cddf9SRui Paulo {
795*f05cddf9SRui Paulo 	struct wpabuf *buf;
796*f05cddf9SRui Paulo 	u8 *len;
797*f05cddf9SRui Paulo 	struct p2p_channels res;
798*f05cddf9SRui Paulo 	u8 group_capab;
799*f05cddf9SRui Paulo 	size_t extra = 0;
800*f05cddf9SRui Paulo 
801*f05cddf9SRui Paulo 	wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG,
802*f05cddf9SRui Paulo 		"P2P: Building GO Negotiation Confirm");
803*f05cddf9SRui Paulo 
804*f05cddf9SRui Paulo #ifdef CONFIG_WIFI_DISPLAY
805*f05cddf9SRui Paulo 	if (p2p->wfd_ie_go_neg)
806*f05cddf9SRui Paulo 		extra = wpabuf_len(p2p->wfd_ie_go_neg);
807*f05cddf9SRui Paulo #endif /* CONFIG_WIFI_DISPLAY */
808*f05cddf9SRui Paulo 
809*f05cddf9SRui Paulo 	buf = wpabuf_alloc(1000 + extra);
810*f05cddf9SRui Paulo 	if (buf == NULL)
811*f05cddf9SRui Paulo 		return NULL;
812*f05cddf9SRui Paulo 
813*f05cddf9SRui Paulo 	p2p_buf_add_public_action_hdr(buf, P2P_GO_NEG_CONF, dialog_token);
814*f05cddf9SRui Paulo 
815*f05cddf9SRui Paulo 	len = p2p_buf_add_ie_hdr(buf);
816*f05cddf9SRui Paulo 	p2p_buf_add_status(buf, status);
817*f05cddf9SRui Paulo 	group_capab = 0;
818*f05cddf9SRui Paulo 	if (peer->go_state == LOCAL_GO) {
819*f05cddf9SRui Paulo 		if (peer->flags & P2P_DEV_PREFER_PERSISTENT_GROUP) {
820*f05cddf9SRui Paulo 			group_capab |= P2P_GROUP_CAPAB_PERSISTENT_GROUP;
821*f05cddf9SRui Paulo 			if (peer->flags & P2P_DEV_PREFER_PERSISTENT_RECONN)
822*f05cddf9SRui Paulo 				group_capab |=
823*f05cddf9SRui Paulo 					P2P_GROUP_CAPAB_PERSISTENT_RECONN;
824*f05cddf9SRui Paulo 		}
825*f05cddf9SRui Paulo 		if (p2p->cross_connect)
826*f05cddf9SRui Paulo 			group_capab |= P2P_GROUP_CAPAB_CROSS_CONN;
827*f05cddf9SRui Paulo 		if (p2p->cfg->p2p_intra_bss)
828*f05cddf9SRui Paulo 			group_capab |= P2P_GROUP_CAPAB_INTRA_BSS_DIST;
829*f05cddf9SRui Paulo 	}
830*f05cddf9SRui Paulo 	p2p_buf_add_capability(buf, p2p->dev_capab &
831*f05cddf9SRui Paulo 			       ~P2P_DEV_CAPAB_CLIENT_DISCOVERABILITY,
832*f05cddf9SRui Paulo 			       group_capab);
833*f05cddf9SRui Paulo 	if (go || resp_chan == NULL)
834*f05cddf9SRui Paulo 		p2p_buf_add_operating_channel(buf, p2p->cfg->country,
835*f05cddf9SRui Paulo 					      p2p->op_reg_class,
836*f05cddf9SRui Paulo 					      p2p->op_channel);
837*f05cddf9SRui Paulo 	else
838*f05cddf9SRui Paulo 		p2p_buf_add_operating_channel(buf, (const char *) resp_chan,
839*f05cddf9SRui Paulo 					      resp_chan[3], resp_chan[4]);
840*f05cddf9SRui Paulo 	p2p_channels_intersect(&p2p->channels, &peer->channels, &res);
841*f05cddf9SRui Paulo 	p2p_buf_add_channel_list(buf, p2p->cfg->country, &res);
842*f05cddf9SRui Paulo 	if (go) {
843*f05cddf9SRui Paulo 		p2p_buf_add_group_id(buf, p2p->cfg->dev_addr, p2p->ssid,
844*f05cddf9SRui Paulo 				     p2p->ssid_len);
845*f05cddf9SRui Paulo 	}
846*f05cddf9SRui Paulo 	p2p_buf_update_ie_hdr(buf, len);
847*f05cddf9SRui Paulo 
848*f05cddf9SRui Paulo #ifdef CONFIG_WIFI_DISPLAY
849*f05cddf9SRui Paulo 	if (p2p->wfd_ie_go_neg)
850*f05cddf9SRui Paulo 		wpabuf_put_buf(buf, p2p->wfd_ie_go_neg);
851*f05cddf9SRui Paulo #endif /* CONFIG_WIFI_DISPLAY */
852*f05cddf9SRui Paulo 
853*f05cddf9SRui Paulo 	return buf;
854*f05cddf9SRui Paulo }
855*f05cddf9SRui Paulo 
856*f05cddf9SRui Paulo 
857*f05cddf9SRui Paulo void p2p_process_go_neg_resp(struct p2p_data *p2p, const u8 *sa,
858*f05cddf9SRui Paulo 			     const u8 *data, size_t len, int rx_freq)
859*f05cddf9SRui Paulo {
860*f05cddf9SRui Paulo 	struct p2p_device *dev;
861*f05cddf9SRui Paulo 	struct wpabuf *conf;
862*f05cddf9SRui Paulo 	int go = -1;
863*f05cddf9SRui Paulo 	struct p2p_message msg;
864*f05cddf9SRui Paulo 	u8 status = P2P_SC_SUCCESS;
865*f05cddf9SRui Paulo 	int freq;
866*f05cddf9SRui Paulo 
867*f05cddf9SRui Paulo 	wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG,
868*f05cddf9SRui Paulo 		"P2P: Received GO Negotiation Response from " MACSTR
869*f05cddf9SRui Paulo 		" (freq=%d)", MAC2STR(sa), rx_freq);
870*f05cddf9SRui Paulo 	dev = p2p_get_device(p2p, sa);
871*f05cddf9SRui Paulo 	if (dev == NULL || dev->wps_method == WPS_NOT_READY ||
872*f05cddf9SRui Paulo 	    dev != p2p->go_neg_peer) {
873*f05cddf9SRui Paulo 		wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG,
874*f05cddf9SRui Paulo 			"P2P: Not ready for GO negotiation with " MACSTR,
875*f05cddf9SRui Paulo 			MAC2STR(sa));
876*f05cddf9SRui Paulo 		return;
877*f05cddf9SRui Paulo 	}
878*f05cddf9SRui Paulo 
879*f05cddf9SRui Paulo 	if (p2p_parse(data, len, &msg))
880*f05cddf9SRui Paulo 		return;
881*f05cddf9SRui Paulo 
882*f05cddf9SRui Paulo 	if (!(dev->flags & P2P_DEV_WAIT_GO_NEG_RESPONSE)) {
883*f05cddf9SRui Paulo 		wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG,
884*f05cddf9SRui Paulo 			"P2P: Was not expecting GO Negotiation Response - "
885*f05cddf9SRui Paulo 			"ignore");
886*f05cddf9SRui Paulo 		p2p_parse_free(&msg);
887*f05cddf9SRui Paulo 		return;
888*f05cddf9SRui Paulo 	}
889*f05cddf9SRui Paulo 	dev->flags &= ~P2P_DEV_WAIT_GO_NEG_RESPONSE;
890*f05cddf9SRui Paulo 
891*f05cddf9SRui Paulo 	if (msg.dialog_token != dev->dialog_token) {
892*f05cddf9SRui Paulo 		wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG,
893*f05cddf9SRui Paulo 			"P2P: Unexpected Dialog Token %u (expected %u)",
894*f05cddf9SRui Paulo 			msg.dialog_token, dev->dialog_token);
895*f05cddf9SRui Paulo 		p2p_parse_free(&msg);
896*f05cddf9SRui Paulo 		return;
897*f05cddf9SRui Paulo 	}
898*f05cddf9SRui Paulo 
899*f05cddf9SRui Paulo 	if (!msg.status) {
900*f05cddf9SRui Paulo 		wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG,
901*f05cddf9SRui Paulo 			"P2P: No Status attribute received");
902*f05cddf9SRui Paulo 		status = P2P_SC_FAIL_INVALID_PARAMS;
903*f05cddf9SRui Paulo 		goto fail;
904*f05cddf9SRui Paulo 	}
905*f05cddf9SRui Paulo 	if (*msg.status) {
906*f05cddf9SRui Paulo 		wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG,
907*f05cddf9SRui Paulo 			"P2P: GO Negotiation rejected: status %d",
908*f05cddf9SRui Paulo 			*msg.status);
909*f05cddf9SRui Paulo 		dev->go_neg_req_sent = 0;
910*f05cddf9SRui Paulo 		if (*msg.status == P2P_SC_FAIL_INFO_CURRENTLY_UNAVAILABLE) {
911*f05cddf9SRui Paulo 			wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG,
912*f05cddf9SRui Paulo 				"P2P: Wait for the peer to become ready for "
913*f05cddf9SRui Paulo 				"GO Negotiation");
914*f05cddf9SRui Paulo 			dev->flags |= P2P_DEV_NOT_YET_READY;
915*f05cddf9SRui Paulo 			dev->wait_count = 0;
916*f05cddf9SRui Paulo 			p2p_set_state(p2p, P2P_WAIT_PEER_IDLE);
917*f05cddf9SRui Paulo 			p2p_set_timeout(p2p, 0, 0);
918*f05cddf9SRui Paulo 		} else {
919*f05cddf9SRui Paulo 			wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG,
920*f05cddf9SRui Paulo 				"P2P: Stop GO Negotiation attempt");
921*f05cddf9SRui Paulo 			p2p_go_neg_failed(p2p, dev, *msg.status);
922*f05cddf9SRui Paulo 		}
923*f05cddf9SRui Paulo 		p2p->cfg->send_action_done(p2p->cfg->cb_ctx);
924*f05cddf9SRui Paulo 		p2p_parse_free(&msg);
925*f05cddf9SRui Paulo 		return;
926*f05cddf9SRui Paulo 	}
927*f05cddf9SRui Paulo 
928*f05cddf9SRui Paulo 	if (!msg.capability) {
929*f05cddf9SRui Paulo 		wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG,
930*f05cddf9SRui Paulo 			"P2P: Mandatory Capability attribute missing from GO "
931*f05cddf9SRui Paulo 			"Negotiation Response");
932*f05cddf9SRui Paulo #ifdef CONFIG_P2P_STRICT
933*f05cddf9SRui Paulo 		status = P2P_SC_FAIL_INVALID_PARAMS;
934*f05cddf9SRui Paulo 		goto fail;
935*f05cddf9SRui Paulo #endif /* CONFIG_P2P_STRICT */
936*f05cddf9SRui Paulo 	}
937*f05cddf9SRui Paulo 
938*f05cddf9SRui Paulo 	if (!msg.p2p_device_info) {
939*f05cddf9SRui Paulo 		wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG,
940*f05cddf9SRui Paulo 			"P2P: Mandatory P2P Device Info attribute missing "
941*f05cddf9SRui Paulo 			"from GO Negotiation Response");
942*f05cddf9SRui Paulo #ifdef CONFIG_P2P_STRICT
943*f05cddf9SRui Paulo 		status = P2P_SC_FAIL_INVALID_PARAMS;
944*f05cddf9SRui Paulo 		goto fail;
945*f05cddf9SRui Paulo #endif /* CONFIG_P2P_STRICT */
946*f05cddf9SRui Paulo 	}
947*f05cddf9SRui Paulo 
948*f05cddf9SRui Paulo 	if (!msg.intended_addr) {
949*f05cddf9SRui Paulo 		wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG,
950*f05cddf9SRui Paulo 			"P2P: No Intended P2P Interface Address attribute "
951*f05cddf9SRui Paulo 			"received");
952*f05cddf9SRui Paulo 		status = P2P_SC_FAIL_INVALID_PARAMS;
953*f05cddf9SRui Paulo 		goto fail;
954*f05cddf9SRui Paulo 	}
955*f05cddf9SRui Paulo 
956*f05cddf9SRui Paulo 	if (!msg.go_intent) {
957*f05cddf9SRui Paulo 		wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG,
958*f05cddf9SRui Paulo 			"P2P: No GO Intent attribute received");
959*f05cddf9SRui Paulo 		status = P2P_SC_FAIL_INVALID_PARAMS;
960*f05cddf9SRui Paulo 		goto fail;
961*f05cddf9SRui Paulo 	}
962*f05cddf9SRui Paulo 	if ((*msg.go_intent >> 1) > P2P_MAX_GO_INTENT) {
963*f05cddf9SRui Paulo 		wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG,
964*f05cddf9SRui Paulo 			"P2P: Invalid GO Intent value (%u) received",
965*f05cddf9SRui Paulo 			*msg.go_intent >> 1);
966*f05cddf9SRui Paulo 		status = P2P_SC_FAIL_INVALID_PARAMS;
967*f05cddf9SRui Paulo 		goto fail;
968*f05cddf9SRui Paulo 	}
969*f05cddf9SRui Paulo 
970*f05cddf9SRui Paulo 	go = p2p_go_det(p2p->go_intent, *msg.go_intent);
971*f05cddf9SRui Paulo 	if (go < 0) {
972*f05cddf9SRui Paulo 		wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG,
973*f05cddf9SRui Paulo 			"P2P: Incompatible GO Intent");
974*f05cddf9SRui Paulo 		status = P2P_SC_FAIL_INCOMPATIBLE_PARAMS;
975*f05cddf9SRui Paulo 		goto fail;
976*f05cddf9SRui Paulo 	}
977*f05cddf9SRui Paulo 
978*f05cddf9SRui Paulo 	if (!go && msg.group_id) {
979*f05cddf9SRui Paulo 		/* Store SSID for Provisioning step */
980*f05cddf9SRui Paulo 		p2p->ssid_len = msg.group_id_len - ETH_ALEN;
981*f05cddf9SRui Paulo 		os_memcpy(p2p->ssid, msg.group_id + ETH_ALEN, p2p->ssid_len);
982*f05cddf9SRui Paulo 	} else if (!go) {
983*f05cddf9SRui Paulo 		wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG,
984*f05cddf9SRui Paulo 			"P2P: Mandatory P2P Group ID attribute missing from "
985*f05cddf9SRui Paulo 			"GO Negotiation Response");
986*f05cddf9SRui Paulo 		p2p->ssid_len = 0;
987*f05cddf9SRui Paulo #ifdef CONFIG_P2P_STRICT
988*f05cddf9SRui Paulo 		status = P2P_SC_FAIL_INVALID_PARAMS;
989*f05cddf9SRui Paulo 		goto fail;
990*f05cddf9SRui Paulo #endif /* CONFIG_P2P_STRICT */
991*f05cddf9SRui Paulo 	}
992*f05cddf9SRui Paulo 
993*f05cddf9SRui Paulo 	if (!msg.config_timeout) {
994*f05cddf9SRui Paulo 		wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG,
995*f05cddf9SRui Paulo 			"P2P: Mandatory Configuration Timeout attribute "
996*f05cddf9SRui Paulo 			"missing from GO Negotiation Response");
997*f05cddf9SRui Paulo #ifdef CONFIG_P2P_STRICT
998*f05cddf9SRui Paulo 		status = P2P_SC_FAIL_INVALID_PARAMS;
999*f05cddf9SRui Paulo 		goto fail;
1000*f05cddf9SRui Paulo #endif /* CONFIG_P2P_STRICT */
1001*f05cddf9SRui Paulo 	} else {
1002*f05cddf9SRui Paulo 		dev->go_timeout = msg.config_timeout[0];
1003*f05cddf9SRui Paulo 		dev->client_timeout = msg.config_timeout[1];
1004*f05cddf9SRui Paulo 	}
1005*f05cddf9SRui Paulo 
1006*f05cddf9SRui Paulo 	if (!msg.operating_channel && !go) {
1007*f05cddf9SRui Paulo 		/*
1008*f05cddf9SRui Paulo 		 * Note: P2P Client may omit Operating Channel attribute to
1009*f05cddf9SRui Paulo 		 * indicate it does not have a preference.
1010*f05cddf9SRui Paulo 		 */
1011*f05cddf9SRui Paulo 		wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG,
1012*f05cddf9SRui Paulo 			"P2P: No Operating Channel attribute received");
1013*f05cddf9SRui Paulo 		status = P2P_SC_FAIL_INVALID_PARAMS;
1014*f05cddf9SRui Paulo 		goto fail;
1015*f05cddf9SRui Paulo 	}
1016*f05cddf9SRui Paulo 	if (!msg.channel_list) {
1017*f05cddf9SRui Paulo 		wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG,
1018*f05cddf9SRui Paulo 			"P2P: No Channel List attribute received");
1019*f05cddf9SRui Paulo 		status = P2P_SC_FAIL_INVALID_PARAMS;
1020*f05cddf9SRui Paulo 		goto fail;
1021*f05cddf9SRui Paulo 	}
1022*f05cddf9SRui Paulo 
1023*f05cddf9SRui Paulo 	if (p2p_peer_channels(p2p, dev, msg.channel_list,
1024*f05cddf9SRui Paulo 			      msg.channel_list_len) < 0) {
1025*f05cddf9SRui Paulo 		wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG,
1026*f05cddf9SRui Paulo 			"P2P: No common channels found");
1027*f05cddf9SRui Paulo 		status = P2P_SC_FAIL_NO_COMMON_CHANNELS;
1028*f05cddf9SRui Paulo 		goto fail;
1029*f05cddf9SRui Paulo 	}
1030*f05cddf9SRui Paulo 
1031*f05cddf9SRui Paulo 	if (msg.operating_channel) {
1032*f05cddf9SRui Paulo 		dev->oper_freq = p2p_channel_to_freq((const char *)
1033*f05cddf9SRui Paulo 						     msg.operating_channel,
1034*f05cddf9SRui Paulo 						     msg.operating_channel[3],
1035*f05cddf9SRui Paulo 						     msg.operating_channel[4]);
1036*f05cddf9SRui Paulo 		wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG, "P2P: Peer operating "
1037*f05cddf9SRui Paulo 			"channel preference: %d MHz", dev->oper_freq);
1038*f05cddf9SRui Paulo 	} else
1039*f05cddf9SRui Paulo 		dev->oper_freq = 0;
1040*f05cddf9SRui Paulo 
1041*f05cddf9SRui Paulo 	switch (msg.dev_password_id) {
1042*f05cddf9SRui Paulo 	case DEV_PW_REGISTRAR_SPECIFIED:
1043*f05cddf9SRui Paulo 		wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG,
1044*f05cddf9SRui Paulo 			"P2P: PIN from peer Display");
1045*f05cddf9SRui Paulo 		if (dev->wps_method != WPS_PIN_KEYPAD) {
1046*f05cddf9SRui Paulo 			wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG,
1047*f05cddf9SRui Paulo 				"P2P: We have wps_method=%s -> "
1048*f05cddf9SRui Paulo 				"incompatible",
1049*f05cddf9SRui Paulo 				p2p_wps_method_str(dev->wps_method));
1050*f05cddf9SRui Paulo 			status = P2P_SC_FAIL_INCOMPATIBLE_PROV_METHOD;
1051*f05cddf9SRui Paulo 			goto fail;
1052*f05cddf9SRui Paulo 		}
1053*f05cddf9SRui Paulo 		break;
1054*f05cddf9SRui Paulo 	case DEV_PW_USER_SPECIFIED:
1055*f05cddf9SRui Paulo 		wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG,
1056*f05cddf9SRui Paulo 			"P2P: Peer entered PIN on Keypad");
1057*f05cddf9SRui Paulo 		if (dev->wps_method != WPS_PIN_DISPLAY) {
1058*f05cddf9SRui Paulo 			wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG,
1059*f05cddf9SRui Paulo 				"P2P: We have wps_method=%s -> "
1060*f05cddf9SRui Paulo 				"incompatible",
1061*f05cddf9SRui Paulo 				p2p_wps_method_str(dev->wps_method));
1062*f05cddf9SRui Paulo 			status = P2P_SC_FAIL_INCOMPATIBLE_PROV_METHOD;
1063*f05cddf9SRui Paulo 			goto fail;
1064*f05cddf9SRui Paulo 		}
1065*f05cddf9SRui Paulo 		break;
1066*f05cddf9SRui Paulo 	case DEV_PW_PUSHBUTTON:
1067*f05cddf9SRui Paulo 		wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG,
1068*f05cddf9SRui Paulo 			"P2P: Peer using pushbutton");
1069*f05cddf9SRui Paulo 		if (dev->wps_method != WPS_PBC) {
1070*f05cddf9SRui Paulo 			wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG,
1071*f05cddf9SRui Paulo 				"P2P: We have wps_method=%s -> "
1072*f05cddf9SRui Paulo 				"incompatible",
1073*f05cddf9SRui Paulo 				p2p_wps_method_str(dev->wps_method));
1074*f05cddf9SRui Paulo 			status = P2P_SC_FAIL_INCOMPATIBLE_PROV_METHOD;
1075*f05cddf9SRui Paulo 			goto fail;
1076*f05cddf9SRui Paulo 		}
1077*f05cddf9SRui Paulo 		break;
1078*f05cddf9SRui Paulo 	default:
1079*f05cddf9SRui Paulo 		wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG,
1080*f05cddf9SRui Paulo 			"P2P: Unsupported Device Password ID %d",
1081*f05cddf9SRui Paulo 			msg.dev_password_id);
1082*f05cddf9SRui Paulo 		status = P2P_SC_FAIL_INCOMPATIBLE_PROV_METHOD;
1083*f05cddf9SRui Paulo 		goto fail;
1084*f05cddf9SRui Paulo 	}
1085*f05cddf9SRui Paulo 
1086*f05cddf9SRui Paulo 	if (go && p2p_go_select_channel(p2p, dev, &status) < 0)
1087*f05cddf9SRui Paulo 		goto fail;
1088*f05cddf9SRui Paulo 
1089*f05cddf9SRui Paulo 	p2p_set_state(p2p, P2P_GO_NEG);
1090*f05cddf9SRui Paulo 	p2p_clear_timeout(p2p);
1091*f05cddf9SRui Paulo 
1092*f05cddf9SRui Paulo 	wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG,
1093*f05cddf9SRui Paulo 		"P2P: GO Negotiation with " MACSTR, MAC2STR(sa));
1094*f05cddf9SRui Paulo 	os_memcpy(dev->intended_addr, msg.intended_addr, ETH_ALEN);
1095*f05cddf9SRui Paulo 
1096*f05cddf9SRui Paulo fail:
1097*f05cddf9SRui Paulo 	conf = p2p_build_go_neg_conf(p2p, dev, msg.dialog_token, status,
1098*f05cddf9SRui Paulo 				     msg.operating_channel, go);
1099*f05cddf9SRui Paulo 	p2p_parse_free(&msg);
1100*f05cddf9SRui Paulo 	if (conf == NULL)
1101*f05cddf9SRui Paulo 		return;
1102*f05cddf9SRui Paulo 	wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG,
1103*f05cddf9SRui Paulo 		"P2P: Sending GO Negotiation Confirm");
1104*f05cddf9SRui Paulo 	if (status == P2P_SC_SUCCESS) {
1105*f05cddf9SRui Paulo 		p2p->pending_action_state = P2P_PENDING_GO_NEG_CONFIRM;
1106*f05cddf9SRui Paulo 		dev->go_state = go ? LOCAL_GO : REMOTE_GO;
1107*f05cddf9SRui Paulo 	} else
1108*f05cddf9SRui Paulo 		p2p->pending_action_state = P2P_NO_PENDING_ACTION;
1109*f05cddf9SRui Paulo 	if (rx_freq > 0)
1110*f05cddf9SRui Paulo 		freq = rx_freq;
1111*f05cddf9SRui Paulo 	else
1112*f05cddf9SRui Paulo 		freq = dev->listen_freq;
1113*f05cddf9SRui Paulo 	if (p2p_send_action(p2p, freq, sa, p2p->cfg->dev_addr, sa,
1114*f05cddf9SRui Paulo 			    wpabuf_head(conf), wpabuf_len(conf), 0) < 0) {
1115*f05cddf9SRui Paulo 		wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG,
1116*f05cddf9SRui Paulo 			"P2P: Failed to send Action frame");
1117*f05cddf9SRui Paulo 		p2p_go_neg_failed(p2p, dev, -1);
1118*f05cddf9SRui Paulo 	}
1119*f05cddf9SRui Paulo 	wpabuf_free(conf);
1120*f05cddf9SRui Paulo }
1121*f05cddf9SRui Paulo 
1122*f05cddf9SRui Paulo 
1123*f05cddf9SRui Paulo void p2p_process_go_neg_conf(struct p2p_data *p2p, const u8 *sa,
1124*f05cddf9SRui Paulo 			     const u8 *data, size_t len)
1125*f05cddf9SRui Paulo {
1126*f05cddf9SRui Paulo 	struct p2p_device *dev;
1127*f05cddf9SRui Paulo 	struct p2p_message msg;
1128*f05cddf9SRui Paulo 
1129*f05cddf9SRui Paulo 	wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG,
1130*f05cddf9SRui Paulo 		"P2P: Received GO Negotiation Confirm from " MACSTR,
1131*f05cddf9SRui Paulo 		MAC2STR(sa));
1132*f05cddf9SRui Paulo 	dev = p2p_get_device(p2p, sa);
1133*f05cddf9SRui Paulo 	if (dev == NULL || dev->wps_method == WPS_NOT_READY ||
1134*f05cddf9SRui Paulo 	    dev != p2p->go_neg_peer) {
1135*f05cddf9SRui Paulo 		wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG,
1136*f05cddf9SRui Paulo 			"P2P: Not ready for GO negotiation with " MACSTR,
1137*f05cddf9SRui Paulo 			MAC2STR(sa));
1138*f05cddf9SRui Paulo 		return;
1139*f05cddf9SRui Paulo 	}
1140*f05cddf9SRui Paulo 
1141*f05cddf9SRui Paulo 	if (p2p->pending_action_state == P2P_PENDING_GO_NEG_RESPONSE) {
1142*f05cddf9SRui Paulo 		wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG, "P2P: Stopped waiting "
1143*f05cddf9SRui Paulo 			"for TX status on GO Negotiation Response since we "
1144*f05cddf9SRui Paulo 			"already received Confirmation");
1145*f05cddf9SRui Paulo 		p2p->pending_action_state = P2P_NO_PENDING_ACTION;
1146*f05cddf9SRui Paulo 	}
1147*f05cddf9SRui Paulo 
1148*f05cddf9SRui Paulo 	if (p2p_parse(data, len, &msg))
1149*f05cddf9SRui Paulo 		return;
1150*f05cddf9SRui Paulo 
1151*f05cddf9SRui Paulo 	if (!(dev->flags & P2P_DEV_WAIT_GO_NEG_CONFIRM)) {
1152*f05cddf9SRui Paulo 		wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG,
1153*f05cddf9SRui Paulo 			"P2P: Was not expecting GO Negotiation Confirm - "
1154*f05cddf9SRui Paulo 			"ignore");
1155*f05cddf9SRui Paulo 		return;
1156*f05cddf9SRui Paulo 	}
1157*f05cddf9SRui Paulo 	dev->flags &= ~P2P_DEV_WAIT_GO_NEG_CONFIRM;
1158*f05cddf9SRui Paulo 
1159*f05cddf9SRui Paulo 	if (msg.dialog_token != dev->dialog_token) {
1160*f05cddf9SRui Paulo 		wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG,
1161*f05cddf9SRui Paulo 			"P2P: Unexpected Dialog Token %u (expected %u)",
1162*f05cddf9SRui Paulo 			msg.dialog_token, dev->dialog_token);
1163*f05cddf9SRui Paulo 		p2p_parse_free(&msg);
1164*f05cddf9SRui Paulo 		return;
1165*f05cddf9SRui Paulo 	}
1166*f05cddf9SRui Paulo 
1167*f05cddf9SRui Paulo 	if (!msg.status) {
1168*f05cddf9SRui Paulo 		wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG,
1169*f05cddf9SRui Paulo 			"P2P: No Status attribute received");
1170*f05cddf9SRui Paulo 		p2p_parse_free(&msg);
1171*f05cddf9SRui Paulo 		return;
1172*f05cddf9SRui Paulo 	}
1173*f05cddf9SRui Paulo 	if (*msg.status) {
1174*f05cddf9SRui Paulo 		wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG,
1175*f05cddf9SRui Paulo 			"P2P: GO Negotiation rejected: status %d",
1176*f05cddf9SRui Paulo 			*msg.status);
1177*f05cddf9SRui Paulo 		p2p_parse_free(&msg);
1178*f05cddf9SRui Paulo 		return;
1179*f05cddf9SRui Paulo 	}
1180*f05cddf9SRui Paulo 
1181*f05cddf9SRui Paulo 	if (dev->go_state == REMOTE_GO && msg.group_id) {
1182*f05cddf9SRui Paulo 		/* Store SSID for Provisioning step */
1183*f05cddf9SRui Paulo 		p2p->ssid_len = msg.group_id_len - ETH_ALEN;
1184*f05cddf9SRui Paulo 		os_memcpy(p2p->ssid, msg.group_id + ETH_ALEN, p2p->ssid_len);
1185*f05cddf9SRui Paulo 	} else if (dev->go_state == REMOTE_GO) {
1186*f05cddf9SRui Paulo 		wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG,
1187*f05cddf9SRui Paulo 			"P2P: Mandatory P2P Group ID attribute missing from "
1188*f05cddf9SRui Paulo 			"GO Negotiation Confirmation");
1189*f05cddf9SRui Paulo 		p2p->ssid_len = 0;
1190*f05cddf9SRui Paulo #ifdef CONFIG_P2P_STRICT
1191*f05cddf9SRui Paulo 		p2p_parse_free(&msg);
1192*f05cddf9SRui Paulo 		return;
1193*f05cddf9SRui Paulo #endif /* CONFIG_P2P_STRICT */
1194*f05cddf9SRui Paulo 	}
1195*f05cddf9SRui Paulo 
1196*f05cddf9SRui Paulo 	if (!msg.operating_channel) {
1197*f05cddf9SRui Paulo 		wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG,
1198*f05cddf9SRui Paulo 			"P2P: Mandatory Operating Channel attribute missing "
1199*f05cddf9SRui Paulo 			"from GO Negotiation Confirmation");
1200*f05cddf9SRui Paulo #ifdef CONFIG_P2P_STRICT
1201*f05cddf9SRui Paulo 		p2p_parse_free(&msg);
1202*f05cddf9SRui Paulo 		return;
1203*f05cddf9SRui Paulo #endif /* CONFIG_P2P_STRICT */
1204*f05cddf9SRui Paulo 	}
1205*f05cddf9SRui Paulo 
1206*f05cddf9SRui Paulo 	if (!msg.channel_list) {
1207*f05cddf9SRui Paulo 		wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG,
1208*f05cddf9SRui Paulo 			"P2P: Mandatory Operating Channel attribute missing "
1209*f05cddf9SRui Paulo 			"from GO Negotiation Confirmation");
1210*f05cddf9SRui Paulo #ifdef CONFIG_P2P_STRICT
1211*f05cddf9SRui Paulo 		p2p_parse_free(&msg);
1212*f05cddf9SRui Paulo 		return;
1213*f05cddf9SRui Paulo #endif /* CONFIG_P2P_STRICT */
1214*f05cddf9SRui Paulo 	}
1215*f05cddf9SRui Paulo 
1216*f05cddf9SRui Paulo 	p2p_parse_free(&msg);
1217*f05cddf9SRui Paulo 
1218*f05cddf9SRui Paulo 	if (dev->go_state == UNKNOWN_GO) {
1219*f05cddf9SRui Paulo 		/*
1220*f05cddf9SRui Paulo 		 * This should not happen since GO negotiation has already
1221*f05cddf9SRui Paulo 		 * been completed.
1222*f05cddf9SRui Paulo 		 */
1223*f05cddf9SRui Paulo 		wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG,
1224*f05cddf9SRui Paulo 			"P2P: Unexpected GO Neg state - do not know which end "
1225*f05cddf9SRui Paulo 			"becomes GO");
1226*f05cddf9SRui Paulo 		return;
1227*f05cddf9SRui Paulo 	}
1228*f05cddf9SRui Paulo 
1229*f05cddf9SRui Paulo 	/*
1230*f05cddf9SRui Paulo 	 * The peer could have missed our ctrl::ack frame for GO Negotiation
1231*f05cddf9SRui Paulo 	 * Confirm and continue retransmitting the frame. To reduce the
1232*f05cddf9SRui Paulo 	 * likelihood of the peer not getting successful TX status for the
1233*f05cddf9SRui Paulo 	 * GO Negotiation Confirm frame, wait a short time here before starting
1234*f05cddf9SRui Paulo 	 * the group so that we will remain on the current channel to
1235*f05cddf9SRui Paulo 	 * acknowledge any possible retransmission from the peer.
1236*f05cddf9SRui Paulo 	 */
1237*f05cddf9SRui Paulo 	wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG, "P2P: 20 ms wait on current "
1238*f05cddf9SRui Paulo 		"channel before starting group");
1239*f05cddf9SRui Paulo 	os_sleep(0, 20000);
1240*f05cddf9SRui Paulo 
1241*f05cddf9SRui Paulo 	p2p_go_complete(p2p, dev);
1242*f05cddf9SRui Paulo }
1243