p2p_invitation.c revision 497c1d5e50162d6b3c1cce5dbd9c5fd9da69aaef
1/*
2 * Wi-Fi Direct - P2P Invitation procedure
3 * Copyright (c) 2010, Atheros Communications
4 *
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License version 2 as
7 * published by the Free Software Foundation.
8 *
9 * Alternatively, this software may be distributed under the terms of BSD
10 * license.
11 *
12 * See README and COPYING for more details.
13 */
14
15#include "includes.h"
16
17#include "common.h"
18#include "common/ieee802_11_defs.h"
19#include "p2p_i.h"
20#include "p2p.h"
21
22
23static struct wpabuf * p2p_build_invitation_req(struct p2p_data *p2p,
24						struct p2p_device *peer,
25						const u8 *go_dev_addr)
26{
27	struct wpabuf *buf;
28	u8 *len;
29	const u8 *dev_addr;
30
31	buf = wpabuf_alloc(1000);
32	if (buf == NULL)
33		return NULL;
34
35	peer->dialog_token++;
36	if (peer->dialog_token == 0)
37		peer->dialog_token = 1;
38	p2p_buf_add_public_action_hdr(buf, P2P_INVITATION_REQ,
39				      peer->dialog_token);
40
41	len = p2p_buf_add_ie_hdr(buf);
42	if (p2p->inv_role == P2P_INVITE_ROLE_ACTIVE_GO || !p2p->inv_persistent)
43		p2p_buf_add_config_timeout(buf, 0, 0);
44	else
45		p2p_buf_add_config_timeout(buf, 100, 20);
46	p2p_buf_add_invitation_flags(buf, p2p->inv_persistent ?
47				     P2P_INVITATION_FLAGS_TYPE : 0);
48	p2p_buf_add_operating_channel(buf, p2p->cfg->country,
49				      p2p->op_reg_class, p2p->op_channel);
50	if (p2p->inv_bssid_set)
51		p2p_buf_add_group_bssid(buf, p2p->inv_bssid);
52	p2p_buf_add_channel_list(buf, p2p->cfg->country, &p2p->channels);
53	if (go_dev_addr)
54		dev_addr = go_dev_addr;
55	else if (p2p->inv_role == P2P_INVITE_ROLE_CLIENT)
56		dev_addr = peer->info.p2p_device_addr;
57	else
58#ifdef ANDROID_BRCM_P2P_PATCH
59		dev_addr = p2p->cfg->p2p_dev_addr;
60#else
61		dev_addr = p2p->cfg->dev_addr;
62#endif
63	p2p_buf_add_group_id(buf, dev_addr, p2p->inv_ssid, p2p->inv_ssid_len);
64	p2p_buf_add_device_info(buf, p2p, peer);
65	p2p_buf_update_ie_hdr(buf, len);
66
67	return buf;
68}
69
70
71static struct wpabuf * p2p_build_invitation_resp(struct p2p_data *p2p,
72						 struct p2p_device *peer,
73						 u8 dialog_token, u8 status,
74						 const u8 *group_bssid,
75						 u8 reg_class, u8 channel,
76						 struct p2p_channels *channels)
77{
78	struct wpabuf *buf;
79	u8 *len;
80
81	buf = wpabuf_alloc(1000);
82	if (buf == NULL)
83		return NULL;
84
85	p2p_buf_add_public_action_hdr(buf, P2P_INVITATION_RESP,
86				      dialog_token);
87
88	len = p2p_buf_add_ie_hdr(buf);
89	p2p_buf_add_status(buf, status);
90	p2p_buf_add_config_timeout(buf, 0, 0); /* FIX */
91	if (reg_class && channel)
92		p2p_buf_add_operating_channel(buf, p2p->cfg->country,
93					      reg_class, channel);
94	if (group_bssid)
95		p2p_buf_add_group_bssid(buf, group_bssid);
96	if (channels)
97		p2p_buf_add_channel_list(buf, p2p->cfg->country, channels);
98	p2p_buf_update_ie_hdr(buf, len);
99
100	return buf;
101}
102
103
104void p2p_process_invitation_req(struct p2p_data *p2p, const u8 *sa,
105				const u8 *data, size_t len, int rx_freq)
106{
107	struct p2p_device *dev;
108	struct p2p_message msg;
109	struct wpabuf *resp = NULL;
110	u8 status = P2P_SC_FAIL_INFO_CURRENTLY_UNAVAILABLE;
111	int freq;
112	int go = 0;
113	u8 group_bssid[ETH_ALEN], *bssid;
114	int op_freq = 0;
115	u8 reg_class = 0, channel = 0;
116	struct p2p_channels intersection, *channels = NULL;
117	int persistent;
118
119	os_memset(group_bssid, 0, sizeof(group_bssid));
120
121	wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG,
122		"P2P: Received Invitation Request from " MACSTR " (freq=%d)",
123		MAC2STR(sa), rx_freq);
124
125	if (p2p_parse(data, len, &msg))
126		return;
127
128	dev = p2p_get_device(p2p, sa);
129	if (dev == NULL || (dev->flags & P2P_DEV_PROBE_REQ_ONLY)) {
130		wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG,
131			"P2P: Invitation Request from unknown peer "
132			MACSTR, MAC2STR(sa));
133
134		if (p2p_add_device(p2p, sa, rx_freq, 0, data + 1, len - 1)) {
135			wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG,
136				"P2P: Invitation Request add device failed "
137				MACSTR, MAC2STR(sa));
138			status = P2P_SC_FAIL_INFO_CURRENTLY_UNAVAILABLE;
139			goto fail;
140		}
141
142		dev = p2p_get_device(p2p, sa);
143		if (dev == NULL) {
144			wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG,
145				"P2P: Reject Invitation Request from unknown "
146				"peer " MACSTR, MAC2STR(sa));
147			status = P2P_SC_FAIL_INFO_CURRENTLY_UNAVAILABLE;
148			goto fail;
149		}
150	}
151
152	if (!msg.group_id || !msg.channel_list) {
153		wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG,
154			"P2P: Mandatory attribute missing in Invitation "
155			"Request from " MACSTR, MAC2STR(sa));
156		status = P2P_SC_FAIL_INVALID_PARAMS;
157		goto fail;
158	}
159
160	if (msg.invitation_flags)
161		persistent = *msg.invitation_flags & P2P_INVITATION_FLAGS_TYPE;
162	else {
163		/* Invitation Flags is a mandatory attribute starting from P2P
164		 * spec 1.06. As a backwards compatibility mechanism, assume
165		 * the request was for a persistent group if the attribute is
166		 * missing.
167		 */
168		wpa_printf(MSG_DEBUG, "P2P: Mandatory Invitation Flags "
169			   "attribute missing from Invitation Request");
170		persistent = 1;
171	}
172
173	if (p2p_peer_channels_check(p2p, &p2p->cfg->channels, dev,
174				    msg.channel_list, msg.channel_list_len) <
175	    0) {
176		wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG,
177			"P2P: No common channels found");
178		status = P2P_SC_FAIL_NO_COMMON_CHANNELS;
179		goto fail;
180	}
181
182	if (p2p->cfg->invitation_process) {
183		status = p2p->cfg->invitation_process(
184			p2p->cfg->cb_ctx, sa, msg.group_bssid, msg.group_id,
185			msg.group_id + ETH_ALEN, msg.group_id_len - ETH_ALEN,
186			&go, group_bssid, &op_freq, persistent);
187	}
188
189	if (op_freq) {
190		if (p2p_freq_to_channel(p2p->cfg->country, op_freq,
191					&reg_class, &channel) < 0) {
192			wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG,
193				"P2P: Unknown forced freq %d MHz from "
194				"invitation_process()", op_freq);
195			status = P2P_SC_FAIL_NO_COMMON_CHANNELS;
196			goto fail;
197		}
198
199		p2p_channels_intersect(&p2p->cfg->channels, &dev->channels,
200				       &intersection);
201		if (!p2p_channels_includes(&intersection, reg_class, channel))
202		{
203			wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG,
204				"P2P: forced freq %d MHz not in the supported "
205				"channels interaction", op_freq);
206			status = P2P_SC_FAIL_NO_COMMON_CHANNELS;
207			goto fail;
208		}
209
210		if (status == P2P_SC_SUCCESS)
211			channels = &intersection;
212	} else {
213		op_freq = p2p_channel_to_freq(p2p->cfg->country,
214					      p2p->cfg->op_reg_class,
215					      p2p->cfg->op_channel);
216		if (op_freq < 0) {
217			wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG,
218				"P2P: Unknown operational channel "
219				"(country=%c%c reg_class=%u channel=%u)",
220				p2p->cfg->country[0], p2p->cfg->country[1],
221				p2p->cfg->op_reg_class, p2p->cfg->op_channel);
222			status = P2P_SC_FAIL_NO_COMMON_CHANNELS;
223			goto fail;
224		}
225
226		p2p_channels_intersect(&p2p->cfg->channels, &dev->channels,
227				       &intersection);
228		if (status == P2P_SC_SUCCESS) {
229			reg_class = p2p->cfg->op_reg_class;
230			channel = p2p->cfg->op_channel;
231			channels = &intersection;
232		}
233	}
234
235fail:
236	if (go && status == P2P_SC_SUCCESS && !is_zero_ether_addr(group_bssid))
237		bssid = group_bssid;
238	else
239		bssid = NULL;
240	resp = p2p_build_invitation_resp(p2p, dev, msg.dialog_token, status,
241					 bssid, reg_class, channel, channels);
242
243	if (resp == NULL)
244		goto out;
245
246	if (rx_freq > 0)
247		freq = rx_freq;
248	else
249		freq = p2p_channel_to_freq(p2p->cfg->country,
250					   p2p->cfg->reg_class,
251					   p2p->cfg->channel);
252	if (freq < 0) {
253		wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG,
254			"P2P: Unknown regulatory class/channel");
255		goto out;
256	}
257
258	/*
259	 * Store copy of invitation data to be used when processing TX status
260	 * callback for the Acton frame.
261	 */
262	os_memcpy(p2p->inv_sa, sa, ETH_ALEN);
263	if (msg.group_bssid) {
264		os_memcpy(p2p->inv_group_bssid, msg.group_bssid, ETH_ALEN);
265		p2p->inv_group_bssid_ptr = p2p->inv_group_bssid;
266	} else
267		p2p->inv_group_bssid_ptr = NULL;
268	if (msg.group_id_len - ETH_ALEN <= 32) {
269		os_memcpy(p2p->inv_ssid, msg.group_id + ETH_ALEN,
270			  msg.group_id_len - ETH_ALEN);
271		p2p->inv_ssid_len = msg.group_id_len - ETH_ALEN;
272	}
273	os_memcpy(p2p->inv_go_dev_addr, msg.group_id, ETH_ALEN);
274	p2p->inv_status = status;
275	p2p->inv_op_freq = op_freq;
276
277	p2p->pending_action_state = P2P_PENDING_INVITATION_RESPONSE;
278	if (p2p_send_action(p2p, freq, sa, p2p->cfg->dev_addr,
279			    p2p->cfg->dev_addr,
280			    wpabuf_head(resp), wpabuf_len(resp), 200) < 0) {
281		wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG,
282			"P2P: Failed to send Action frame");
283	}
284
285out:
286	wpabuf_free(resp);
287	p2p_parse_free(&msg);
288}
289
290
291void p2p_process_invitation_resp(struct p2p_data *p2p, const u8 *sa,
292				 const u8 *data, size_t len)
293{
294	struct p2p_device *dev;
295	struct p2p_message msg;
296
297	wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG,
298		"P2P: Received Invitation Response from " MACSTR,
299		MAC2STR(sa));
300
301	dev = p2p_get_device(p2p, sa);
302	if (dev == NULL) {
303		wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG,
304			"P2P: Ignore Invitation Response from unknown peer "
305			MACSTR, MAC2STR(sa));
306		return;
307	}
308
309	if (dev != p2p->invite_peer) {
310		wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG,
311			"P2P: Ignore unexpected Invitation Response from peer "
312			MACSTR, MAC2STR(sa));
313		return;
314	}
315
316	if (p2p_parse(data, len, &msg))
317		return;
318
319	if (!msg.status) {
320		wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG,
321			"P2P: Mandatory Status attribute missing in "
322			"Invitation Response from " MACSTR, MAC2STR(sa));
323		p2p_parse_free(&msg);
324		return;
325	}
326
327	if (p2p->cfg->invitation_result)
328		p2p->cfg->invitation_result(p2p->cfg->cb_ctx, *msg.status,
329					    msg.group_bssid);
330
331	p2p_parse_free(&msg);
332
333	p2p_clear_timeout(p2p);
334	p2p_set_state(p2p, P2P_IDLE);
335	p2p->invite_peer = NULL;
336}
337
338
339int p2p_invite_send(struct p2p_data *p2p, struct p2p_device *dev,
340		    const u8 *go_dev_addr)
341{
342	struct wpabuf *req;
343	int freq;
344
345	freq = dev->listen_freq > 0 ? dev->listen_freq : dev->oper_freq;
346	if (freq <= 0) {
347		wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG,
348			"P2P: No Listen/Operating frequency known for the "
349			"peer " MACSTR " to send Invitation Request",
350			MAC2STR(dev->info.p2p_device_addr));
351		return -1;
352	}
353
354	req = p2p_build_invitation_req(p2p, dev, go_dev_addr);
355	if (req == NULL)
356		return -1;
357	wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG,
358		"P2P: Sending Invitation Request");
359	p2p_set_state(p2p, P2P_INVITE);
360	p2p->pending_action_state = P2P_PENDING_INVITATION_REQUEST;
361	p2p->invite_peer = dev;
362	dev->invitation_reqs++;
363	if (p2p_send_action(p2p, freq, dev->info.p2p_device_addr,
364			    p2p->cfg->dev_addr, dev->info.p2p_device_addr,
365			    wpabuf_head(req), wpabuf_len(req), 200) < 0) {
366		wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG,
367			"P2P: Failed to send Action frame");
368		/* Use P2P find to recover and retry */
369		p2p_set_timeout(p2p, 0, 0);
370	}
371
372	wpabuf_free(req);
373
374	return 0;
375}
376
377
378void p2p_invitation_req_cb(struct p2p_data *p2p, int success)
379{
380	wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG,
381		"P2P: Invitation Request TX callback: success=%d", success);
382
383	if (p2p->invite_peer == NULL) {
384		wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG,
385			"P2P: No pending Invite");
386		return;
387	}
388
389	/*
390	 * Use P2P find, if needed, to find the other device from its listen
391	 * channel.
392	 */
393	p2p_set_state(p2p, P2P_INVITE);
394	p2p_set_timeout(p2p, 0, 100000);
395}
396
397
398void p2p_invitation_resp_cb(struct p2p_data *p2p, int success)
399{
400	wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG,
401		"P2P: Invitation Response TX callback: success=%d", success);
402	p2p->cfg->send_action_done(p2p->cfg->cb_ctx);
403
404	if (success && p2p->cfg->invitation_received) {
405		p2p->cfg->invitation_received(p2p->cfg->cb_ctx,
406					      p2p->inv_sa,
407					      p2p->inv_group_bssid_ptr,
408					      p2p->inv_ssid, p2p->inv_ssid_len,
409					      p2p->inv_go_dev_addr,
410					      p2p->inv_status,
411					      p2p->inv_op_freq);
412	}
413}
414
415
416int p2p_invite(struct p2p_data *p2p, const u8 *peer, enum p2p_invite_role role,
417	       const u8 *bssid, const u8 *ssid, size_t ssid_len,
418	       unsigned int force_freq, const u8 *go_dev_addr,
419	       int persistent_group)
420{
421	struct p2p_device *dev;
422
423	wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG,
424		"P2P: Request to invite peer " MACSTR " role=%d persistent=%d "
425		"force_freq=%u",
426		MAC2STR(peer), role, persistent_group, force_freq);
427	if (bssid)
428		wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG,
429			"P2P: Invitation for BSSID " MACSTR, MAC2STR(bssid));
430	if (go_dev_addr) {
431		wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG,
432			"P2P: Invitation for GO Device Address " MACSTR,
433			MAC2STR(go_dev_addr));
434		os_memcpy(p2p->invite_go_dev_addr_buf, go_dev_addr, ETH_ALEN);
435		p2p->invite_go_dev_addr = p2p->invite_go_dev_addr_buf;
436	} else
437		p2p->invite_go_dev_addr = NULL;
438	wpa_hexdump_ascii(MSG_DEBUG, "P2P: Invitation for SSID",
439			  ssid, ssid_len);
440
441	dev = p2p_get_device(p2p, peer);
442	if (dev == NULL || (dev->listen_freq <= 0 && dev->oper_freq <= 0)) {
443		wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG,
444			"P2P: Cannot invite unknown P2P Device " MACSTR,
445			MAC2STR(peer));
446		return -1;
447	}
448
449	if (dev->flags & P2P_DEV_GROUP_CLIENT_ONLY) {
450		if (!(dev->info.dev_capab &
451		      P2P_DEV_CAPAB_CLIENT_DISCOVERABILITY)) {
452			wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG,
453				"P2P: Cannot invite a P2P Device " MACSTR
454				" that is in a group and is not discoverable",
455				MAC2STR(peer));
456		}
457		/* TODO: use device discoverability request through GO */
458	}
459
460	dev->invitation_reqs = 0;
461
462	if (force_freq) {
463		if (p2p_freq_to_channel(p2p->cfg->country, force_freq,
464					&p2p->op_reg_class, &p2p->op_channel) <
465		    0) {
466			wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG,
467				"P2P: Unsupported frequency %u MHz",
468				force_freq);
469			return -1;
470		}
471		p2p->channels.reg_classes = 1;
472		p2p->channels.reg_class[0].channels = 1;
473		p2p->channels.reg_class[0].reg_class = p2p->op_reg_class;
474		p2p->channels.reg_class[0].channel[0] = p2p->op_channel;
475	} else {
476		p2p->op_reg_class = p2p->cfg->op_reg_class;
477		p2p->op_channel = p2p->cfg->op_channel;
478		os_memcpy(&p2p->channels, &p2p->cfg->channels,
479			  sizeof(struct p2p_channels));
480	}
481
482	if (p2p->state != P2P_IDLE)
483		p2p_stop_find(p2p);
484
485	p2p->inv_role = role;
486	p2p->inv_bssid_set = bssid != NULL;
487	if (bssid)
488		os_memcpy(p2p->inv_bssid, bssid, ETH_ALEN);
489	os_memcpy(p2p->inv_ssid, ssid, ssid_len);
490	p2p->inv_ssid_len = ssid_len;
491	p2p->inv_persistent = persistent_group;
492	return p2p_invite_send(p2p, dev, go_dev_addr);
493}
494