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