• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Wi-Fi Direct - P2P Invitation procedure
3  * Copyright (c) 2010, Atheros Communications
4  *
5  * This software may be distributed under the terms of the BSD license.
6  * See README for more details.
7  */
8 
9 #include "includes.h"
10 
11 #include "common.h"
12 #include "common/ieee802_11_defs.h"
13 #include "common/wpa_ctrl.h"
14 #include "p2p_i.h"
15 #include "p2p.h"
16 
17 
p2p_build_invitation_req(struct p2p_data * p2p,struct p2p_device * peer,const u8 * go_dev_addr,int dev_pw_id)18 static struct wpabuf * p2p_build_invitation_req(struct p2p_data *p2p,
19 						struct p2p_device *peer,
20 						const u8 *go_dev_addr,
21 						int dev_pw_id)
22 {
23 	struct wpabuf *buf;
24 	u8 *len;
25 	const u8 *dev_addr;
26 	size_t extra = 0;
27 
28 #ifdef CONFIG_WIFI_DISPLAY
29 	struct wpabuf *wfd_ie = p2p->wfd_ie_invitation;
30 	if (wfd_ie && p2p->inv_role == P2P_INVITE_ROLE_ACTIVE_GO) {
31 		size_t i;
32 		for (i = 0; i < p2p->num_groups; i++) {
33 			struct p2p_group *g = p2p->groups[i];
34 			struct wpabuf *ie;
35 			if (os_memcmp(p2p_group_get_interface_addr(g),
36 				      p2p->inv_bssid, ETH_ALEN) != 0)
37 				continue;
38 			ie = p2p_group_get_wfd_ie(g);
39 			if (ie) {
40 				wfd_ie = ie;
41 				break;
42 			}
43 		}
44 	}
45 	if (wfd_ie)
46 		extra = wpabuf_len(wfd_ie);
47 #endif /* CONFIG_WIFI_DISPLAY */
48 
49 	if (p2p->vendor_elem && p2p->vendor_elem[VENDOR_ELEM_P2P_INV_REQ])
50 		extra += wpabuf_len(p2p->vendor_elem[VENDOR_ELEM_P2P_INV_REQ]);
51 
52 	buf = wpabuf_alloc(1000 + extra);
53 	if (buf == NULL)
54 		return NULL;
55 
56 	peer->dialog_token++;
57 	if (peer->dialog_token == 0)
58 		peer->dialog_token = 1;
59 	p2p_buf_add_public_action_hdr(buf, P2P_INVITATION_REQ,
60 				      peer->dialog_token);
61 
62 	len = p2p_buf_add_ie_hdr(buf);
63 	if (p2p->inv_role == P2P_INVITE_ROLE_ACTIVE_GO || !p2p->inv_persistent)
64 		p2p_buf_add_config_timeout(buf, 0, 0);
65 	else
66 		p2p_buf_add_config_timeout(buf, p2p->go_timeout,
67 					   p2p->client_timeout);
68 	p2p_buf_add_invitation_flags(buf, p2p->inv_persistent ?
69 				     P2P_INVITATION_FLAGS_TYPE : 0);
70 	if (p2p->inv_role != P2P_INVITE_ROLE_CLIENT ||
71 	    !(peer->flags & P2P_DEV_NO_PREF_CHAN))
72 		p2p_buf_add_operating_channel(buf, p2p->cfg->country,
73 					      p2p->op_reg_class,
74 					      p2p->op_channel);
75 	if (p2p->inv_bssid_set)
76 		p2p_buf_add_group_bssid(buf, p2p->inv_bssid);
77 	p2p_buf_add_channel_list(buf, p2p->cfg->country, &p2p->channels);
78 	if (go_dev_addr)
79 		dev_addr = go_dev_addr;
80 	else if (p2p->inv_role == P2P_INVITE_ROLE_CLIENT)
81 		dev_addr = peer->info.p2p_device_addr;
82 	else
83 		dev_addr = p2p->cfg->dev_addr;
84 	p2p_buf_add_group_id(buf, dev_addr, p2p->inv_ssid, p2p->inv_ssid_len);
85 	p2p_buf_add_device_info(buf, p2p, peer);
86 	p2p_buf_update_ie_hdr(buf, len);
87 
88 	p2p_buf_add_pref_channel_list(buf, p2p->pref_freq_list,
89 				      p2p->num_pref_freq);
90 
91 #ifdef CONFIG_WIFI_DISPLAY
92 	if (wfd_ie)
93 		wpabuf_put_buf(buf, wfd_ie);
94 #endif /* CONFIG_WIFI_DISPLAY */
95 
96 	if (p2p->vendor_elem && p2p->vendor_elem[VENDOR_ELEM_P2P_INV_REQ])
97 		wpabuf_put_buf(buf, p2p->vendor_elem[VENDOR_ELEM_P2P_INV_REQ]);
98 
99 	if (dev_pw_id >= 0) {
100 		/* WSC IE in Invitation Request for NFC static handover */
101 		p2p_build_wps_ie(p2p, buf, dev_pw_id, 0);
102 	}
103 
104 	return buf;
105 }
106 
107 
p2p_build_invitation_resp(struct p2p_data * p2p,struct p2p_device * peer,u8 dialog_token,u8 status,const u8 * group_bssid,u8 reg_class,u8 channel,struct p2p_channels * channels)108 static struct wpabuf * p2p_build_invitation_resp(struct p2p_data *p2p,
109 						 struct p2p_device *peer,
110 						 u8 dialog_token, u8 status,
111 						 const u8 *group_bssid,
112 						 u8 reg_class, u8 channel,
113 						 struct p2p_channels *channels)
114 {
115 	struct wpabuf *buf;
116 	u8 *len;
117 	size_t extra = 0;
118 
119 #ifdef CONFIG_WIFI_DISPLAY
120 	struct wpabuf *wfd_ie = p2p->wfd_ie_invitation;
121 	if (wfd_ie && group_bssid) {
122 		size_t i;
123 		for (i = 0; i < p2p->num_groups; i++) {
124 			struct p2p_group *g = p2p->groups[i];
125 			struct wpabuf *ie;
126 			if (os_memcmp(p2p_group_get_interface_addr(g),
127 				      group_bssid, ETH_ALEN) != 0)
128 				continue;
129 			ie = p2p_group_get_wfd_ie(g);
130 			if (ie) {
131 				wfd_ie = ie;
132 				break;
133 			}
134 		}
135 	}
136 	if (wfd_ie)
137 		extra = wpabuf_len(wfd_ie);
138 #endif /* CONFIG_WIFI_DISPLAY */
139 
140 	if (p2p->vendor_elem && p2p->vendor_elem[VENDOR_ELEM_P2P_INV_RESP])
141 		extra += wpabuf_len(p2p->vendor_elem[VENDOR_ELEM_P2P_INV_RESP]);
142 
143 	buf = wpabuf_alloc(1000 + extra);
144 	if (buf == NULL)
145 		return NULL;
146 
147 	p2p_buf_add_public_action_hdr(buf, P2P_INVITATION_RESP,
148 				      dialog_token);
149 
150 	len = p2p_buf_add_ie_hdr(buf);
151 	p2p_buf_add_status(buf, status);
152 	p2p_buf_add_config_timeout(buf, 0, 0); /* FIX */
153 	if (reg_class && channel)
154 		p2p_buf_add_operating_channel(buf, p2p->cfg->country,
155 					      reg_class, channel);
156 	if (group_bssid)
157 		p2p_buf_add_group_bssid(buf, group_bssid);
158 	if (channels)
159 		p2p_buf_add_channel_list(buf, p2p->cfg->country, channels);
160 	p2p_buf_update_ie_hdr(buf, len);
161 
162 #ifdef CONFIG_WIFI_DISPLAY
163 	if (wfd_ie)
164 		wpabuf_put_buf(buf, wfd_ie);
165 #endif /* CONFIG_WIFI_DISPLAY */
166 
167 	if (p2p->vendor_elem && p2p->vendor_elem[VENDOR_ELEM_P2P_INV_RESP])
168 		wpabuf_put_buf(buf, p2p->vendor_elem[VENDOR_ELEM_P2P_INV_RESP]);
169 
170 	return buf;
171 }
172 
173 
p2p_process_invitation_req(struct p2p_data * p2p,const u8 * sa,const u8 * data,size_t len,int rx_freq)174 void p2p_process_invitation_req(struct p2p_data *p2p, const u8 *sa,
175 				const u8 *data, size_t len, int rx_freq)
176 {
177 	struct p2p_device *dev;
178 	struct p2p_message msg;
179 	struct wpabuf *resp = NULL;
180 	u8 status = P2P_SC_FAIL_INFO_CURRENTLY_UNAVAILABLE;
181 	int freq;
182 	int go = 0;
183 	u8 group_bssid[ETH_ALEN], *bssid;
184 	int op_freq = 0;
185 	u8 reg_class = 0, channel = 0;
186 	struct p2p_channels all_channels, intersection, *channels = NULL;
187 	int persistent;
188 
189 	os_memset(group_bssid, 0, sizeof(group_bssid));
190 
191 	p2p_dbg(p2p, "Received Invitation Request from " MACSTR " (freq=%d)",
192 		MAC2STR(sa), rx_freq);
193 
194 	if (p2p_parse(data, len, &msg))
195 		return;
196 
197 	dev = p2p_get_device(p2p, sa);
198 	if (dev == NULL || (dev->flags & P2P_DEV_PROBE_REQ_ONLY)) {
199 		p2p_dbg(p2p, "Invitation Request from unknown peer " MACSTR,
200 			MAC2STR(sa));
201 
202 		if (p2p_add_device(p2p, sa, rx_freq, NULL, 0, data + 1, len - 1,
203 				   0)) {
204 			p2p_dbg(p2p, "Invitation Request add device failed "
205 				MACSTR, MAC2STR(sa));
206 			status = P2P_SC_FAIL_INFO_CURRENTLY_UNAVAILABLE;
207 			goto fail;
208 		}
209 
210 		dev = p2p_get_device(p2p, sa);
211 		if (dev == NULL) {
212 			p2p_dbg(p2p, "Reject Invitation Request from unknown peer "
213 				MACSTR, MAC2STR(sa));
214 			status = P2P_SC_FAIL_INFO_CURRENTLY_UNAVAILABLE;
215 			goto fail;
216 		}
217 	}
218 
219 	if (!msg.group_id || !msg.channel_list) {
220 		p2p_dbg(p2p, "Mandatory attribute missing in Invitation Request from "
221 			MACSTR, MAC2STR(sa));
222 		status = P2P_SC_FAIL_INVALID_PARAMS;
223 		goto fail;
224 	}
225 
226 	if (msg.invitation_flags)
227 		persistent = *msg.invitation_flags & P2P_INVITATION_FLAGS_TYPE;
228 	else {
229 		/* Invitation Flags is a mandatory attribute starting from P2P
230 		 * spec 1.06. As a backwards compatibility mechanism, assume
231 		 * the request was for a persistent group if the attribute is
232 		 * missing.
233 		 */
234 		p2p_dbg(p2p, "Mandatory Invitation Flags attribute missing from Invitation Request");
235 		persistent = 1;
236 	}
237 
238 	p2p_channels_union(&p2p->cfg->channels, &p2p->cfg->cli_channels,
239 			   &all_channels);
240 
241 	if (p2p_peer_channels_check(p2p, &all_channels, dev,
242 				    msg.channel_list, msg.channel_list_len) <
243 	    0) {
244 		p2p_dbg(p2p, "No common channels found");
245 		status = P2P_SC_FAIL_NO_COMMON_CHANNELS;
246 		goto fail;
247 	}
248 
249 	p2p_channels_dump(p2p, "own channels", &p2p->cfg->channels);
250 	p2p_channels_dump(p2p, "own client channels", &all_channels);
251 	p2p_channels_dump(p2p, "peer channels", &dev->channels);
252 	p2p_channels_intersect(&all_channels, &dev->channels,
253 			       &intersection);
254 	p2p_channels_dump(p2p, "intersection", &intersection);
255 
256 	if (p2p->cfg->invitation_process) {
257 		status = p2p->cfg->invitation_process(
258 			p2p->cfg->cb_ctx, sa, msg.group_bssid, msg.group_id,
259 			msg.group_id + ETH_ALEN, msg.group_id_len - ETH_ALEN,
260 			&go, group_bssid, &op_freq, persistent, &intersection,
261 			msg.dev_password_id_present ? msg.dev_password_id : -1);
262 	}
263 
264 	if (go) {
265 		p2p_channels_intersect(&p2p->cfg->channels, &dev->channels,
266 				       &intersection);
267 		p2p_channels_dump(p2p, "intersection(GO)", &intersection);
268 		if (intersection.reg_classes == 0) {
269 			p2p_dbg(p2p, "No common channels found (GO)");
270 			status = P2P_SC_FAIL_NO_COMMON_CHANNELS;
271 			goto fail;
272 		}
273 	}
274 
275 	if (op_freq) {
276 		p2p_dbg(p2p, "Invitation processing forced frequency %d MHz",
277 			op_freq);
278 		if (p2p_freq_to_channel(op_freq, &reg_class, &channel) < 0) {
279 			p2p_dbg(p2p, "Unknown forced freq %d MHz from invitation_process()",
280 				op_freq);
281 			status = P2P_SC_FAIL_NO_COMMON_CHANNELS;
282 			goto fail;
283 		}
284 
285 		if (!p2p_channels_includes(&intersection, reg_class, channel))
286 		{
287 			p2p_dbg(p2p, "forced freq %d MHz not in the supported channels intersection",
288 				op_freq);
289 			status = P2P_SC_FAIL_NO_COMMON_CHANNELS;
290 			goto fail;
291 		}
292 
293 		if (status == P2P_SC_SUCCESS)
294 			channels = &intersection;
295 	} else {
296 		p2p_dbg(p2p, "No forced channel from invitation processing - figure out best one to use");
297 
298 		/* Default to own configuration as a starting point */
299 		p2p->op_reg_class = p2p->cfg->op_reg_class;
300 		p2p->op_channel = p2p->cfg->op_channel;
301 		p2p_dbg(p2p, "Own default op_class %d channel %d",
302 			p2p->op_reg_class, p2p->op_channel);
303 
304 		/* Use peer preference if specified and compatible */
305 		if (msg.operating_channel) {
306 			int req_freq;
307 			req_freq = p2p_channel_to_freq(
308 				msg.operating_channel[3],
309 				msg.operating_channel[4]);
310 			p2p_dbg(p2p, "Peer operating channel preference: %d MHz",
311 				req_freq);
312 			if (req_freq > 0 &&
313 			    p2p_channels_includes(&intersection,
314 						  msg.operating_channel[3],
315 						  msg.operating_channel[4])) {
316 				p2p->op_reg_class = msg.operating_channel[3];
317 				p2p->op_channel = msg.operating_channel[4];
318 				p2p_dbg(p2p, "Use peer preference op_class %d channel %d",
319 					p2p->op_reg_class, p2p->op_channel);
320 			} else {
321 				p2p_dbg(p2p, "Cannot use peer channel preference");
322 			}
323 		}
324 
325 		/* Reselect the channel only for the case of the GO */
326 		if (go &&
327 		    !p2p_channels_includes(&intersection, p2p->op_reg_class,
328 					   p2p->op_channel)) {
329 			p2p_dbg(p2p, "Initially selected channel (op_class %d channel %d) not in channel intersection - try to reselect",
330 				p2p->op_reg_class, p2p->op_channel);
331 			p2p_reselect_channel(p2p, &intersection);
332 			p2p_dbg(p2p, "Re-selection result: op_class %d channel %d",
333 				p2p->op_reg_class, p2p->op_channel);
334 			if (!p2p_channels_includes(&intersection,
335 						   p2p->op_reg_class,
336 						   p2p->op_channel)) {
337 				p2p_dbg(p2p, "Peer does not support selected operating channel (reg_class=%u channel=%u)",
338 					p2p->op_reg_class, p2p->op_channel);
339 				status = P2P_SC_FAIL_NO_COMMON_CHANNELS;
340 				goto fail;
341 			}
342 		} else if (go && !(dev->flags & P2P_DEV_FORCE_FREQ) &&
343 			   !p2p->cfg->cfg_op_channel) {
344 			p2p_dbg(p2p, "Try to reselect channel selection with peer information received; previously selected op_class %u channel %u",
345 				p2p->op_reg_class, p2p->op_channel);
346 			p2p_reselect_channel(p2p, &intersection);
347 		}
348 
349 		/*
350 		 * Use the driver preferred frequency list extension if
351 		 * supported.
352 		 */
353 		p2p_check_pref_chan(p2p, go, dev, &msg);
354 
355 		op_freq = p2p_channel_to_freq(p2p->op_reg_class,
356 					      p2p->op_channel);
357 		if (op_freq < 0) {
358 			p2p_dbg(p2p, "Unknown operational channel (country=%c%c reg_class=%u channel=%u)",
359 				p2p->cfg->country[0], p2p->cfg->country[1],
360 				p2p->op_reg_class, p2p->op_channel);
361 			status = P2P_SC_FAIL_NO_COMMON_CHANNELS;
362 			goto fail;
363 		}
364 		p2p_dbg(p2p, "Selected operating channel - %d MHz", op_freq);
365 
366 		if (status == P2P_SC_SUCCESS) {
367 			reg_class = p2p->op_reg_class;
368 			channel = p2p->op_channel;
369 			channels = &intersection;
370 		}
371 	}
372 
373 fail:
374 	if (go && status == P2P_SC_SUCCESS && !is_zero_ether_addr(group_bssid))
375 		bssid = group_bssid;
376 	else
377 		bssid = NULL;
378 	resp = p2p_build_invitation_resp(p2p, dev, msg.dialog_token, status,
379 					 bssid, reg_class, channel, channels);
380 
381 	if (resp == NULL)
382 		goto out;
383 
384 	if (rx_freq > 0)
385 		freq = rx_freq;
386 	else
387 		freq = p2p_channel_to_freq(p2p->cfg->reg_class,
388 					   p2p->cfg->channel);
389 	if (freq < 0) {
390 		p2p_dbg(p2p, "Unknown regulatory class/channel");
391 		goto out;
392 	}
393 
394 	/*
395 	 * Store copy of invitation data to be used when processing TX status
396 	 * callback for the Acton frame.
397 	 */
398 	os_memcpy(p2p->inv_sa, sa, ETH_ALEN);
399 	if (msg.group_bssid) {
400 		os_memcpy(p2p->inv_group_bssid, msg.group_bssid, ETH_ALEN);
401 		p2p->inv_group_bssid_ptr = p2p->inv_group_bssid;
402 	} else
403 		p2p->inv_group_bssid_ptr = NULL;
404 	if (msg.group_id) {
405 		if (msg.group_id_len - ETH_ALEN <= SSID_MAX_LEN) {
406 			os_memcpy(p2p->inv_ssid, msg.group_id + ETH_ALEN,
407 				  msg.group_id_len - ETH_ALEN);
408 			p2p->inv_ssid_len = msg.group_id_len - ETH_ALEN;
409 		}
410 		os_memcpy(p2p->inv_go_dev_addr, msg.group_id, ETH_ALEN);
411 	} else {
412 		p2p->inv_ssid_len = 0;
413 		os_memset(p2p->inv_go_dev_addr, 0, ETH_ALEN);
414 	}
415 	p2p->inv_status = status;
416 	p2p->inv_op_freq = op_freq;
417 
418 	p2p->pending_action_state = P2P_PENDING_INVITATION_RESPONSE;
419 	if (p2p_send_action(p2p, freq, sa, p2p->cfg->dev_addr,
420 			    p2p->cfg->dev_addr,
421 			    wpabuf_head(resp), wpabuf_len(resp), 50) < 0) {
422 		p2p_dbg(p2p, "Failed to send Action frame");
423 	}
424 
425 out:
426 	wpabuf_free(resp);
427 	p2p_parse_free(&msg);
428 }
429 
430 
p2p_process_invitation_resp(struct p2p_data * p2p,const u8 * sa,const u8 * data,size_t len)431 void p2p_process_invitation_resp(struct p2p_data *p2p, const u8 *sa,
432 				 const u8 *data, size_t len)
433 {
434 	struct p2p_device *dev;
435 	struct p2p_message msg;
436 	struct p2p_channels intersection, *channels = NULL;
437 
438 	p2p_dbg(p2p, "Received Invitation Response from " MACSTR,
439 		MAC2STR(sa));
440 
441 	dev = p2p_get_device(p2p, sa);
442 	if (dev == NULL) {
443 		p2p_dbg(p2p, "Ignore Invitation Response from unknown peer "
444 			MACSTR, MAC2STR(sa));
445 		p2p->cfg->send_action_done(p2p->cfg->cb_ctx);
446 		return;
447 	}
448 
449 	if (dev != p2p->invite_peer) {
450 		p2p_dbg(p2p, "Ignore unexpected Invitation Response from peer "
451 			MACSTR, MAC2STR(sa));
452 		p2p->cfg->send_action_done(p2p->cfg->cb_ctx);
453 		return;
454 	}
455 
456 	if (p2p_parse(data, len, &msg)) {
457 		p2p->cfg->send_action_done(p2p->cfg->cb_ctx);
458 		return;
459 	}
460 
461 	if (!msg.status) {
462 		p2p_dbg(p2p, "Mandatory Status attribute missing in Invitation Response from "
463 			MACSTR, MAC2STR(sa));
464 		p2p_parse_free(&msg);
465 		p2p->cfg->send_action_done(p2p->cfg->cb_ctx);
466 		return;
467 	}
468 
469 	/*
470 	 * We should not really receive a replayed response twice since
471 	 * duplicate frames are supposed to be dropped. However, not all drivers
472 	 * do that for pre-association frames. We did not use to verify dialog
473 	 * token matches for invitation response frames, but that check can be
474 	 * safely used to drop a replayed response to the previous Invitation
475 	 * Request in case the suggested operating channel was changed. This
476 	 * allows a duplicated reject frame to be dropped with the assumption
477 	 * that the real response follows after it.
478 	 */
479 	if (*msg.status == P2P_SC_FAIL_NO_COMMON_CHANNELS &&
480 	    p2p->retry_invite_req_sent &&
481 	    msg.dialog_token != dev->dialog_token) {
482 		p2p_dbg(p2p, "Unexpected Dialog Token %u (expected %u)",
483 			msg.dialog_token, dev->dialog_token);
484 		p2p_parse_free(&msg);
485 		return;
486 	}
487 
488 	if (*msg.status == P2P_SC_FAIL_NO_COMMON_CHANNELS &&
489 	    p2p->retry_invite_req &&
490 	    p2p_channel_random_social(&p2p->cfg->channels, &p2p->op_reg_class,
491 				      &p2p->op_channel, NULL, NULL) == 0) {
492 		p2p->retry_invite_req = 0;
493 		p2p->cfg->send_action_done(p2p->cfg->cb_ctx);
494 		p2p->cfg->stop_listen(p2p->cfg->cb_ctx);
495 		p2p_set_state(p2p, P2P_INVITE);
496 		p2p_dbg(p2p, "Resend Invitation Request setting op_class %u channel %u as operating channel",
497 			p2p->op_reg_class, p2p->op_channel);
498 		p2p->retry_invite_req_sent = 1;
499 		p2p_invite_send(p2p, p2p->invite_peer, p2p->invite_go_dev_addr,
500 				p2p->invite_dev_pw_id);
501 		p2p_parse_free(&msg);
502 		return;
503 	}
504 	p2p->cfg->send_action_done(p2p->cfg->cb_ctx);
505 	p2p->retry_invite_req = 0;
506 
507 	if (!msg.channel_list && *msg.status == P2P_SC_SUCCESS) {
508 		p2p_dbg(p2p, "Mandatory Channel List attribute missing in Invitation Response from "
509 			MACSTR, MAC2STR(sa));
510 #ifdef CONFIG_P2P_STRICT
511 		p2p_parse_free(&msg);
512 		return;
513 #endif /* CONFIG_P2P_STRICT */
514 		/* Try to survive without peer channel list */
515 		channels = &p2p->channels;
516 	} else if (!msg.channel_list) {
517 		/* Non-success cases are not required to include Channel List */
518 		channels = &p2p->channels;
519 	} else if (p2p_peer_channels_check(p2p, &p2p->channels, dev,
520 					   msg.channel_list,
521 					   msg.channel_list_len) < 0) {
522 		p2p_dbg(p2p, "No common channels found");
523 		p2p_parse_free(&msg);
524 		return;
525 	} else {
526 		p2p_channels_intersect(&p2p->channels, &dev->channels,
527 				       &intersection);
528 		channels = &intersection;
529 	}
530 
531 	if (p2p->cfg->invitation_result) {
532 		int peer_oper_freq = 0;
533 		int freq = p2p_channel_to_freq(p2p->op_reg_class,
534 					       p2p->op_channel);
535 		if (freq < 0)
536 			freq = 0;
537 
538 		if (msg.operating_channel) {
539 			peer_oper_freq = p2p_channel_to_freq(
540 				msg.operating_channel[3],
541 				msg.operating_channel[4]);
542 			if (peer_oper_freq < 0)
543 				peer_oper_freq = 0;
544 		}
545 
546 		/*
547 		 * Use the driver preferred frequency list extension if
548 		 * supported.
549 		 */
550 		p2p_check_pref_chan(p2p, 0, dev, &msg);
551 
552 		p2p->cfg->invitation_result(p2p->cfg->cb_ctx, *msg.status,
553 					    msg.group_bssid, channels, sa,
554 					    freq, peer_oper_freq);
555 	}
556 
557 	p2p_parse_free(&msg);
558 
559 	p2p_clear_timeout(p2p);
560 	p2p_set_state(p2p, P2P_IDLE);
561 	p2p->invite_peer = NULL;
562 }
563 
564 
p2p_invite_send(struct p2p_data * p2p,struct p2p_device * dev,const u8 * go_dev_addr,int dev_pw_id)565 int p2p_invite_send(struct p2p_data *p2p, struct p2p_device *dev,
566 		    const u8 *go_dev_addr, int dev_pw_id)
567 {
568 	struct wpabuf *req;
569 	int freq;
570 
571 	freq = dev->listen_freq > 0 ? dev->listen_freq : dev->oper_freq;
572 	if (freq <= 0)
573 		freq = dev->oob_go_neg_freq;
574 	if (freq <= 0) {
575 		p2p_dbg(p2p, "No Listen/Operating frequency known for the peer "
576 			MACSTR " to send Invitation Request",
577 			MAC2STR(dev->info.p2p_device_addr));
578 		return -1;
579 	}
580 
581 	req = p2p_build_invitation_req(p2p, dev, go_dev_addr, dev_pw_id);
582 	if (req == NULL)
583 		return -1;
584 	if (p2p->state != P2P_IDLE)
585 		p2p_stop_listen_for_freq(p2p, freq);
586 	p2p_dbg(p2p, "Sending Invitation Request");
587 	p2p_set_state(p2p, P2P_INVITE);
588 	p2p->pending_action_state = P2P_PENDING_INVITATION_REQUEST;
589 	p2p->invite_peer = dev;
590 	dev->invitation_reqs++;
591 	if (p2p_send_action(p2p, freq, dev->info.p2p_device_addr,
592 			    p2p->cfg->dev_addr, dev->info.p2p_device_addr,
593 			    wpabuf_head(req), wpabuf_len(req), 500) < 0) {
594 		p2p_dbg(p2p, "Failed to send Action frame");
595 		/* Use P2P find to recover and retry */
596 		p2p_set_timeout(p2p, 0, 0);
597 	} else {
598 		dev->flags |= P2P_DEV_WAIT_INV_REQ_ACK;
599 	}
600 
601 	wpabuf_free(req);
602 
603 	return 0;
604 }
605 
606 
p2p_invitation_req_cb(struct p2p_data * p2p,int success)607 void p2p_invitation_req_cb(struct p2p_data *p2p, int success)
608 {
609 	p2p_dbg(p2p, "Invitation Request TX callback: success=%d", success);
610 
611 	if (p2p->invite_peer == NULL) {
612 		p2p_dbg(p2p, "No pending Invite");
613 		return;
614 	}
615 
616 	if (success)
617 		p2p->invite_peer->flags &= ~P2P_DEV_WAIT_INV_REQ_ACK;
618 
619 	/*
620 	 * Use P2P find, if needed, to find the other device from its listen
621 	 * channel.
622 	 */
623 	p2p_set_state(p2p, P2P_INVITE);
624 	p2p_set_timeout(p2p, 0, success ? 500000 : 100000);
625 }
626 
627 
p2p_invitation_resp_cb(struct p2p_data * p2p,int success)628 void p2p_invitation_resp_cb(struct p2p_data *p2p, int success)
629 {
630 	p2p_dbg(p2p, "Invitation Response TX callback: success=%d", success);
631 	p2p->cfg->send_action_done(p2p->cfg->cb_ctx);
632 
633 	if (!success)
634 		p2p_dbg(p2p, "Assume Invitation Response was actually received by the peer even though Ack was not reported");
635 
636 	if (p2p->cfg->invitation_received) {
637 		p2p->cfg->invitation_received(p2p->cfg->cb_ctx,
638 					      p2p->inv_sa,
639 					      p2p->inv_group_bssid_ptr,
640 					      p2p->inv_ssid, p2p->inv_ssid_len,
641 					      p2p->inv_go_dev_addr,
642 					      p2p->inv_status,
643 					      p2p->inv_op_freq);
644 	}
645 }
646 
647 
p2p_invite(struct p2p_data * p2p,const u8 * peer,enum p2p_invite_role role,const u8 * bssid,const u8 * ssid,size_t ssid_len,unsigned int force_freq,const u8 * go_dev_addr,int persistent_group,unsigned int pref_freq,int dev_pw_id)648 int p2p_invite(struct p2p_data *p2p, const u8 *peer, enum p2p_invite_role role,
649 	       const u8 *bssid, const u8 *ssid, size_t ssid_len,
650 	       unsigned int force_freq, const u8 *go_dev_addr,
651 	       int persistent_group, unsigned int pref_freq, int dev_pw_id)
652 {
653 	struct p2p_device *dev;
654 
655 	p2p_dbg(p2p, "Request to invite peer " MACSTR " role=%d persistent=%d "
656 		"force_freq=%u allow_6ghz=%d",
657 		MAC2STR(peer), role, persistent_group, force_freq,
658 		p2p->allow_6ghz);
659 	if (bssid)
660 		p2p_dbg(p2p, "Invitation for BSSID " MACSTR, MAC2STR(bssid));
661 	if (go_dev_addr) {
662 		p2p_dbg(p2p, "Invitation for GO Device Address " MACSTR,
663 			MAC2STR(go_dev_addr));
664 		os_memcpy(p2p->invite_go_dev_addr_buf, go_dev_addr, ETH_ALEN);
665 		p2p->invite_go_dev_addr = p2p->invite_go_dev_addr_buf;
666 	} else
667 		p2p->invite_go_dev_addr = NULL;
668 	wpa_hexdump_ascii(MSG_DEBUG, "Invitation for SSID",
669 			  ssid, ssid_len);
670 	if (dev_pw_id >= 0) {
671 		p2p_dbg(p2p, "Invitation to use Device Password ID %d",
672 			dev_pw_id);
673 	}
674 	p2p->invite_dev_pw_id = dev_pw_id;
675 	p2p->retry_invite_req = role == P2P_INVITE_ROLE_GO &&
676 		persistent_group && !force_freq;
677 	p2p->retry_invite_req_sent = 0;
678 
679 	dev = p2p_get_device(p2p, peer);
680 	if (dev == NULL || (dev->listen_freq <= 0 && dev->oper_freq <= 0 &&
681 			    dev->oob_go_neg_freq <= 0)) {
682 		p2p_dbg(p2p, "Cannot invite unknown P2P Device " MACSTR,
683 			MAC2STR(peer));
684 		return -1;
685 	}
686 
687 	if (p2p_prepare_channel(p2p, dev, force_freq, pref_freq,
688 				role != P2P_INVITE_ROLE_CLIENT) < 0)
689 		return -1;
690 
691 	if (persistent_group && role == P2P_INVITE_ROLE_CLIENT && !force_freq &&
692 	    !pref_freq)
693 		dev->flags |= P2P_DEV_NO_PREF_CHAN;
694 	else
695 		dev->flags &= ~P2P_DEV_NO_PREF_CHAN;
696 
697 	if (dev->flags & P2P_DEV_GROUP_CLIENT_ONLY) {
698 		if (!(dev->info.dev_capab &
699 		      P2P_DEV_CAPAB_CLIENT_DISCOVERABILITY)) {
700 			p2p_dbg(p2p, "Cannot invite a P2P Device " MACSTR
701 				" that is in a group and is not discoverable",
702 				MAC2STR(peer));
703 		}
704 		/* TODO: use device discoverability request through GO */
705 	}
706 
707 	dev->invitation_reqs = 0;
708 
709 	if (p2p->state != P2P_IDLE)
710 		p2p_stop_find(p2p);
711 
712 	p2p->inv_role = role;
713 	p2p->inv_bssid_set = bssid != NULL;
714 	if (bssid)
715 		os_memcpy(p2p->inv_bssid, bssid, ETH_ALEN);
716 	os_memcpy(p2p->inv_ssid, ssid, ssid_len);
717 	p2p->inv_ssid_len = ssid_len;
718 	p2p->inv_persistent = persistent_group;
719 	return p2p_invite_send(p2p, dev, go_dev_addr, dev_pw_id);
720 }
721