2 * Wi-Fi Direct - P2P Invitation procedure
3 * Copyright (c) 2010, Atheros Communications
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.
9 * Alternatively, this software may be distributed under the terms of BSD
12 * See README and COPYING for more details.
18 #include "common/ieee802_11_defs.h"
23 static struct wpabuf
* p2p_build_invitation_req(struct p2p_data
*p2p
,
24 struct p2p_device
*peer
,
25 const u8
*go_dev_addr
)
31 buf
= wpabuf_alloc(1000);
36 if (peer
->dialog_token
== 0)
37 peer
->dialog_token
= 1;
38 p2p_buf_add_public_action_hdr(buf
, P2P_INVITATION_REQ
,
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);
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
);
54 dev_addr
= go_dev_addr
;
55 else if (p2p
->inv_role
== P2P_INVITE_ROLE_CLIENT
)
56 dev_addr
= peer
->info
.p2p_device_addr
;
58 dev_addr
= p2p
->cfg
->dev_addr
;
59 p2p_buf_add_group_id(buf
, dev_addr
, p2p
->inv_ssid
, p2p
->inv_ssid_len
);
60 p2p_buf_add_device_info(buf
, p2p
, peer
);
61 p2p_buf_update_ie_hdr(buf
, len
);
67 static struct wpabuf
* p2p_build_invitation_resp(struct p2p_data
*p2p
,
68 struct p2p_device
*peer
,
69 u8 dialog_token
, u8 status
,
70 const u8
*group_bssid
,
71 u8 reg_class
, u8 channel
,
72 struct p2p_channels
*channels
)
77 buf
= wpabuf_alloc(1000);
81 p2p_buf_add_public_action_hdr(buf
, P2P_INVITATION_RESP
,
84 len
= p2p_buf_add_ie_hdr(buf
);
85 p2p_buf_add_status(buf
, status
);
86 p2p_buf_add_config_timeout(buf
, 0, 0); /* FIX */
87 if (reg_class
&& channel
)
88 p2p_buf_add_operating_channel(buf
, p2p
->cfg
->country
,
91 p2p_buf_add_group_bssid(buf
, group_bssid
);
93 p2p_buf_add_channel_list(buf
, p2p
->cfg
->country
, channels
);
94 p2p_buf_update_ie_hdr(buf
, len
);
100 void p2p_process_invitation_req(struct p2p_data
*p2p
, const u8
*sa
,
101 const u8
*data
, size_t len
, int rx_freq
)
103 struct p2p_device
*dev
;
104 struct p2p_message msg
;
105 struct wpabuf
*resp
= NULL
;
106 u8 status
= P2P_SC_FAIL_INFO_CURRENTLY_UNAVAILABLE
;
109 u8 group_bssid
[ETH_ALEN
], *bssid
;
111 u8 reg_class
= 0, channel
= 0;
112 struct p2p_channels intersection
, *channels
= NULL
;
115 os_memset(group_bssid
, 0, sizeof(group_bssid
));
117 wpa_msg(p2p
->cfg
->msg_ctx
, MSG_DEBUG
,
118 "P2P: Received Invitation Request from " MACSTR
" (freq=%d)",
119 MAC2STR(sa
), rx_freq
);
121 if (p2p_parse(data
, len
, &msg
))
124 dev
= p2p_get_device(p2p
, sa
);
125 if (dev
== NULL
|| (dev
->flags
& P2P_DEV_PROBE_REQ_ONLY
)) {
126 wpa_msg(p2p
->cfg
->msg_ctx
, MSG_DEBUG
,
127 "P2P: Invitation Request from unknown peer "
128 MACSTR
, MAC2STR(sa
));
130 if (p2p_add_device(p2p
, sa
, rx_freq
, 0, data
+ 1, len
- 1)) {
131 wpa_msg(p2p
->cfg
->msg_ctx
, MSG_DEBUG
,
132 "P2P: Invitation Request add device failed "
133 MACSTR
, MAC2STR(sa
));
134 status
= P2P_SC_FAIL_INFO_CURRENTLY_UNAVAILABLE
;
138 dev
= p2p_get_device(p2p
, sa
);
140 wpa_msg(p2p
->cfg
->msg_ctx
, MSG_DEBUG
,
141 "P2P: Reject Invitation Request from unknown "
142 "peer " MACSTR
, MAC2STR(sa
));
143 status
= P2P_SC_FAIL_INFO_CURRENTLY_UNAVAILABLE
;
148 if (!msg
.group_id
|| !msg
.channel_list
) {
149 wpa_msg(p2p
->cfg
->msg_ctx
, MSG_DEBUG
,
150 "P2P: Mandatory attribute missing in Invitation "
151 "Request from " MACSTR
, MAC2STR(sa
));
152 status
= P2P_SC_FAIL_INVALID_PARAMS
;
156 if (msg
.invitation_flags
)
157 persistent
= *msg
.invitation_flags
& P2P_INVITATION_FLAGS_TYPE
;
159 /* Invitation Flags is a mandatory attribute starting from P2P
160 * spec 1.06. As a backwards compatibility mechanism, assume
161 * the request was for a persistent group if the attribute is
164 wpa_printf(MSG_DEBUG
, "P2P: Mandatory Invitation Flags "
165 "attribute missing from Invitation Request");
169 if (p2p_peer_channels_check(p2p
, &p2p
->cfg
->channels
, dev
,
170 msg
.channel_list
, msg
.channel_list_len
) <
172 wpa_msg(p2p
->cfg
->msg_ctx
, MSG_DEBUG
,
173 "P2P: No common channels found");
174 status
= P2P_SC_FAIL_NO_COMMON_CHANNELS
;
178 if (p2p
->cfg
->invitation_process
) {
179 status
= p2p
->cfg
->invitation_process(
180 p2p
->cfg
->cb_ctx
, sa
, msg
.group_bssid
, msg
.group_id
,
181 msg
.group_id
+ ETH_ALEN
, msg
.group_id_len
- ETH_ALEN
,
182 &go
, group_bssid
, &op_freq
, persistent
);
186 if (p2p_freq_to_channel(p2p
->cfg
->country
, op_freq
,
187 ®_class
, &channel
) < 0) {
188 wpa_msg(p2p
->cfg
->msg_ctx
, MSG_DEBUG
,
189 "P2P: Unknown forced freq %d MHz from "
190 "invitation_process()", op_freq
);
191 status
= P2P_SC_FAIL_NO_COMMON_CHANNELS
;
195 p2p_channels_intersect(&p2p
->cfg
->channels
, &dev
->channels
,
197 if (!p2p_channels_includes(&intersection
, reg_class
, channel
))
199 wpa_msg(p2p
->cfg
->msg_ctx
, MSG_DEBUG
,
200 "P2P: forced freq %d MHz not in the supported "
201 "channels interaction", op_freq
);
202 status
= P2P_SC_FAIL_NO_COMMON_CHANNELS
;
206 if (status
== P2P_SC_SUCCESS
)
207 channels
= &intersection
;
209 op_freq
= p2p_channel_to_freq(p2p
->cfg
->country
,
210 p2p
->cfg
->op_reg_class
,
211 p2p
->cfg
->op_channel
);
213 wpa_msg(p2p
->cfg
->msg_ctx
, MSG_DEBUG
,
214 "P2P: Unknown operational channel "
215 "(country=%c%c reg_class=%u channel=%u)",
216 p2p
->cfg
->country
[0], p2p
->cfg
->country
[1],
217 p2p
->cfg
->op_reg_class
, p2p
->cfg
->op_channel
);
218 status
= P2P_SC_FAIL_NO_COMMON_CHANNELS
;
222 p2p_channels_intersect(&p2p
->cfg
->channels
, &dev
->channels
,
224 if (status
== P2P_SC_SUCCESS
) {
225 reg_class
= p2p
->cfg
->op_reg_class
;
226 channel
= p2p
->cfg
->op_channel
;
227 channels
= &intersection
;
232 if (go
&& status
== P2P_SC_SUCCESS
&& !is_zero_ether_addr(group_bssid
))
236 resp
= p2p_build_invitation_resp(p2p
, dev
, msg
.dialog_token
, status
,
237 bssid
, reg_class
, channel
, channels
);
245 freq
= p2p_channel_to_freq(p2p
->cfg
->country
,
249 wpa_msg(p2p
->cfg
->msg_ctx
, MSG_DEBUG
,
250 "P2P: Unknown regulatory class/channel");
255 * Store copy of invitation data to be used when processing TX status
256 * callback for the Acton frame.
258 os_memcpy(p2p
->inv_sa
, sa
, ETH_ALEN
);
259 if (msg
.group_bssid
) {
260 os_memcpy(p2p
->inv_group_bssid
, msg
.group_bssid
, ETH_ALEN
);
261 p2p
->inv_group_bssid_ptr
= p2p
->inv_group_bssid
;
263 p2p
->inv_group_bssid_ptr
= NULL
;
264 if (msg
.group_id_len
- ETH_ALEN
<= 32) {
265 os_memcpy(p2p
->inv_ssid
, msg
.group_id
+ ETH_ALEN
,
266 msg
.group_id_len
- ETH_ALEN
);
267 p2p
->inv_ssid_len
= msg
.group_id_len
- ETH_ALEN
;
269 os_memcpy(p2p
->inv_go_dev_addr
, msg
.group_id
, ETH_ALEN
);
270 p2p
->inv_status
= status
;
271 p2p
->inv_op_freq
= op_freq
;
273 p2p
->pending_action_state
= P2P_PENDING_INVITATION_RESPONSE
;
274 if (p2p_send_action(p2p
, freq
, sa
, p2p
->cfg
->dev_addr
,
276 wpabuf_head(resp
), wpabuf_len(resp
), 200) < 0) {
277 wpa_msg(p2p
->cfg
->msg_ctx
, MSG_DEBUG
,
278 "P2P: Failed to send Action frame");
283 p2p_parse_free(&msg
);
287 void p2p_process_invitation_resp(struct p2p_data
*p2p
, const u8
*sa
,
288 const u8
*data
, size_t len
)
290 struct p2p_device
*dev
;
291 struct p2p_message msg
;
293 wpa_msg(p2p
->cfg
->msg_ctx
, MSG_DEBUG
,
294 "P2P: Received Invitation Response from " MACSTR
,
297 dev
= p2p_get_device(p2p
, sa
);
299 wpa_msg(p2p
->cfg
->msg_ctx
, MSG_DEBUG
,
300 "P2P: Ignore Invitation Response from unknown peer "
301 MACSTR
, MAC2STR(sa
));
305 if (dev
!= p2p
->invite_peer
) {
306 wpa_msg(p2p
->cfg
->msg_ctx
, MSG_DEBUG
,
307 "P2P: Ignore unexpected Invitation Response from peer "
308 MACSTR
, MAC2STR(sa
));
312 if (p2p_parse(data
, len
, &msg
))
316 wpa_msg(p2p
->cfg
->msg_ctx
, MSG_DEBUG
,
317 "P2P: Mandatory Status attribute missing in "
318 "Invitation Response from " MACSTR
, MAC2STR(sa
));
319 p2p_parse_free(&msg
);
323 if (p2p
->cfg
->invitation_result
)
324 p2p
->cfg
->invitation_result(p2p
->cfg
->cb_ctx
, *msg
.status
,
327 p2p_parse_free(&msg
);
329 p2p_clear_timeout(p2p
);
330 p2p_set_state(p2p
, P2P_IDLE
);
331 p2p
->invite_peer
= NULL
;
335 int p2p_invite_send(struct p2p_data
*p2p
, struct p2p_device
*dev
,
336 const u8
*go_dev_addr
)
341 freq
= dev
->listen_freq
> 0 ? dev
->listen_freq
: dev
->oper_freq
;
343 wpa_msg(p2p
->cfg
->msg_ctx
, MSG_DEBUG
,
344 "P2P: No Listen/Operating frequency known for the "
345 "peer " MACSTR
" to send Invitation Request",
346 MAC2STR(dev
->info
.p2p_device_addr
));
350 req
= p2p_build_invitation_req(p2p
, dev
, go_dev_addr
);
353 wpa_msg(p2p
->cfg
->msg_ctx
, MSG_DEBUG
,
354 "P2P: Sending Invitation Request");
355 p2p_set_state(p2p
, P2P_INVITE
);
356 p2p
->pending_action_state
= P2P_PENDING_INVITATION_REQUEST
;
357 p2p
->invite_peer
= dev
;
358 dev
->invitation_reqs
++;
359 if (p2p_send_action(p2p
, freq
, dev
->info
.p2p_device_addr
,
360 p2p
->cfg
->dev_addr
, dev
->info
.p2p_device_addr
,
361 wpabuf_head(req
), wpabuf_len(req
), 200) < 0) {
362 wpa_msg(p2p
->cfg
->msg_ctx
, MSG_DEBUG
,
363 "P2P: Failed to send Action frame");
364 /* Use P2P find to recover and retry */
365 p2p_set_timeout(p2p
, 0, 0);
374 void p2p_invitation_req_cb(struct p2p_data
*p2p
, int success
)
376 wpa_msg(p2p
->cfg
->msg_ctx
, MSG_DEBUG
,
377 "P2P: Invitation Request TX callback: success=%d", success
);
379 if (p2p
->invite_peer
== NULL
) {
380 wpa_msg(p2p
->cfg
->msg_ctx
, MSG_DEBUG
,
381 "P2P: No pending Invite");
386 * Use P2P find, if needed, to find the other device from its listen
389 p2p_set_state(p2p
, P2P_INVITE
);
390 p2p_set_timeout(p2p
, 0, 100000);
394 void p2p_invitation_resp_cb(struct p2p_data
*p2p
, int success
)
396 wpa_msg(p2p
->cfg
->msg_ctx
, MSG_DEBUG
,
397 "P2P: Invitation Response TX callback: success=%d", success
);
398 p2p
->cfg
->send_action_done(p2p
->cfg
->cb_ctx
);
400 if (success
&& p2p
->cfg
->invitation_received
) {
401 p2p
->cfg
->invitation_received(p2p
->cfg
->cb_ctx
,
403 p2p
->inv_group_bssid_ptr
,
404 p2p
->inv_ssid
, p2p
->inv_ssid_len
,
405 p2p
->inv_go_dev_addr
,
412 int p2p_invite(struct p2p_data
*p2p
, const u8
*peer
, enum p2p_invite_role role
,
413 const u8
*bssid
, const u8
*ssid
, size_t ssid_len
,
414 unsigned int force_freq
, const u8
*go_dev_addr
,
415 int persistent_group
)
417 struct p2p_device
*dev
;
419 wpa_msg(p2p
->cfg
->msg_ctx
, MSG_DEBUG
,
420 "P2P: Request to invite peer " MACSTR
" role=%d persistent=%d "
422 MAC2STR(peer
), role
, persistent_group
, force_freq
);
424 wpa_msg(p2p
->cfg
->msg_ctx
, MSG_DEBUG
,
425 "P2P: Invitation for BSSID " MACSTR
, MAC2STR(bssid
));
427 wpa_msg(p2p
->cfg
->msg_ctx
, MSG_DEBUG
,
428 "P2P: Invitation for GO Device Address " MACSTR
,
429 MAC2STR(go_dev_addr
));
430 os_memcpy(p2p
->invite_go_dev_addr_buf
, go_dev_addr
, ETH_ALEN
);
431 p2p
->invite_go_dev_addr
= p2p
->invite_go_dev_addr_buf
;
433 p2p
->invite_go_dev_addr
= NULL
;
434 wpa_hexdump_ascii(MSG_DEBUG
, "P2P: Invitation for SSID",
437 dev
= p2p_get_device(p2p
, peer
);
438 if (dev
== NULL
|| (dev
->listen_freq
<= 0 && dev
->oper_freq
<= 0)) {
439 wpa_msg(p2p
->cfg
->msg_ctx
, MSG_DEBUG
,
440 "P2P: Cannot invite unknown P2P Device " MACSTR
,
445 if (dev
->flags
& P2P_DEV_GROUP_CLIENT_ONLY
) {
446 if (!(dev
->info
.dev_capab
&
447 P2P_DEV_CAPAB_CLIENT_DISCOVERABILITY
)) {
448 wpa_msg(p2p
->cfg
->msg_ctx
, MSG_DEBUG
,
449 "P2P: Cannot invite a P2P Device " MACSTR
450 " that is in a group and is not discoverable",
453 /* TODO: use device discoverability request through GO */
456 dev
->invitation_reqs
= 0;
459 if (p2p_freq_to_channel(p2p
->cfg
->country
, force_freq
,
460 &p2p
->op_reg_class
, &p2p
->op_channel
) <
462 wpa_msg(p2p
->cfg
->msg_ctx
, MSG_DEBUG
,
463 "P2P: Unsupported frequency %u MHz",
467 p2p
->channels
.reg_classes
= 1;
468 p2p
->channels
.reg_class
[0].channels
= 1;
469 p2p
->channels
.reg_class
[0].reg_class
= p2p
->op_reg_class
;
470 p2p
->channels
.reg_class
[0].channel
[0] = p2p
->op_channel
;
472 p2p
->op_reg_class
= p2p
->cfg
->op_reg_class
;
473 p2p
->op_channel
= p2p
->cfg
->op_channel
;
474 os_memcpy(&p2p
->channels
, &p2p
->cfg
->channels
,
475 sizeof(struct p2p_channels
));
478 if (p2p
->state
!= P2P_IDLE
)
481 p2p
->inv_role
= role
;
482 p2p
->inv_bssid_set
= bssid
!= NULL
;
484 os_memcpy(p2p
->inv_bssid
, bssid
, ETH_ALEN
);
485 os_memcpy(p2p
->inv_ssid
, ssid
, ssid_len
);
486 p2p
->inv_ssid_len
= ssid_len
;
487 p2p
->inv_persistent
= persistent_group
;
488 return p2p_invite_send(p2p
, dev
, go_dev_addr
);