blob: 68dfb8dc03b94131123c27ab125035b47c043200 [file] [log] [blame]
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07001/*
2 * Wi-Fi Direct - P2P module
3 * Copyright (c) 2009-2010, Atheros Communications
4 *
Dmitry Shmidtc5ec7f52012-03-06 16:33:24 -08005 * This software may be distributed under the terms of the BSD license.
6 * See README for more details.
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07007 */
8
9#include "includes.h"
10
11#include "common.h"
12#include "eloop.h"
13#include "common/ieee802_11_defs.h"
14#include "common/ieee802_11_common.h"
Dmitry Shmidtc5ec7f52012-03-06 16:33:24 -080015#include "common/wpa_ctrl.h"
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -070016#include "wps/wps_i.h"
17#include "p2p_i.h"
18#include "p2p.h"
19
20
21static void p2p_state_timeout(void *eloop_ctx, void *timeout_ctx);
22static void p2p_device_free(struct p2p_data *p2p, struct p2p_device *dev);
23static void p2p_process_presence_req(struct p2p_data *p2p, const u8 *da,
24 const u8 *sa, const u8 *data, size_t len,
25 int rx_freq);
26static void p2p_process_presence_resp(struct p2p_data *p2p, const u8 *da,
27 const u8 *sa, const u8 *data,
28 size_t len);
29static void p2p_ext_listen_timeout(void *eloop_ctx, void *timeout_ctx);
30static void p2p_scan_timeout(void *eloop_ctx, void *timeout_ctx);
31
32
33/*
34 * p2p_scan recovery timeout
35 *
36 * Many drivers are using 30 second timeout on scan results. Allow a bit larger
37 * timeout for this to avoid hitting P2P timeout unnecessarily.
38 */
39#define P2P_SCAN_TIMEOUT 35
40
41/**
42 * P2P_PEER_EXPIRATION_AGE - Number of seconds after which inactive peer
43 * entries will be removed
44 */
Dmitry Shmidt2fb777c2012-05-02 12:29:53 -070045#ifdef ANDROID_P2P
46#define P2P_PEER_EXPIRATION_AGE 30
47#else
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -070048#define P2P_PEER_EXPIRATION_AGE 300
Dmitry Shmidt2fb777c2012-05-02 12:29:53 -070049#endif
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -070050
51#define P2P_PEER_EXPIRATION_INTERVAL (P2P_PEER_EXPIRATION_AGE / 2)
52
Dmitry Shmidt2fb777c2012-05-02 12:29:53 -070053#ifdef ANDROID_P2P
54int p2p_connection_in_progress(struct p2p_data *p2p)
55{
56 int ret = 0;
57
58 switch (p2p->state) {
59 case P2P_CONNECT:
60 case P2P_CONNECT_LISTEN:
61 case P2P_GO_NEG:
62 case P2P_WAIT_PEER_CONNECT:
63 case P2P_PROVISIONING:
64 case P2P_INVITE:
65 case P2P_INVITE_LISTEN:
66 ret = 1;
67 break;
68
69 default:
70 ret = 0;
71 }
72
73 return ret;
74}
75#endif
76
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -070077static void p2p_expire_peers(struct p2p_data *p2p)
78{
79 struct p2p_device *dev, *n;
80 struct os_time now;
Dmitry Shmidtc5ec7f52012-03-06 16:33:24 -080081 size_t i;
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -070082
83 os_get_time(&now);
84 dl_list_for_each_safe(dev, n, &p2p->devices, struct p2p_device, list) {
85 if (dev->last_seen.sec + P2P_PEER_EXPIRATION_AGE >= now.sec)
86 continue;
Dmitry Shmidtc5ec7f52012-03-06 16:33:24 -080087
88 if (p2p->cfg->go_connected &&
89 p2p->cfg->go_connected(p2p->cfg->cb_ctx,
90 dev->info.p2p_device_addr)) {
91 /*
92 * We are connected as a client to a group in which the
93 * peer is the GO, so do not expire the peer entry.
94 */
95 os_get_time(&dev->last_seen);
96 continue;
97 }
98
99 for (i = 0; i < p2p->num_groups; i++) {
100 if (p2p_group_is_client_connected(
101 p2p->groups[i], dev->info.p2p_device_addr))
102 break;
103 }
104 if (i < p2p->num_groups) {
105 /*
106 * The peer is connected as a client in a group where
107 * we are the GO, so do not expire the peer entry.
108 */
109 os_get_time(&dev->last_seen);
110 continue;
111 }
112
Dmitry Shmidt2fb777c2012-05-02 12:29:53 -0700113#ifdef ANDROID_P2P
114 /* If Connection is in progress, don't expire the peer
115 */
116 if (p2p_connection_in_progress(p2p))
117 continue;
118#endif
119
120 wpa_msg(p2p->cfg->msg_ctx, MSG_ERROR, "P2P: Expiring old peer "
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -0700121 "entry " MACSTR, MAC2STR(dev->info.p2p_device_addr));
122 dl_list_del(&dev->list);
123 p2p_device_free(p2p, dev);
124 }
125}
126
127
128static void p2p_expiration_timeout(void *eloop_ctx, void *timeout_ctx)
129{
130 struct p2p_data *p2p = eloop_ctx;
131 p2p_expire_peers(p2p);
132 eloop_register_timeout(P2P_PEER_EXPIRATION_INTERVAL, 0,
133 p2p_expiration_timeout, p2p, NULL);
134}
135
136
137static const char * p2p_state_txt(int state)
138{
139 switch (state) {
140 case P2P_IDLE:
141 return "IDLE";
142 case P2P_SEARCH:
143 return "SEARCH";
144 case P2P_CONNECT:
145 return "CONNECT";
146 case P2P_CONNECT_LISTEN:
147 return "CONNECT_LISTEN";
148 case P2P_GO_NEG:
149 return "GO_NEG";
150 case P2P_LISTEN_ONLY:
151 return "LISTEN_ONLY";
152 case P2P_WAIT_PEER_CONNECT:
153 return "WAIT_PEER_CONNECT";
154 case P2P_WAIT_PEER_IDLE:
155 return "WAIT_PEER_IDLE";
156 case P2P_SD_DURING_FIND:
157 return "SD_DURING_FIND";
158 case P2P_PROVISIONING:
159 return "PROVISIONING";
160 case P2P_PD_DURING_FIND:
161 return "PD_DURING_FIND";
162 case P2P_INVITE:
163 return "INVITE";
164 case P2P_INVITE_LISTEN:
165 return "INVITE_LISTEN";
Dmitry Shmidt1f69aa52012-01-24 16:10:04 -0800166 case P2P_SEARCH_WHEN_READY:
167 return "SEARCH_WHEN_READY";
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -0700168 default:
169 return "?";
170 }
171}
172
173
Dmitry Shmidt1f69aa52012-01-24 16:10:04 -0800174u16 p2p_get_provisioning_info(struct p2p_data *p2p, const u8 *addr)
175{
176 struct p2p_device *dev = NULL;
177
178 if (!addr || !p2p)
179 return 0;
180
181 dev = p2p_get_device(p2p, addr);
182 if (dev)
183 return dev->wps_prov_info;
184 else
185 return 0;
186}
187
188
189void p2p_clear_provisioning_info(struct p2p_data *p2p, const u8 *iface_addr)
190{
191 struct p2p_device *dev = NULL;
192
193 if (!iface_addr || !p2p)
194 return;
195
196 dev = p2p_get_device_interface(p2p, iface_addr);
197 if (dev)
198 dev->wps_prov_info = 0;
199}
200
201
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -0700202void p2p_set_state(struct p2p_data *p2p, int new_state)
203{
204 wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG, "P2P: State %s -> %s",
205 p2p_state_txt(p2p->state), p2p_state_txt(new_state));
206 p2p->state = new_state;
207}
208
209
210void p2p_set_timeout(struct p2p_data *p2p, unsigned int sec, unsigned int usec)
211{
212 wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG,
213 "P2P: Set timeout (state=%s): %u.%06u sec",
214 p2p_state_txt(p2p->state), sec, usec);
215 eloop_cancel_timeout(p2p_state_timeout, p2p, NULL);
216 eloop_register_timeout(sec, usec, p2p_state_timeout, p2p, NULL);
217}
218
219
220void p2p_clear_timeout(struct p2p_data *p2p)
221{
222 wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG, "P2P: Clear timeout (state=%s)",
223 p2p_state_txt(p2p->state));
224 eloop_cancel_timeout(p2p_state_timeout, p2p, NULL);
225}
226
227
228void p2p_go_neg_failed(struct p2p_data *p2p, struct p2p_device *peer,
229 int status)
230{
231 struct p2p_go_neg_results res;
232 p2p_clear_timeout(p2p);
233 p2p_set_state(p2p, P2P_IDLE);
Dmitry Shmidt1f69aa52012-01-24 16:10:04 -0800234 if (p2p->go_neg_peer)
235 p2p->go_neg_peer->wps_method = WPS_NOT_READY;
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -0700236 p2p->go_neg_peer = NULL;
237
238 os_memset(&res, 0, sizeof(res));
239 res.status = status;
240 if (peer) {
241 os_memcpy(res.peer_device_addr, peer->info.p2p_device_addr,
242 ETH_ALEN);
243 os_memcpy(res.peer_interface_addr, peer->intended_addr,
244 ETH_ALEN);
245 }
246 p2p->cfg->go_neg_completed(p2p->cfg->cb_ctx, &res);
247}
248
249
250static void p2p_listen_in_find(struct p2p_data *p2p)
251{
252 unsigned int r, tu;
253 int freq;
254 struct wpabuf *ies;
255
256 wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG,
257 "P2P: Starting short listen state (state=%s)",
258 p2p_state_txt(p2p->state));
259
260 freq = p2p_channel_to_freq(p2p->cfg->country, p2p->cfg->reg_class,
261 p2p->cfg->channel);
262 if (freq < 0) {
263 wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG,
264 "P2P: Unknown regulatory class/channel");
265 return;
266 }
267
268 os_get_random((u8 *) &r, sizeof(r));
269 tu = (r % ((p2p->max_disc_int - p2p->min_disc_int) + 1) +
270 p2p->min_disc_int) * 100;
271
272 p2p->pending_listen_freq = freq;
273 p2p->pending_listen_sec = 0;
274 p2p->pending_listen_usec = 1024 * tu;
275
276 ies = p2p_build_probe_resp_ies(p2p);
277 if (ies == NULL)
278 return;
279
280 if (p2p->cfg->start_listen(p2p->cfg->cb_ctx, freq, 1024 * tu / 1000,
281 ies) < 0) {
282 wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG,
283 "P2P: Failed to start listen mode");
284 p2p->pending_listen_freq = 0;
285 }
286 wpabuf_free(ies);
287}
288
289
290int p2p_listen(struct p2p_data *p2p, unsigned int timeout)
291{
292 int freq;
293 struct wpabuf *ies;
294
295 wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG,
296 "P2P: Going to listen(only) state");
297
298 freq = p2p_channel_to_freq(p2p->cfg->country, p2p->cfg->reg_class,
299 p2p->cfg->channel);
300 if (freq < 0) {
301 wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG,
302 "P2P: Unknown regulatory class/channel");
303 return -1;
304 }
305
306 p2p->pending_listen_freq = freq;
307 p2p->pending_listen_sec = timeout / 1000;
308 p2p->pending_listen_usec = (timeout % 1000) * 1000;
309
310 if (p2p->p2p_scan_running) {
Dmitry Shmidt1f69aa52012-01-24 16:10:04 -0800311 if (p2p->start_after_scan == P2P_AFTER_SCAN_NOTHING) {
312 wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG,
313 "P2P: p2p_scan running - connect is already "
314 "pending - skip listen");
315 return 0;
316 }
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -0700317 wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG,
318 "P2P: p2p_scan running - delay start of listen state");
319 p2p->start_after_scan = P2P_AFTER_SCAN_LISTEN;
320 return 0;
321 }
322
323 ies = p2p_build_probe_resp_ies(p2p);
324 if (ies == NULL)
325 return -1;
326
327 if (p2p->cfg->start_listen(p2p->cfg->cb_ctx, freq, timeout, ies) < 0) {
328 wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG,
329 "P2P: Failed to start listen mode");
330 p2p->pending_listen_freq = 0;
331 wpabuf_free(ies);
332 return -1;
333 }
334 wpabuf_free(ies);
335
336 p2p_set_state(p2p, P2P_LISTEN_ONLY);
337
338 return 0;
339}
340
341
342static void p2p_device_clear_reported(struct p2p_data *p2p)
343{
344 struct p2p_device *dev;
345 dl_list_for_each(dev, &p2p->devices, struct p2p_device, list)
346 dev->flags &= ~P2P_DEV_REPORTED;
347}
348
349
350/**
351 * p2p_get_device - Fetch a peer entry
352 * @p2p: P2P module context from p2p_init()
353 * @addr: P2P Device Address of the peer
354 * Returns: Pointer to the device entry or %NULL if not found
355 */
356struct p2p_device * p2p_get_device(struct p2p_data *p2p, const u8 *addr)
357{
358 struct p2p_device *dev;
359 dl_list_for_each(dev, &p2p->devices, struct p2p_device, list) {
360 if (os_memcmp(dev->info.p2p_device_addr, addr, ETH_ALEN) == 0)
361 return dev;
362 }
363 return NULL;
364}
365
366
367/**
368 * p2p_get_device_interface - Fetch a peer entry based on P2P Interface Address
369 * @p2p: P2P module context from p2p_init()
370 * @addr: P2P Interface Address of the peer
371 * Returns: Pointer to the device entry or %NULL if not found
372 */
373struct p2p_device * p2p_get_device_interface(struct p2p_data *p2p,
374 const u8 *addr)
375{
376 struct p2p_device *dev;
377 dl_list_for_each(dev, &p2p->devices, struct p2p_device, list) {
378 if (os_memcmp(dev->interface_addr, addr, ETH_ALEN) == 0)
379 return dev;
380 }
381 return NULL;
382}
383
384
385/**
386 * p2p_create_device - Create a peer entry
387 * @p2p: P2P module context from p2p_init()
388 * @addr: P2P Device Address of the peer
389 * Returns: Pointer to the device entry or %NULL on failure
390 *
391 * If there is already an entry for the peer, it will be returned instead of
392 * creating a new one.
393 */
394static struct p2p_device * p2p_create_device(struct p2p_data *p2p,
395 const u8 *addr)
396{
397 struct p2p_device *dev, *oldest = NULL;
398 size_t count = 0;
399
400 dev = p2p_get_device(p2p, addr);
401 if (dev)
402 return dev;
403
404 dl_list_for_each(dev, &p2p->devices, struct p2p_device, list) {
405 count++;
406 if (oldest == NULL ||
407 os_time_before(&dev->last_seen, &oldest->last_seen))
408 oldest = dev;
409 }
410 if (count + 1 > p2p->cfg->max_peers && oldest) {
411 wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG,
412 "P2P: Remove oldest peer entry to make room for a new "
413 "peer");
414 dl_list_del(&oldest->list);
415 p2p_device_free(p2p, oldest);
416 }
417
418 dev = os_zalloc(sizeof(*dev));
419 if (dev == NULL)
420 return NULL;
421 dl_list_add(&p2p->devices, &dev->list);
422 os_memcpy(dev->info.p2p_device_addr, addr, ETH_ALEN);
423
424 return dev;
425}
426
427
428static void p2p_copy_client_info(struct p2p_device *dev,
429 struct p2p_client_info *cli)
430{
431 os_memcpy(dev->info.device_name, cli->dev_name, cli->dev_name_len);
432 dev->info.device_name[cli->dev_name_len] = '\0';
433 dev->info.dev_capab = cli->dev_capab;
434 dev->info.config_methods = cli->config_methods;
435 os_memcpy(dev->info.pri_dev_type, cli->pri_dev_type, 8);
436 dev->info.wps_sec_dev_type_list_len = 8 * cli->num_sec_dev_types;
437 os_memcpy(dev->info.wps_sec_dev_type_list, cli->sec_dev_types,
438 dev->info.wps_sec_dev_type_list_len);
439}
440
441
442static int p2p_add_group_clients(struct p2p_data *p2p, const u8 *go_dev_addr,
443 const u8 *go_interface_addr, int freq,
444 const u8 *gi, size_t gi_len)
445{
446 struct p2p_group_info info;
447 size_t c;
448 struct p2p_device *dev;
449
450 if (gi == NULL)
451 return 0;
452
453 if (p2p_group_info_parse(gi, gi_len, &info) < 0)
454 return -1;
455
456 /*
457 * Clear old data for this group; if the devices are still in the
458 * group, the information will be restored in the loop following this.
459 */
460 dl_list_for_each(dev, &p2p->devices, struct p2p_device, list) {
Dmitry Shmidt1f69aa52012-01-24 16:10:04 -0800461 if (os_memcmp(dev->member_in_go_iface, go_interface_addr,
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -0700462 ETH_ALEN) == 0) {
463 os_memset(dev->member_in_go_iface, 0, ETH_ALEN);
464 os_memset(dev->member_in_go_dev, 0, ETH_ALEN);
465 }
466 }
467
468 for (c = 0; c < info.num_clients; c++) {
469 struct p2p_client_info *cli = &info.client[c];
Dmitry Shmidt1f69aa52012-01-24 16:10:04 -0800470 if (os_memcmp(cli->p2p_device_addr, p2p->cfg->dev_addr,
471 ETH_ALEN) == 0)
472 continue; /* ignore our own entry */
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -0700473 dev = p2p_get_device(p2p, cli->p2p_device_addr);
474 if (dev) {
475 /*
476 * Update information only if we have not received this
477 * directly from the client.
478 */
479 if (dev->flags & (P2P_DEV_GROUP_CLIENT_ONLY |
480 P2P_DEV_PROBE_REQ_ONLY))
481 p2p_copy_client_info(dev, cli);
482 if (dev->flags & P2P_DEV_PROBE_REQ_ONLY) {
483 dev->flags &= ~P2P_DEV_PROBE_REQ_ONLY;
484 }
485 } else {
486 dev = p2p_create_device(p2p, cli->p2p_device_addr);
487 if (dev == NULL)
488 continue;
489 dev->flags |= P2P_DEV_GROUP_CLIENT_ONLY;
490 p2p_copy_client_info(dev, cli);
491 dev->oper_freq = freq;
492 p2p->cfg->dev_found(p2p->cfg->cb_ctx,
493 dev->info.p2p_device_addr,
494 &dev->info, 1);
495 dev->flags |= P2P_DEV_REPORTED | P2P_DEV_REPORTED_ONCE;
496 }
497
498 os_memcpy(dev->interface_addr, cli->p2p_interface_addr,
499 ETH_ALEN);
500 os_get_time(&dev->last_seen);
501 os_memcpy(dev->member_in_go_dev, go_dev_addr, ETH_ALEN);
502 os_memcpy(dev->member_in_go_iface, go_interface_addr,
503 ETH_ALEN);
504 }
505
506 return 0;
507}
508
509
510static void p2p_copy_wps_info(struct p2p_device *dev, int probe_req,
511 const struct p2p_message *msg)
512{
513 os_memcpy(dev->info.device_name, msg->device_name,
514 sizeof(dev->info.device_name));
515
516 if (msg->manufacturer &&
517 msg->manufacturer_len < sizeof(dev->info.manufacturer)) {
518 os_memset(dev->info.manufacturer, 0,
519 sizeof(dev->info.manufacturer));
520 os_memcpy(dev->info.manufacturer, msg->manufacturer,
521 msg->manufacturer_len);
522 }
523
524 if (msg->model_name &&
525 msg->model_name_len < sizeof(dev->info.model_name)) {
526 os_memset(dev->info.model_name, 0,
527 sizeof(dev->info.model_name));
528 os_memcpy(dev->info.model_name, msg->model_name,
529 msg->model_name_len);
530 }
531
532 if (msg->model_number &&
533 msg->model_number_len < sizeof(dev->info.model_number)) {
534 os_memset(dev->info.model_number, 0,
535 sizeof(dev->info.model_number));
536 os_memcpy(dev->info.model_number, msg->model_number,
537 msg->model_number_len);
538 }
539
540 if (msg->serial_number &&
541 msg->serial_number_len < sizeof(dev->info.serial_number)) {
542 os_memset(dev->info.serial_number, 0,
543 sizeof(dev->info.serial_number));
544 os_memcpy(dev->info.serial_number, msg->serial_number,
545 msg->serial_number_len);
546 }
547
548 if (msg->pri_dev_type)
549 os_memcpy(dev->info.pri_dev_type, msg->pri_dev_type,
550 sizeof(dev->info.pri_dev_type));
551 else if (msg->wps_pri_dev_type)
552 os_memcpy(dev->info.pri_dev_type, msg->wps_pri_dev_type,
553 sizeof(dev->info.pri_dev_type));
554
555 if (msg->wps_sec_dev_type_list) {
556 os_memcpy(dev->info.wps_sec_dev_type_list,
557 msg->wps_sec_dev_type_list,
558 msg->wps_sec_dev_type_list_len);
559 dev->info.wps_sec_dev_type_list_len =
560 msg->wps_sec_dev_type_list_len;
561 }
562
563 if (msg->capability) {
564 dev->info.dev_capab = msg->capability[0];
565 dev->info.group_capab = msg->capability[1];
566 }
567
568 if (msg->ext_listen_timing) {
569 dev->ext_listen_period = WPA_GET_LE16(msg->ext_listen_timing);
570 dev->ext_listen_interval =
571 WPA_GET_LE16(msg->ext_listen_timing + 2);
572 }
573
574 if (!probe_req) {
575 dev->info.config_methods = msg->config_methods ?
576 msg->config_methods : msg->wps_config_methods;
577 }
578}
579
580
581/**
582 * p2p_add_device - Add peer entries based on scan results
583 * @p2p: P2P module context from p2p_init()
584 * @addr: Source address of Beacon or Probe Response frame (may be either
585 * P2P Device Address or P2P Interface Address)
586 * @level: Signal level (signal strength of the received frame from the peer)
587 * @freq: Frequency on which the Beacon or Probe Response frame was received
588 * @ies: IEs from the Beacon or Probe Response frame
589 * @ies_len: Length of ies buffer in octets
590 * Returns: 0 on success, -1 on failure
591 *
592 * If the scan result is for a GO, the clients in the group will also be added
593 * to the peer table. This function can also be used with some other frames
594 * like Provision Discovery Request that contains P2P Capability and P2P Device
595 * Info attributes.
596 */
597int p2p_add_device(struct p2p_data *p2p, const u8 *addr, int freq, int level,
598 const u8 *ies, size_t ies_len)
599{
600 struct p2p_device *dev;
601 struct p2p_message msg;
602 const u8 *p2p_dev_addr;
603 int i;
604
605 os_memset(&msg, 0, sizeof(msg));
606 if (p2p_parse_ies(ies, ies_len, &msg)) {
607 wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG,
608 "P2P: Failed to parse P2P IE for a device entry");
609 p2p_parse_free(&msg);
610 return -1;
611 }
612
613 if (msg.p2p_device_addr)
614 p2p_dev_addr = msg.p2p_device_addr;
615 else if (msg.device_id)
616 p2p_dev_addr = msg.device_id;
617 else {
618 wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG,
619 "P2P: Ignore scan data without P2P Device Info or "
620 "P2P Device Id");
621 p2p_parse_free(&msg);
622 return -1;
623 }
624
625 if (!is_zero_ether_addr(p2p->peer_filter) &&
626 os_memcmp(p2p_dev_addr, p2p->peer_filter, ETH_ALEN) != 0) {
627 wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG, "P2P: Do not add peer "
628 "filter for " MACSTR " due to peer filter",
629 MAC2STR(p2p_dev_addr));
630 return 0;
631 }
632
633 dev = p2p_create_device(p2p, p2p_dev_addr);
634 if (dev == NULL) {
635 p2p_parse_free(&msg);
636 return -1;
637 }
638 os_get_time(&dev->last_seen);
639 dev->flags &= ~(P2P_DEV_PROBE_REQ_ONLY | P2P_DEV_GROUP_CLIENT_ONLY);
640
641 if (os_memcmp(addr, p2p_dev_addr, ETH_ALEN) != 0)
642 os_memcpy(dev->interface_addr, addr, ETH_ALEN);
643 if (msg.ssid &&
644 (msg.ssid[1] != P2P_WILDCARD_SSID_LEN ||
645 os_memcmp(msg.ssid + 2, P2P_WILDCARD_SSID, P2P_WILDCARD_SSID_LEN)
646 != 0)) {
647 os_memcpy(dev->oper_ssid, msg.ssid + 2, msg.ssid[1]);
648 dev->oper_ssid_len = msg.ssid[1];
649 }
650
651 if (freq >= 2412 && freq <= 2484 && msg.ds_params &&
652 *msg.ds_params >= 1 && *msg.ds_params <= 14) {
653 int ds_freq;
654 if (*msg.ds_params == 14)
655 ds_freq = 2484;
656 else
657 ds_freq = 2407 + *msg.ds_params * 5;
658 if (freq != ds_freq) {
659 wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG,
660 "P2P: Update Listen frequency based on DS "
661 "Parameter Set IE: %d -> %d MHz",
662 freq, ds_freq);
663 freq = ds_freq;
664 }
665 }
666
667 if (dev->listen_freq && dev->listen_freq != freq) {
668 wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG,
669 "P2P: Update Listen frequency based on scan "
670 "results (" MACSTR " %d -> %d MHz (DS param %d)",
671 MAC2STR(dev->info.p2p_device_addr), dev->listen_freq,
672 freq, msg.ds_params ? *msg.ds_params : -1);
673 }
674 dev->listen_freq = freq;
675 if (msg.group_info)
676 dev->oper_freq = freq;
Jouni Malinen75ecf522011-06-27 15:19:46 -0700677 dev->info.level = level;
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -0700678
679 p2p_copy_wps_info(dev, 0, &msg);
680
681 for (i = 0; i < P2P_MAX_WPS_VENDOR_EXT; i++) {
682 wpabuf_free(dev->info.wps_vendor_ext[i]);
683 dev->info.wps_vendor_ext[i] = NULL;
684 }
685
686 for (i = 0; i < P2P_MAX_WPS_VENDOR_EXT; i++) {
687 if (msg.wps_vendor_ext[i] == NULL)
688 break;
689 dev->info.wps_vendor_ext[i] = wpabuf_alloc_copy(
690 msg.wps_vendor_ext[i], msg.wps_vendor_ext_len[i]);
691 if (dev->info.wps_vendor_ext[i] == NULL)
692 break;
693 }
694
695 p2p_add_group_clients(p2p, p2p_dev_addr, addr, freq, msg.group_info,
696 msg.group_info_len);
697
698 p2p_parse_free(&msg);
699
700 if (p2p_pending_sd_req(p2p, dev))
701 dev->flags |= P2P_DEV_SD_SCHEDULE;
702
703 if (dev->flags & P2P_DEV_REPORTED)
704 return 0;
705
706 wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG,
707 "P2P: Peer found with Listen frequency %d MHz", freq);
708 if (dev->flags & P2P_DEV_USER_REJECTED) {
709 wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG,
710 "P2P: Do not report rejected device");
711 return 0;
712 }
713
714 p2p->cfg->dev_found(p2p->cfg->cb_ctx, addr, &dev->info,
715 !(dev->flags & P2P_DEV_REPORTED_ONCE));
716 dev->flags |= P2P_DEV_REPORTED | P2P_DEV_REPORTED_ONCE;
717
718 return 0;
719}
720
721
722static void p2p_device_free(struct p2p_data *p2p, struct p2p_device *dev)
723{
724 int i;
725
Dmitry Shmidt497c1d52011-07-21 15:19:46 -0700726 if (p2p->go_neg_peer == dev) {
Dmitry Shmidt1f69aa52012-01-24 16:10:04 -0800727 /*
728 * If GO Negotiation is in progress, report that it has failed.
729 */
Dmitry Shmidt497c1d52011-07-21 15:19:46 -0700730 p2p_go_neg_failed(p2p, dev, -1);
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -0700731 p2p->go_neg_peer = NULL;
Dmitry Shmidt497c1d52011-07-21 15:19:46 -0700732 }
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -0700733 if (p2p->invite_peer == dev)
734 p2p->invite_peer = NULL;
735 if (p2p->sd_peer == dev)
736 p2p->sd_peer = NULL;
737 if (p2p->pending_client_disc_go == dev)
738 p2p->pending_client_disc_go = NULL;
739
Dmitry Shmidtc55524a2011-07-07 11:18:38 -0700740 /* dev_lost() device, but only if it was previously dev_found() */
741 if (dev->flags & P2P_DEV_REPORTED_ONCE)
742 p2p->cfg->dev_lost(p2p->cfg->cb_ctx,
743 dev->info.p2p_device_addr);
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -0700744
745 for (i = 0; i < P2P_MAX_WPS_VENDOR_EXT; i++) {
746 wpabuf_free(dev->info.wps_vendor_ext[i]);
747 dev->info.wps_vendor_ext[i] = NULL;
748 }
749
750 os_free(dev);
751}
752
753
754static int p2p_get_next_prog_freq(struct p2p_data *p2p)
755{
756 struct p2p_channels *c;
757 struct p2p_reg_class *cla;
758 size_t cl, ch;
759 int found = 0;
760 u8 reg_class;
761 u8 channel;
762 int freq;
763
764 c = &p2p->cfg->channels;
765 for (cl = 0; cl < c->reg_classes; cl++) {
766 cla = &c->reg_class[cl];
767 if (cla->reg_class != p2p->last_prog_scan_class)
768 continue;
769 for (ch = 0; ch < cla->channels; ch++) {
770 if (cla->channel[ch] == p2p->last_prog_scan_chan) {
771 found = 1;
772 break;
773 }
774 }
775 if (found)
776 break;
777 }
778
779 if (!found) {
780 /* Start from beginning */
781 reg_class = c->reg_class[0].reg_class;
782 channel = c->reg_class[0].channel[0];
783 } else {
784 /* Pick the next channel */
785 ch++;
786 if (ch == cla->channels) {
787 cl++;
788 if (cl == c->reg_classes)
789 cl = 0;
790 ch = 0;
791 }
792 reg_class = c->reg_class[cl].reg_class;
793 channel = c->reg_class[cl].channel[ch];
794 }
795
796 freq = p2p_channel_to_freq(p2p->cfg->country, reg_class, channel);
797 wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG, "P2P: Next progressive search "
798 "channel: reg_class %u channel %u -> %d MHz",
799 reg_class, channel, freq);
800 p2p->last_prog_scan_class = reg_class;
801 p2p->last_prog_scan_chan = channel;
802
803 if (freq == 2412 || freq == 2437 || freq == 2462)
804 return 0; /* No need to add social channels */
805 return freq;
806}
807
808
809static void p2p_search(struct p2p_data *p2p)
810{
811 int freq = 0;
812 enum p2p_scan_type type;
813
814 if (p2p->drv_in_listen) {
815 wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG, "P2P: Driver is still "
816 "in Listen state - wait for it to end before "
817 "continuing");
818 return;
819 }
820 p2p->cfg->stop_listen(p2p->cfg->cb_ctx);
821
822 if (p2p->go_neg_peer) {
823 /*
824 * Only scan the known listen frequency of the peer
825 * during GO Negotiation start.
826 */
827 freq = p2p->go_neg_peer->listen_freq;
828 if (freq <= 0)
829 freq = p2p->go_neg_peer->oper_freq;
830 type = P2P_SCAN_SPECIFIC;
831 wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG, "P2P: Starting search "
832 "for freq %u (GO Neg)", freq);
833 } else if (p2p->invite_peer) {
834 /*
835 * Only scan the known listen frequency of the peer
836 * during Invite start.
837 */
838 freq = p2p->invite_peer->listen_freq;
839 if (freq <= 0)
840 freq = p2p->invite_peer->oper_freq;
841 type = P2P_SCAN_SPECIFIC;
842 wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG, "P2P: Starting search "
843 "for freq %u (Invite)", freq);
844 } else if (p2p->find_type == P2P_FIND_PROGRESSIVE &&
845 (freq = p2p_get_next_prog_freq(p2p)) > 0) {
846 type = P2P_SCAN_SOCIAL_PLUS_ONE;
847 wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG, "P2P: Starting search "
848 "(+ freq %u)", freq);
849 } else {
850 type = P2P_SCAN_SOCIAL;
851 wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG, "P2P: Starting search");
852 }
853
854 if (p2p->cfg->p2p_scan(p2p->cfg->cb_ctx, type, freq,
Dmitry Shmidtc5ec7f52012-03-06 16:33:24 -0800855 p2p->num_req_dev_types, p2p->req_dev_types,
856 p2p->find_dev_id)) {
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -0700857 wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG,
858 "P2P: Scan request failed");
859 p2p_continue_find(p2p);
860 } else {
861 wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG, "P2P: Running p2p_scan");
862 p2p->p2p_scan_running = 1;
863 eloop_cancel_timeout(p2p_scan_timeout, p2p, NULL);
864 eloop_register_timeout(P2P_SCAN_TIMEOUT, 0, p2p_scan_timeout,
865 p2p, NULL);
866 }
867}
868
869
870static void p2p_find_timeout(void *eloop_ctx, void *timeout_ctx)
871{
872 struct p2p_data *p2p = eloop_ctx;
873 wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG, "P2P: Find timeout -> stop");
874 p2p_stop_find(p2p);
875}
876
877
878static int p2p_run_after_scan(struct p2p_data *p2p)
879{
880 struct p2p_device *dev;
881 enum p2p_after_scan op;
882
883 if (p2p->after_scan_tx) {
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -0700884 /* TODO: schedule p2p_run_after_scan to be called from TX
885 * status callback(?) */
886 wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG, "P2P: Send pending "
887 "Action frame at p2p_scan completion");
Dmitry Shmidt1f69aa52012-01-24 16:10:04 -0800888 p2p->cfg->send_action(p2p->cfg->cb_ctx,
889 p2p->after_scan_tx->freq,
890 p2p->after_scan_tx->dst,
891 p2p->after_scan_tx->src,
892 p2p->after_scan_tx->bssid,
893 (u8 *) (p2p->after_scan_tx + 1),
894 p2p->after_scan_tx->len,
895 p2p->after_scan_tx->wait_time);
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -0700896 os_free(p2p->after_scan_tx);
897 p2p->after_scan_tx = NULL;
898 return 1;
899 }
900
901 op = p2p->start_after_scan;
902 p2p->start_after_scan = P2P_AFTER_SCAN_NOTHING;
903 switch (op) {
904 case P2P_AFTER_SCAN_NOTHING:
905 break;
906 case P2P_AFTER_SCAN_LISTEN:
907 wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG, "P2P: Start previously "
908 "requested Listen state");
909 p2p_listen(p2p, p2p->pending_listen_sec * 1000 +
910 p2p->pending_listen_usec / 1000);
911 return 1;
912 case P2P_AFTER_SCAN_CONNECT:
913 wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG, "P2P: Start previously "
914 "requested connect with " MACSTR,
915 MAC2STR(p2p->after_scan_peer));
916 dev = p2p_get_device(p2p, p2p->after_scan_peer);
917 if (dev == NULL) {
918 wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG, "P2P: Peer not "
919 "known anymore");
920 break;
921 }
922 p2p_connect_send(p2p, dev);
923 return 1;
924 }
925
926 return 0;
927}
928
929
930static void p2p_scan_timeout(void *eloop_ctx, void *timeout_ctx)
931{
932 struct p2p_data *p2p = eloop_ctx;
933 int running;
934 wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG, "P2P: p2p_scan timeout "
935 "(running=%d)", p2p->p2p_scan_running);
936 running = p2p->p2p_scan_running;
937 /* Make sure we recover from missed scan results callback */
938 p2p->p2p_scan_running = 0;
939
940 if (running)
941 p2p_run_after_scan(p2p);
942}
943
944
945static void p2p_free_req_dev_types(struct p2p_data *p2p)
946{
947 p2p->num_req_dev_types = 0;
948 os_free(p2p->req_dev_types);
949 p2p->req_dev_types = NULL;
950}
951
952
953int p2p_find(struct p2p_data *p2p, unsigned int timeout,
954 enum p2p_discovery_type type,
Dmitry Shmidtc5ec7f52012-03-06 16:33:24 -0800955 unsigned int num_req_dev_types, const u8 *req_dev_types,
956 const u8 *dev_id)
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -0700957{
958 int res;
959
960 wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG, "P2P: Starting find (type=%d)",
961 type);
962 if (p2p->p2p_scan_running) {
963 wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG, "P2P: p2p_scan is "
964 "already running");
965 }
966
967 p2p_free_req_dev_types(p2p);
968 if (req_dev_types && num_req_dev_types) {
969 p2p->req_dev_types = os_malloc(num_req_dev_types *
970 WPS_DEV_TYPE_LEN);
971 if (p2p->req_dev_types == NULL)
972 return -1;
973 os_memcpy(p2p->req_dev_types, req_dev_types,
974 num_req_dev_types * WPS_DEV_TYPE_LEN);
975 p2p->num_req_dev_types = num_req_dev_types;
976 }
977
Dmitry Shmidtc5ec7f52012-03-06 16:33:24 -0800978 if (dev_id) {
979 os_memcpy(p2p->find_dev_id_buf, dev_id, ETH_ALEN);
980 p2p->find_dev_id = p2p->find_dev_id_buf;
981 } else
982 p2p->find_dev_id = NULL;
983
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -0700984 p2p->start_after_scan = P2P_AFTER_SCAN_NOTHING;
985 p2p_clear_timeout(p2p);
986 p2p->cfg->stop_listen(p2p->cfg->cb_ctx);
987 p2p->find_type = type;
988 p2p_device_clear_reported(p2p);
989 p2p_set_state(p2p, P2P_SEARCH);
990 eloop_cancel_timeout(p2p_find_timeout, p2p, NULL);
Dmitry Shmidt1f69aa52012-01-24 16:10:04 -0800991 p2p->last_p2p_find_timeout = timeout;
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -0700992 if (timeout)
993 eloop_register_timeout(timeout, 0, p2p_find_timeout,
994 p2p, NULL);
995 switch (type) {
996 case P2P_FIND_START_WITH_FULL:
997 case P2P_FIND_PROGRESSIVE:
998 res = p2p->cfg->p2p_scan(p2p->cfg->cb_ctx, P2P_SCAN_FULL, 0,
999 p2p->num_req_dev_types,
Dmitry Shmidtc5ec7f52012-03-06 16:33:24 -08001000 p2p->req_dev_types, dev_id);
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07001001 break;
1002 case P2P_FIND_ONLY_SOCIAL:
1003 res = p2p->cfg->p2p_scan(p2p->cfg->cb_ctx, P2P_SCAN_SOCIAL, 0,
1004 p2p->num_req_dev_types,
Dmitry Shmidtc5ec7f52012-03-06 16:33:24 -08001005 p2p->req_dev_types, dev_id);
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07001006 break;
1007 default:
1008 return -1;
1009 }
1010
1011 if (res == 0) {
1012 wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG, "P2P: Running p2p_scan");
1013 p2p->p2p_scan_running = 1;
1014 eloop_cancel_timeout(p2p_scan_timeout, p2p, NULL);
1015 eloop_register_timeout(P2P_SCAN_TIMEOUT, 0, p2p_scan_timeout,
1016 p2p, NULL);
Dmitry Shmidt1f69aa52012-01-24 16:10:04 -08001017 } else if (res == 1) {
1018 wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG, "P2P: Could not start "
1019 "p2p_scan at this point - will try again after "
1020 "previous scan completes");
1021 res = 0;
1022 p2p_set_state(p2p, P2P_SEARCH_WHEN_READY);
1023 eloop_cancel_timeout(p2p_find_timeout, p2p, NULL);
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07001024 } else {
1025 wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG, "P2P: Failed to start "
1026 "p2p_scan");
Dmitry Shmidt1f69aa52012-01-24 16:10:04 -08001027 p2p_set_state(p2p, P2P_IDLE);
1028 eloop_cancel_timeout(p2p_find_timeout, p2p, NULL);
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07001029 }
1030
1031 return res;
1032}
1033
Dmitry Shmidt2fb777c2012-05-02 12:29:53 -07001034#ifdef ANDROID_P2P
1035int p2p_search_pending(struct p2p_data *p2p)
1036{
1037 if(p2p == NULL)
1038 return 0;
1039
1040 if(p2p->state == P2P_SEARCH_WHEN_READY)
1041 return 1;
1042
1043 return 0;
1044}
1045#endif
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07001046
Dmitry Shmidt1f69aa52012-01-24 16:10:04 -08001047int p2p_other_scan_completed(struct p2p_data *p2p)
1048{
1049 if (p2p->state != P2P_SEARCH_WHEN_READY)
1050 return 0;
1051 wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG, "P2P: Starting pending P2P find "
1052 "now that previous scan was completed");
1053 if (p2p_find(p2p, p2p->last_p2p_find_timeout, p2p->find_type,
Dmitry Shmidtc5ec7f52012-03-06 16:33:24 -08001054 p2p->num_req_dev_types, p2p->req_dev_types,
1055 p2p->find_dev_id) < 0)
Dmitry Shmidt1f69aa52012-01-24 16:10:04 -08001056 return 0;
1057 return 1;
1058}
1059
1060
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07001061void p2p_stop_find_for_freq(struct p2p_data *p2p, int freq)
1062{
1063 wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG, "P2P: Stopping find");
1064 eloop_cancel_timeout(p2p_find_timeout, p2p, NULL);
1065 p2p_clear_timeout(p2p);
Dmitry Shmidtc5ec7f52012-03-06 16:33:24 -08001066 if (p2p->state == P2P_SEARCH)
1067 wpa_msg(p2p->cfg->msg_ctx, MSG_INFO, P2P_EVENT_FIND_STOPPED);
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07001068 p2p_set_state(p2p, P2P_IDLE);
1069 p2p_free_req_dev_types(p2p);
1070 p2p->start_after_scan = P2P_AFTER_SCAN_NOTHING;
1071 p2p->go_neg_peer = NULL;
1072 p2p->sd_peer = NULL;
1073 p2p->invite_peer = NULL;
1074 if (freq > 0 && p2p->drv_in_listen == freq && p2p->in_listen) {
1075 wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG, "P2P: Skip stop_listen "
1076 "since we are on correct channel for response");
1077 return;
1078 }
Dmitry Shmidt1f69aa52012-01-24 16:10:04 -08001079 if (p2p->drv_in_listen) {
1080 /*
1081 * The driver may not deliver callback to p2p_listen_end()
1082 * when the operation gets canceled, so clear the internal
1083 * variable that is tracking driver state.
1084 */
1085 wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG, "P2P: Clear "
1086 "drv_in_listen (%d)", p2p->drv_in_listen);
1087 p2p->drv_in_listen = 0;
1088 }
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07001089 p2p->cfg->stop_listen(p2p->cfg->cb_ctx);
1090}
1091
1092
1093void p2p_stop_find(struct p2p_data *p2p)
1094{
1095 p2p_stop_find_for_freq(p2p, 0);
1096}
1097
1098
1099static int p2p_prepare_channel(struct p2p_data *p2p, unsigned int force_freq)
1100{
1101 if (force_freq) {
1102 u8 op_reg_class, op_channel;
1103 if (p2p_freq_to_channel(p2p->cfg->country, force_freq,
1104 &op_reg_class, &op_channel) < 0) {
1105 wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG,
1106 "P2P: Unsupported frequency %u MHz",
1107 force_freq);
1108 return -1;
1109 }
1110 if (!p2p_channels_includes(&p2p->cfg->channels, op_reg_class,
1111 op_channel)) {
1112 wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG,
1113 "P2P: Frequency %u MHz (oper_class %u "
1114 "channel %u) not allowed for P2P",
1115 force_freq, op_reg_class, op_channel);
1116 return -1;
1117 }
1118 p2p->op_reg_class = op_reg_class;
1119 p2p->op_channel = op_channel;
1120 p2p->channels.reg_classes = 1;
1121 p2p->channels.reg_class[0].channels = 1;
1122 p2p->channels.reg_class[0].reg_class = p2p->op_reg_class;
1123 p2p->channels.reg_class[0].channel[0] = p2p->op_channel;
1124 } else {
1125 u8 op_reg_class, op_channel;
1126
1127 if (!p2p->cfg->cfg_op_channel && p2p->best_freq_overall > 0 &&
1128 p2p_supported_freq(p2p, p2p->best_freq_overall) &&
1129 p2p_freq_to_channel(p2p->cfg->country,
1130 p2p->best_freq_overall,
1131 &op_reg_class, &op_channel) == 0) {
1132 wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG,
1133 "P2P: Select best overall channel as "
1134 "operating channel preference");
1135 p2p->op_reg_class = op_reg_class;
1136 p2p->op_channel = op_channel;
1137 } else if (!p2p->cfg->cfg_op_channel && p2p->best_freq_5 > 0 &&
1138 p2p_supported_freq(p2p, p2p->best_freq_5) &&
1139 p2p_freq_to_channel(p2p->cfg->country,
1140 p2p->best_freq_5,
1141 &op_reg_class, &op_channel) ==
1142 0) {
1143 wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG,
1144 "P2P: Select best 5 GHz channel as "
1145 "operating channel preference");
1146 p2p->op_reg_class = op_reg_class;
1147 p2p->op_channel = op_channel;
1148 } else if (!p2p->cfg->cfg_op_channel &&
1149 p2p->best_freq_24 > 0 &&
1150 p2p_supported_freq(p2p, p2p->best_freq_24) &&
1151 p2p_freq_to_channel(p2p->cfg->country,
1152 p2p->best_freq_24,
1153 &op_reg_class, &op_channel) ==
1154 0) {
1155 wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG,
1156 "P2P: Select best 2.4 GHz channel as "
1157 "operating channel preference");
1158 p2p->op_reg_class = op_reg_class;
1159 p2p->op_channel = op_channel;
1160 } else {
1161 p2p->op_reg_class = p2p->cfg->op_reg_class;
1162 p2p->op_channel = p2p->cfg->op_channel;
1163 }
1164
1165 os_memcpy(&p2p->channels, &p2p->cfg->channels,
1166 sizeof(struct p2p_channels));
1167 }
1168 wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG,
1169 "P2P: Own preference for operation channel: "
1170 "Operating Class %u Channel %u%s",
1171 p2p->op_reg_class, p2p->op_channel,
1172 force_freq ? " (forced)" : "");
1173
1174 return 0;
1175}
1176
1177
Dmitry Shmidt1f69aa52012-01-24 16:10:04 -08001178static void p2p_set_dev_persistent(struct p2p_device *dev,
1179 int persistent_group)
1180{
1181 switch (persistent_group) {
1182 case 0:
1183 dev->flags &= ~(P2P_DEV_PREFER_PERSISTENT_GROUP |
1184 P2P_DEV_PREFER_PERSISTENT_RECONN);
1185 break;
1186 case 1:
1187 dev->flags |= P2P_DEV_PREFER_PERSISTENT_GROUP;
1188 dev->flags &= ~P2P_DEV_PREFER_PERSISTENT_RECONN;
1189 break;
1190 case 2:
1191 dev->flags |= P2P_DEV_PREFER_PERSISTENT_GROUP |
1192 P2P_DEV_PREFER_PERSISTENT_RECONN;
1193 break;
1194 }
1195}
1196
1197
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07001198int p2p_connect(struct p2p_data *p2p, const u8 *peer_addr,
1199 enum p2p_wps_method wps_method,
1200 int go_intent, const u8 *own_interface_addr,
1201 unsigned int force_freq, int persistent_group)
1202{
1203 struct p2p_device *dev;
1204
1205 wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG,
1206 "P2P: Request to start group negotiation - peer=" MACSTR
1207 " GO Intent=%d Intended Interface Address=" MACSTR
1208 " wps_method=%d persistent_group=%d",
1209 MAC2STR(peer_addr), go_intent, MAC2STR(own_interface_addr),
1210 wps_method, persistent_group);
1211
1212 if (p2p_prepare_channel(p2p, force_freq) < 0)
1213 return -1;
1214
Dmitry Shmidt1f69aa52012-01-24 16:10:04 -08001215 p2p->ssid_set = 0;
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07001216 dev = p2p_get_device(p2p, peer_addr);
1217 if (dev == NULL || (dev->flags & P2P_DEV_PROBE_REQ_ONLY)) {
1218 wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG,
1219 "P2P: Cannot connect to unknown P2P Device " MACSTR,
1220 MAC2STR(peer_addr));
1221 return -1;
1222 }
1223
1224 if (dev->flags & P2P_DEV_GROUP_CLIENT_ONLY) {
1225 if (!(dev->info.dev_capab &
1226 P2P_DEV_CAPAB_CLIENT_DISCOVERABILITY)) {
1227 wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG,
1228 "P2P: Cannot connect to P2P Device " MACSTR
1229 " that is in a group and is not discoverable",
1230 MAC2STR(peer_addr));
1231 return -1;
1232 }
1233 if (dev->oper_freq <= 0) {
1234 wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG,
1235 "P2P: Cannot connect to P2P Device " MACSTR
1236 " with incomplete information",
1237 MAC2STR(peer_addr));
1238 return -1;
1239 }
1240
1241 /*
1242 * First, try to connect directly. If the peer does not
1243 * acknowledge frames, assume it is sleeping and use device
1244 * discoverability via the GO at that point.
1245 */
1246 }
1247
1248 dev->flags &= ~P2P_DEV_NOT_YET_READY;
1249 dev->flags &= ~P2P_DEV_USER_REJECTED;
1250 dev->flags &= ~P2P_DEV_WAIT_GO_NEG_RESPONSE;
1251 dev->flags &= ~P2P_DEV_WAIT_GO_NEG_CONFIRM;
1252 dev->connect_reqs = 0;
1253 dev->go_neg_req_sent = 0;
1254 dev->go_state = UNKNOWN_GO;
Dmitry Shmidt1f69aa52012-01-24 16:10:04 -08001255 p2p_set_dev_persistent(dev, persistent_group);
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07001256 p2p->go_intent = go_intent;
1257 os_memcpy(p2p->intended_addr, own_interface_addr, ETH_ALEN);
1258
1259 if (p2p->state != P2P_IDLE)
1260 p2p_stop_find(p2p);
1261
1262 if (p2p->after_scan_tx) {
1263 /*
1264 * We need to drop the pending frame to avoid issues with the
1265 * new GO Negotiation, e.g., when the pending frame was from a
1266 * previous attempt at starting a GO Negotiation.
1267 */
1268 wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG, "P2P: Dropped "
1269 "previous pending Action frame TX that was waiting "
1270 "for p2p_scan completion");
1271 os_free(p2p->after_scan_tx);
1272 p2p->after_scan_tx = NULL;
1273 }
1274
1275 dev->wps_method = wps_method;
1276 dev->status = P2P_SC_SUCCESS;
1277
1278 if (force_freq)
1279 dev->flags |= P2P_DEV_FORCE_FREQ;
1280 else
1281 dev->flags &= ~P2P_DEV_FORCE_FREQ;
1282
1283 if (p2p->p2p_scan_running) {
1284 wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG,
1285 "P2P: p2p_scan running - delay connect send");
1286 p2p->start_after_scan = P2P_AFTER_SCAN_CONNECT;
1287 os_memcpy(p2p->after_scan_peer, peer_addr, ETH_ALEN);
1288 return 0;
1289 }
1290 p2p->start_after_scan = P2P_AFTER_SCAN_NOTHING;
1291
1292 return p2p_connect_send(p2p, dev);
1293}
1294
1295
1296int p2p_authorize(struct p2p_data *p2p, const u8 *peer_addr,
1297 enum p2p_wps_method wps_method,
1298 int go_intent, const u8 *own_interface_addr,
1299 unsigned int force_freq, int persistent_group)
1300{
1301 struct p2p_device *dev;
1302
1303 wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG,
1304 "P2P: Request to authorize group negotiation - peer=" MACSTR
1305 " GO Intent=%d Intended Interface Address=" MACSTR
1306 " wps_method=%d persistent_group=%d",
1307 MAC2STR(peer_addr), go_intent, MAC2STR(own_interface_addr),
1308 wps_method, persistent_group);
1309
1310 if (p2p_prepare_channel(p2p, force_freq) < 0)
1311 return -1;
1312
1313 dev = p2p_get_device(p2p, peer_addr);
1314 if (dev == NULL) {
1315 wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG,
1316 "P2P: Cannot authorize unknown P2P Device " MACSTR,
1317 MAC2STR(peer_addr));
1318 return -1;
1319 }
1320
1321 dev->flags &= ~P2P_DEV_NOT_YET_READY;
1322 dev->flags &= ~P2P_DEV_USER_REJECTED;
1323 dev->go_neg_req_sent = 0;
1324 dev->go_state = UNKNOWN_GO;
Dmitry Shmidt1f69aa52012-01-24 16:10:04 -08001325 p2p_set_dev_persistent(dev, persistent_group);
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07001326 p2p->go_intent = go_intent;
1327 os_memcpy(p2p->intended_addr, own_interface_addr, ETH_ALEN);
1328
1329 dev->wps_method = wps_method;
1330 dev->status = P2P_SC_SUCCESS;
1331
1332 if (force_freq)
1333 dev->flags |= P2P_DEV_FORCE_FREQ;
1334 else
1335 dev->flags &= ~P2P_DEV_FORCE_FREQ;
1336
1337 return 0;
1338}
1339
1340
1341void p2p_add_dev_info(struct p2p_data *p2p, const u8 *addr,
1342 struct p2p_device *dev, struct p2p_message *msg)
1343{
1344 os_get_time(&dev->last_seen);
1345
1346 p2p_copy_wps_info(dev, 0, msg);
1347
1348 if (msg->listen_channel) {
1349 int freq;
1350 freq = p2p_channel_to_freq((char *) msg->listen_channel,
1351 msg->listen_channel[3],
1352 msg->listen_channel[4]);
1353 if (freq < 0) {
1354 wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG,
1355 "P2P: Unknown peer Listen channel: "
1356 "country=%c%c(0x%02x) reg_class=%u channel=%u",
1357 msg->listen_channel[0],
1358 msg->listen_channel[1],
1359 msg->listen_channel[2],
1360 msg->listen_channel[3],
1361 msg->listen_channel[4]);
1362 } else {
1363 wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG, "P2P: Update "
1364 "peer " MACSTR " Listen channel: %u -> %u MHz",
1365 MAC2STR(dev->info.p2p_device_addr),
1366 dev->listen_freq, freq);
1367 dev->listen_freq = freq;
1368 }
1369 }
1370
1371 if (dev->flags & P2P_DEV_PROBE_REQ_ONLY) {
1372 dev->flags &= ~P2P_DEV_PROBE_REQ_ONLY;
1373 wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG,
1374 "P2P: Completed device entry based on data from "
1375 "GO Negotiation Request");
1376 } else {
1377 wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG,
1378 "P2P: Created device entry based on GO Neg Req: "
1379 MACSTR " dev_capab=0x%x group_capab=0x%x name='%s' "
1380 "listen_freq=%d",
1381 MAC2STR(dev->info.p2p_device_addr),
1382 dev->info.dev_capab, dev->info.group_capab,
1383 dev->info.device_name, dev->listen_freq);
1384 }
1385
1386 dev->flags &= ~P2P_DEV_GROUP_CLIENT_ONLY;
1387
1388 if (dev->flags & P2P_DEV_USER_REJECTED) {
1389 wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG,
1390 "P2P: Do not report rejected device");
1391 return;
1392 }
1393
1394 p2p->cfg->dev_found(p2p->cfg->cb_ctx, addr, &dev->info,
1395 !(dev->flags & P2P_DEV_REPORTED_ONCE));
1396 dev->flags |= P2P_DEV_REPORTED | P2P_DEV_REPORTED_ONCE;
1397}
1398
1399
1400void p2p_build_ssid(struct p2p_data *p2p, u8 *ssid, size_t *ssid_len)
1401{
1402 os_memcpy(ssid, P2P_WILDCARD_SSID, P2P_WILDCARD_SSID_LEN);
1403 p2p_random((char *) &ssid[P2P_WILDCARD_SSID_LEN], 2);
1404 os_memcpy(&ssid[P2P_WILDCARD_SSID_LEN + 2],
1405 p2p->cfg->ssid_postfix, p2p->cfg->ssid_postfix_len);
1406 *ssid_len = P2P_WILDCARD_SSID_LEN + 2 + p2p->cfg->ssid_postfix_len;
1407}
1408
1409
1410int p2p_go_params(struct p2p_data *p2p, struct p2p_go_neg_results *params)
1411{
1412 p2p_build_ssid(p2p, params->ssid, &params->ssid_len);
1413 p2p_random(params->passphrase, 8);
1414 return 0;
1415}
1416
1417
1418void p2p_go_complete(struct p2p_data *p2p, struct p2p_device *peer)
1419{
1420 struct p2p_go_neg_results res;
1421 int go = peer->go_state == LOCAL_GO;
1422 struct p2p_channels intersection;
1423 int freqs;
1424 size_t i, j;
1425
1426 wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG,
1427 "P2P: GO Negotiation with " MACSTR " completed (%s will be "
1428 "GO)", MAC2STR(peer->info.p2p_device_addr),
1429 go ? "local end" : "peer");
1430
1431 os_memset(&res, 0, sizeof(res));
1432 res.role_go = go;
1433 os_memcpy(res.peer_device_addr, peer->info.p2p_device_addr, ETH_ALEN);
1434 os_memcpy(res.peer_interface_addr, peer->intended_addr, ETH_ALEN);
1435 res.wps_method = peer->wps_method;
Dmitry Shmidt1f69aa52012-01-24 16:10:04 -08001436 if (peer->flags & P2P_DEV_PREFER_PERSISTENT_GROUP) {
1437 if (peer->flags & P2P_DEV_PREFER_PERSISTENT_RECONN)
1438 res.persistent_group = 2;
1439 else
1440 res.persistent_group = 1;
1441 }
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07001442
1443 if (go) {
1444 /* Setup AP mode for WPS provisioning */
1445 res.freq = p2p_channel_to_freq(p2p->cfg->country,
1446 p2p->op_reg_class,
1447 p2p->op_channel);
1448 os_memcpy(res.ssid, p2p->ssid, p2p->ssid_len);
1449 res.ssid_len = p2p->ssid_len;
1450 p2p_random(res.passphrase, 8);
1451 } else {
1452 res.freq = peer->oper_freq;
1453 if (p2p->ssid_len) {
1454 os_memcpy(res.ssid, p2p->ssid, p2p->ssid_len);
1455 res.ssid_len = p2p->ssid_len;
1456 }
1457 }
1458
1459 p2p_channels_intersect(&p2p->channels, &peer->channels,
1460 &intersection);
1461 freqs = 0;
1462 for (i = 0; i < intersection.reg_classes; i++) {
1463 struct p2p_reg_class *c = &intersection.reg_class[i];
1464 if (freqs + 1 == P2P_MAX_CHANNELS)
1465 break;
1466 for (j = 0; j < c->channels; j++) {
1467 int freq;
1468 if (freqs + 1 == P2P_MAX_CHANNELS)
1469 break;
1470 freq = p2p_channel_to_freq(peer->country, c->reg_class,
1471 c->channel[j]);
1472 if (freq < 0)
1473 continue;
1474 res.freq_list[freqs++] = freq;
1475 }
1476 }
1477
1478 res.peer_config_timeout = go ? peer->client_timeout : peer->go_timeout;
1479
1480 p2p_clear_timeout(p2p);
Dmitry Shmidt1f69aa52012-01-24 16:10:04 -08001481 p2p->ssid_set = 0;
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07001482 peer->go_neg_req_sent = 0;
1483 peer->wps_method = WPS_NOT_READY;
1484
1485 p2p_set_state(p2p, P2P_PROVISIONING);
1486 p2p->cfg->go_neg_completed(p2p->cfg->cb_ctx, &res);
1487}
1488
1489
1490static void p2p_rx_p2p_action(struct p2p_data *p2p, const u8 *sa,
1491 const u8 *data, size_t len, int rx_freq)
1492{
1493 wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG,
1494 "P2P: RX P2P Public Action from " MACSTR, MAC2STR(sa));
1495 wpa_hexdump(MSG_MSGDUMP, "P2P: P2P Public Action contents", data, len);
1496
1497 if (len < 1)
1498 return;
1499
1500 switch (data[0]) {
1501 case P2P_GO_NEG_REQ:
1502 p2p_process_go_neg_req(p2p, sa, data + 1, len - 1, rx_freq);
1503 break;
1504 case P2P_GO_NEG_RESP:
1505 p2p_process_go_neg_resp(p2p, sa, data + 1, len - 1, rx_freq);
1506 break;
1507 case P2P_GO_NEG_CONF:
1508 p2p_process_go_neg_conf(p2p, sa, data + 1, len - 1);
1509 break;
1510 case P2P_INVITATION_REQ:
1511 p2p_process_invitation_req(p2p, sa, data + 1, len - 1,
1512 rx_freq);
1513 break;
1514 case P2P_INVITATION_RESP:
1515 p2p_process_invitation_resp(p2p, sa, data + 1, len - 1);
1516 break;
1517 case P2P_PROV_DISC_REQ:
1518 p2p_process_prov_disc_req(p2p, sa, data + 1, len - 1, rx_freq);
1519 break;
1520 case P2P_PROV_DISC_RESP:
1521 p2p_process_prov_disc_resp(p2p, sa, data + 1, len - 1);
1522 break;
1523 case P2P_DEV_DISC_REQ:
1524 p2p_process_dev_disc_req(p2p, sa, data + 1, len - 1, rx_freq);
1525 break;
1526 case P2P_DEV_DISC_RESP:
1527 p2p_process_dev_disc_resp(p2p, sa, data + 1, len - 1);
1528 break;
1529 default:
1530 wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG,
1531 "P2P: Unsupported P2P Public Action frame type %d",
1532 data[0]);
1533 break;
1534 }
1535}
1536
1537
Dmitry Shmidt1f69aa52012-01-24 16:10:04 -08001538static void p2p_rx_action_public(struct p2p_data *p2p, const u8 *da,
1539 const u8 *sa, const u8 *bssid, const u8 *data,
1540 size_t len, int freq)
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07001541{
1542 if (len < 1)
1543 return;
1544
1545 switch (data[0]) {
1546 case WLAN_PA_VENDOR_SPECIFIC:
1547 data++;
1548 len--;
1549 if (len < 3)
1550 return;
1551 if (WPA_GET_BE24(data) != OUI_WFA)
1552 return;
1553
1554 data += 3;
1555 len -= 3;
1556 if (len < 1)
1557 return;
1558
1559 if (*data != P2P_OUI_TYPE)
1560 return;
1561
1562 p2p_rx_p2p_action(p2p, sa, data + 1, len - 1, freq);
1563 break;
1564 case WLAN_PA_GAS_INITIAL_REQ:
1565 p2p_rx_gas_initial_req(p2p, sa, data + 1, len - 1, freq);
1566 break;
1567 case WLAN_PA_GAS_INITIAL_RESP:
1568 p2p_rx_gas_initial_resp(p2p, sa, data + 1, len - 1, freq);
1569 break;
1570 case WLAN_PA_GAS_COMEBACK_REQ:
1571 p2p_rx_gas_comeback_req(p2p, sa, data + 1, len - 1, freq);
1572 break;
1573 case WLAN_PA_GAS_COMEBACK_RESP:
1574 p2p_rx_gas_comeback_resp(p2p, sa, data + 1, len - 1, freq);
1575 break;
1576 }
1577}
1578
1579
1580void p2p_rx_action(struct p2p_data *p2p, const u8 *da, const u8 *sa,
1581 const u8 *bssid, u8 category,
1582 const u8 *data, size_t len, int freq)
1583{
1584 if (category == WLAN_ACTION_PUBLIC) {
1585 p2p_rx_action_public(p2p, da, sa, bssid, data, len, freq);
1586 return;
1587 }
1588
1589 if (category != WLAN_ACTION_VENDOR_SPECIFIC)
1590 return;
1591
1592 if (len < 4)
1593 return;
1594
1595 if (WPA_GET_BE24(data) != OUI_WFA)
1596 return;
1597 data += 3;
1598 len -= 3;
1599
1600 if (*data != P2P_OUI_TYPE)
1601 return;
1602 data++;
1603 len--;
1604
1605 /* P2P action frame */
1606 wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG,
1607 "P2P: RX P2P Action from " MACSTR, MAC2STR(sa));
1608 wpa_hexdump(MSG_MSGDUMP, "P2P: P2P Action contents", data, len);
1609
1610 if (len < 1)
1611 return;
1612 switch (data[0]) {
1613 case P2P_NOA:
1614 wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG,
1615 "P2P: Received P2P Action - Notice of Absence");
1616 /* TODO */
1617 break;
1618 case P2P_PRESENCE_REQ:
1619 p2p_process_presence_req(p2p, da, sa, data + 1, len - 1, freq);
1620 break;
1621 case P2P_PRESENCE_RESP:
1622 p2p_process_presence_resp(p2p, da, sa, data + 1, len - 1);
1623 break;
1624 case P2P_GO_DISC_REQ:
1625 p2p_process_go_disc_req(p2p, da, sa, data + 1, len - 1, freq);
1626 break;
1627 default:
1628 wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG,
1629 "P2P: Received P2P Action - unknown type %u", data[0]);
1630 break;
1631 }
1632}
1633
1634
1635static void p2p_go_neg_start(void *eloop_ctx, void *timeout_ctx)
1636{
1637 struct p2p_data *p2p = eloop_ctx;
1638 if (p2p->go_neg_peer == NULL)
1639 return;
1640 p2p->cfg->stop_listen(p2p->cfg->cb_ctx);
1641 p2p->go_neg_peer->status = P2P_SC_SUCCESS;
1642 p2p_connect_send(p2p, p2p->go_neg_peer);
1643}
1644
1645
1646static void p2p_invite_start(void *eloop_ctx, void *timeout_ctx)
1647{
1648 struct p2p_data *p2p = eloop_ctx;
1649 if (p2p->invite_peer == NULL)
1650 return;
1651 p2p->cfg->stop_listen(p2p->cfg->cb_ctx);
1652 p2p_invite_send(p2p, p2p->invite_peer, p2p->invite_go_dev_addr);
1653}
1654
1655
1656static void p2p_add_dev_from_probe_req(struct p2p_data *p2p, const u8 *addr,
1657 const u8 *ie, size_t ie_len)
1658{
1659 struct p2p_message msg;
1660 struct p2p_device *dev;
1661
1662 os_memset(&msg, 0, sizeof(msg));
1663 if (p2p_parse_ies(ie, ie_len, &msg) < 0 || msg.p2p_attributes == NULL)
1664 {
1665 p2p_parse_free(&msg);
1666 return; /* not a P2P probe */
1667 }
1668
1669 if (msg.ssid == NULL || msg.ssid[1] != P2P_WILDCARD_SSID_LEN ||
1670 os_memcmp(msg.ssid + 2, P2P_WILDCARD_SSID, P2P_WILDCARD_SSID_LEN)
1671 != 0) {
1672 /* The Probe Request is not part of P2P Device Discovery. It is
1673 * not known whether the source address of the frame is the P2P
1674 * Device Address or P2P Interface Address. Do not add a new
1675 * peer entry based on this frames.
1676 */
1677 p2p_parse_free(&msg);
1678 return;
1679 }
1680
1681 dev = p2p_get_device(p2p, addr);
1682 if (dev) {
1683 if (dev->country[0] == 0 && msg.listen_channel)
1684 os_memcpy(dev->country, msg.listen_channel, 3);
Dmitry Shmidt1f69aa52012-01-24 16:10:04 -08001685 os_get_time(&dev->last_seen);
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07001686 p2p_parse_free(&msg);
1687 return; /* already known */
1688 }
1689
1690 dev = p2p_create_device(p2p, addr);
1691 if (dev == NULL) {
1692 p2p_parse_free(&msg);
1693 return;
1694 }
1695
1696 os_get_time(&dev->last_seen);
1697 dev->flags |= P2P_DEV_PROBE_REQ_ONLY;
1698
1699 if (msg.listen_channel) {
1700 os_memcpy(dev->country, msg.listen_channel, 3);
1701 dev->listen_freq = p2p_channel_to_freq(dev->country,
1702 msg.listen_channel[3],
1703 msg.listen_channel[4]);
1704 }
1705
1706 p2p_copy_wps_info(dev, 1, &msg);
1707
1708 p2p_parse_free(&msg);
1709
1710 wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG,
1711 "P2P: Created device entry based on Probe Req: " MACSTR
1712 " dev_capab=0x%x group_capab=0x%x name='%s' listen_freq=%d",
1713 MAC2STR(dev->info.p2p_device_addr), dev->info.dev_capab,
1714 dev->info.group_capab, dev->info.device_name,
1715 dev->listen_freq);
1716}
1717
1718
1719struct p2p_device * p2p_add_dev_from_go_neg_req(struct p2p_data *p2p,
1720 const u8 *addr,
1721 struct p2p_message *msg)
1722{
1723 struct p2p_device *dev;
1724
1725 dev = p2p_get_device(p2p, addr);
1726 if (dev) {
1727 os_get_time(&dev->last_seen);
1728 return dev; /* already known */
1729 }
1730
1731 dev = p2p_create_device(p2p, addr);
1732 if (dev == NULL)
1733 return NULL;
1734
1735 p2p_add_dev_info(p2p, addr, dev, msg);
1736
1737 return dev;
1738}
1739
1740
1741static int dev_type_match(const u8 *dev_type, const u8 *req_dev_type)
1742{
1743 if (os_memcmp(dev_type, req_dev_type, WPS_DEV_TYPE_LEN) == 0)
1744 return 1;
1745 if (os_memcmp(dev_type, req_dev_type, 2) == 0 &&
1746 WPA_GET_BE32(&req_dev_type[2]) == 0 &&
1747 WPA_GET_BE16(&req_dev_type[6]) == 0)
1748 return 1; /* Category match with wildcard OUI/sub-category */
1749 return 0;
1750}
1751
1752
1753int dev_type_list_match(const u8 *dev_type, const u8 *req_dev_type[],
1754 size_t num_req_dev_type)
1755{
1756 size_t i;
1757 for (i = 0; i < num_req_dev_type; i++) {
1758 if (dev_type_match(dev_type, req_dev_type[i]))
1759 return 1;
1760 }
1761 return 0;
1762}
1763
1764
1765/**
1766 * p2p_match_dev_type - Match local device type with requested type
1767 * @p2p: P2P module context from p2p_init()
1768 * @wps: WPS TLVs from Probe Request frame (concatenated WPS IEs)
1769 * Returns: 1 on match, 0 on mismatch
1770 *
1771 * This function can be used to match the Requested Device Type attribute in
1772 * WPS IE with the local device types for deciding whether to reply to a Probe
1773 * Request frame.
1774 */
1775int p2p_match_dev_type(struct p2p_data *p2p, struct wpabuf *wps)
1776{
1777 struct wps_parse_attr attr;
1778 size_t i;
1779
1780 if (wps_parse_msg(wps, &attr))
1781 return 1; /* assume no Requested Device Type attributes */
1782
1783 if (attr.num_req_dev_type == 0)
1784 return 1; /* no Requested Device Type attributes -> match */
1785
1786 if (dev_type_list_match(p2p->cfg->pri_dev_type, attr.req_dev_type,
1787 attr.num_req_dev_type))
1788 return 1; /* Own Primary Device Type matches */
1789
1790 for (i = 0; i < p2p->cfg->num_sec_dev_types; i++)
1791 if (dev_type_list_match(p2p->cfg->sec_dev_type[i],
1792 attr.req_dev_type,
1793 attr.num_req_dev_type))
1794 return 1; /* Own Secondary Device Type matches */
1795
1796 /* No matching device type found */
1797 return 0;
1798}
1799
1800
1801struct wpabuf * p2p_build_probe_resp_ies(struct p2p_data *p2p)
1802{
1803 struct wpabuf *buf;
1804 u8 *len;
1805
1806 buf = wpabuf_alloc(1000);
1807 if (buf == NULL)
1808 return NULL;
1809
1810 p2p_build_wps_ie(p2p, buf, DEV_PW_DEFAULT, 1);
1811
1812 /* P2P IE */
1813 len = p2p_buf_add_ie_hdr(buf);
1814 p2p_buf_add_capability(buf, p2p->dev_capab, 0);
1815 if (p2p->ext_listen_interval)
1816 p2p_buf_add_ext_listen_timing(buf, p2p->ext_listen_period,
1817 p2p->ext_listen_interval);
1818 p2p_buf_add_device_info(buf, p2p, NULL);
1819 p2p_buf_update_ie_hdr(buf, len);
1820
1821 return buf;
1822}
1823
1824
Dmitry Shmidt1f69aa52012-01-24 16:10:04 -08001825static int is_11b(u8 rate)
1826{
1827 return rate == 0x02 || rate == 0x04 || rate == 0x0b || rate == 0x16;
1828}
1829
1830
1831static int supp_rates_11b_only(struct ieee802_11_elems *elems)
1832{
1833 int num_11b = 0, num_others = 0;
1834 int i;
1835
1836 if (elems->supp_rates == NULL && elems->ext_supp_rates == NULL)
1837 return 0;
1838
1839 for (i = 0; elems->supp_rates && i < elems->supp_rates_len; i++) {
1840 if (is_11b(elems->supp_rates[i]))
1841 num_11b++;
1842 else
1843 num_others++;
1844 }
1845
1846 for (i = 0; elems->ext_supp_rates && i < elems->ext_supp_rates_len;
1847 i++) {
1848 if (is_11b(elems->ext_supp_rates[i]))
1849 num_11b++;
1850 else
1851 num_others++;
1852 }
1853
1854 return num_11b > 0 && num_others == 0;
1855}
1856
1857
1858static void p2p_reply_probe(struct p2p_data *p2p, const u8 *addr,
1859 const u8 *dst, const u8 *bssid, const u8 *ie,
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07001860 size_t ie_len)
1861{
1862 struct ieee802_11_elems elems;
1863 struct wpabuf *buf;
1864 struct ieee80211_mgmt *resp;
Dmitry Shmidt1f69aa52012-01-24 16:10:04 -08001865 struct p2p_message msg;
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07001866 struct wpabuf *ies;
1867
1868 if (!p2p->in_listen || !p2p->drv_in_listen) {
1869 /* not in Listen state - ignore Probe Request */
1870 return;
1871 }
1872
1873 if (ieee802_11_parse_elems((u8 *) ie, ie_len, &elems, 0) ==
1874 ParseFailed) {
1875 /* Ignore invalid Probe Request frames */
1876 return;
1877 }
1878
1879 if (elems.p2p == NULL) {
1880 /* not a P2P probe - ignore it */
1881 return;
1882 }
1883
Dmitry Shmidt1f69aa52012-01-24 16:10:04 -08001884 if (dst && !is_broadcast_ether_addr(dst) &&
1885 os_memcmp(dst, p2p->cfg->dev_addr, ETH_ALEN) != 0) {
1886 /* Not sent to the broadcast address or our P2P Device Address
1887 */
1888 return;
1889 }
1890
1891 if (bssid && !is_broadcast_ether_addr(bssid)) {
1892 /* Not sent to the Wildcard BSSID */
1893 return;
1894 }
1895
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07001896 if (elems.ssid == NULL || elems.ssid_len != P2P_WILDCARD_SSID_LEN ||
1897 os_memcmp(elems.ssid, P2P_WILDCARD_SSID, P2P_WILDCARD_SSID_LEN) !=
1898 0) {
1899 /* not using P2P Wildcard SSID - ignore */
1900 return;
1901 }
1902
Dmitry Shmidt1f69aa52012-01-24 16:10:04 -08001903 if (supp_rates_11b_only(&elems)) {
1904 /* Indicates support for 11b rates only */
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07001905 return;
1906 }
Dmitry Shmidt1f69aa52012-01-24 16:10:04 -08001907
1908 os_memset(&msg, 0, sizeof(msg));
1909 if (p2p_parse_ies(ie, ie_len, &msg) < 0) {
1910 /* Could not parse P2P attributes */
1911 return;
1912 }
1913
1914 if (msg.device_id &&
1915 os_memcmp(msg.device_id, p2p->cfg->dev_addr, ETH_ALEN != 0)) {
1916 /* Device ID did not match */
1917 p2p_parse_free(&msg);
1918 return;
1919 }
1920
1921 /* Check Requested Device Type match */
1922 if (msg.wps_attributes &&
1923 !p2p_match_dev_type(p2p, msg.wps_attributes)) {
1924 /* No match with Requested Device Type */
1925 p2p_parse_free(&msg);
1926 return;
1927 }
1928 p2p_parse_free(&msg);
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07001929
1930 if (!p2p->cfg->send_probe_resp)
1931 return; /* Response generated elsewhere */
1932
1933 wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG,
1934 "P2P: Reply to P2P Probe Request in Listen state");
1935
1936 /*
1937 * We do not really have a specific BSS that this frame is advertising,
1938 * so build a frame that has some information in valid format. This is
1939 * really only used for discovery purposes, not to learn exact BSS
1940 * parameters.
1941 */
1942 ies = p2p_build_probe_resp_ies(p2p);
1943 if (ies == NULL)
1944 return;
1945
1946 buf = wpabuf_alloc(200 + wpabuf_len(ies));
1947 if (buf == NULL) {
1948 wpabuf_free(ies);
1949 return;
1950 }
1951
1952 resp = NULL;
1953 resp = wpabuf_put(buf, resp->u.probe_resp.variable - (u8 *) resp);
1954
1955 resp->frame_control = host_to_le16((WLAN_FC_TYPE_MGMT << 2) |
1956 (WLAN_FC_STYPE_PROBE_RESP << 4));
1957 os_memcpy(resp->da, addr, ETH_ALEN);
1958 os_memcpy(resp->sa, p2p->cfg->dev_addr, ETH_ALEN);
1959 os_memcpy(resp->bssid, p2p->cfg->dev_addr, ETH_ALEN);
1960 resp->u.probe_resp.beacon_int = host_to_le16(100);
1961 /* hardware or low-level driver will setup seq_ctrl and timestamp */
1962 resp->u.probe_resp.capab_info =
1963 host_to_le16(WLAN_CAPABILITY_SHORT_PREAMBLE |
1964 WLAN_CAPABILITY_PRIVACY |
1965 WLAN_CAPABILITY_SHORT_SLOT_TIME);
1966
1967 wpabuf_put_u8(buf, WLAN_EID_SSID);
1968 wpabuf_put_u8(buf, P2P_WILDCARD_SSID_LEN);
1969 wpabuf_put_data(buf, P2P_WILDCARD_SSID, P2P_WILDCARD_SSID_LEN);
1970
1971 wpabuf_put_u8(buf, WLAN_EID_SUPP_RATES);
1972 wpabuf_put_u8(buf, 8);
1973 wpabuf_put_u8(buf, (60 / 5) | 0x80);
1974 wpabuf_put_u8(buf, 90 / 5);
1975 wpabuf_put_u8(buf, (120 / 5) | 0x80);
1976 wpabuf_put_u8(buf, 180 / 5);
1977 wpabuf_put_u8(buf, (240 / 5) | 0x80);
1978 wpabuf_put_u8(buf, 360 / 5);
1979 wpabuf_put_u8(buf, 480 / 5);
1980 wpabuf_put_u8(buf, 540 / 5);
1981
1982 wpabuf_put_u8(buf, WLAN_EID_DS_PARAMS);
1983 wpabuf_put_u8(buf, 1);
1984 wpabuf_put_u8(buf, p2p->cfg->channel);
1985
1986 wpabuf_put_buf(buf, ies);
1987 wpabuf_free(ies);
1988
1989 p2p->cfg->send_probe_resp(p2p->cfg->cb_ctx, buf);
1990
1991 wpabuf_free(buf);
1992}
1993
1994
Dmitry Shmidt1f69aa52012-01-24 16:10:04 -08001995int p2p_probe_req_rx(struct p2p_data *p2p, const u8 *addr, const u8 *dst,
1996 const u8 *bssid, const u8 *ie, size_t ie_len)
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07001997{
1998 p2p_add_dev_from_probe_req(p2p, addr, ie, ie_len);
1999
Dmitry Shmidt1f69aa52012-01-24 16:10:04 -08002000 p2p_reply_probe(p2p, addr, dst, bssid, ie, ie_len);
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07002001
2002 if ((p2p->state == P2P_CONNECT || p2p->state == P2P_CONNECT_LISTEN) &&
2003 p2p->go_neg_peer &&
2004 os_memcmp(addr, p2p->go_neg_peer->info.p2p_device_addr, ETH_ALEN)
2005 == 0) {
2006 /* Received a Probe Request from GO Negotiation peer */
2007 wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG,
2008 "P2P: Found GO Negotiation peer - try to start GO "
2009 "negotiation from timeout");
2010 eloop_register_timeout(0, 0, p2p_go_neg_start, p2p, NULL);
2011 return 1;
2012 }
2013
2014 if ((p2p->state == P2P_INVITE || p2p->state == P2P_INVITE_LISTEN) &&
2015 p2p->invite_peer &&
2016 os_memcmp(addr, p2p->invite_peer->info.p2p_device_addr, ETH_ALEN)
2017 == 0) {
2018 /* Received a Probe Request from Invite peer */
2019 wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG,
2020 "P2P: Found Invite peer - try to start Invite from "
2021 "timeout");
2022 eloop_register_timeout(0, 0, p2p_invite_start, p2p, NULL);
2023 return 1;
2024 }
2025
2026 return 0;
2027}
2028
2029
2030static int p2p_assoc_req_ie_wlan_ap(struct p2p_data *p2p, const u8 *bssid,
2031 u8 *buf, size_t len, struct wpabuf *p2p_ie)
2032{
2033 struct wpabuf *tmp;
2034 u8 *lpos;
2035 size_t tmplen;
2036 int res;
2037 u8 group_capab;
2038
2039 if (p2p_ie == NULL)
2040 return 0; /* WLAN AP is not a P2P manager */
2041
2042 /*
2043 * (Re)Association Request - P2P IE
2044 * P2P Capability attribute (shall be present)
2045 * P2P Interface attribute (present if concurrent device and
2046 * P2P Management is enabled)
2047 */
2048 tmp = wpabuf_alloc(200);
2049 if (tmp == NULL)
2050 return -1;
2051
2052 lpos = p2p_buf_add_ie_hdr(tmp);
2053 group_capab = 0;
2054 if (p2p->num_groups > 0) {
2055 group_capab |= P2P_GROUP_CAPAB_GROUP_OWNER;
2056 if ((p2p->dev_capab & P2P_DEV_CAPAB_CONCURRENT_OPER) &&
2057 (p2p->dev_capab & P2P_DEV_CAPAB_INFRA_MANAGED) &&
2058 p2p->cross_connect)
2059 group_capab |= P2P_GROUP_CAPAB_CROSS_CONN;
2060 }
2061 p2p_buf_add_capability(tmp, p2p->dev_capab, group_capab);
2062 if ((p2p->dev_capab & P2P_DEV_CAPAB_CONCURRENT_OPER) &&
2063 (p2p->dev_capab & P2P_DEV_CAPAB_INFRA_MANAGED))
2064 p2p_buf_add_p2p_interface(tmp, p2p);
2065 p2p_buf_update_ie_hdr(tmp, lpos);
2066
2067 tmplen = wpabuf_len(tmp);
2068 if (tmplen > len)
2069 res = -1;
2070 else {
2071 os_memcpy(buf, wpabuf_head(tmp), tmplen);
2072 res = tmplen;
2073 }
2074 wpabuf_free(tmp);
2075
2076 return res;
2077}
2078
2079
2080int p2p_assoc_req_ie(struct p2p_data *p2p, const u8 *bssid, u8 *buf,
2081 size_t len, int p2p_group, struct wpabuf *p2p_ie)
2082{
2083 struct wpabuf *tmp;
2084 u8 *lpos;
2085 struct p2p_device *peer;
2086 size_t tmplen;
2087 int res;
2088
2089 if (!p2p_group)
2090 return p2p_assoc_req_ie_wlan_ap(p2p, bssid, buf, len, p2p_ie);
2091
2092 /*
2093 * (Re)Association Request - P2P IE
2094 * P2P Capability attribute (shall be present)
2095 * Extended Listen Timing (may be present)
2096 * P2P Device Info attribute (shall be present)
2097 */
2098 tmp = wpabuf_alloc(200);
2099 if (tmp == NULL)
2100 return -1;
2101
2102 peer = bssid ? p2p_get_device(p2p, bssid) : NULL;
2103
2104 lpos = p2p_buf_add_ie_hdr(tmp);
2105 p2p_buf_add_capability(tmp, p2p->dev_capab, 0);
2106 if (p2p->ext_listen_interval)
2107 p2p_buf_add_ext_listen_timing(tmp, p2p->ext_listen_period,
2108 p2p->ext_listen_interval);
2109 p2p_buf_add_device_info(tmp, p2p, peer);
2110 p2p_buf_update_ie_hdr(tmp, lpos);
2111
2112 tmplen = wpabuf_len(tmp);
2113 if (tmplen > len)
2114 res = -1;
2115 else {
2116 os_memcpy(buf, wpabuf_head(tmp), tmplen);
2117 res = tmplen;
2118 }
2119 wpabuf_free(tmp);
2120
2121 return res;
2122}
2123
2124
2125int p2p_scan_result_text(const u8 *ies, size_t ies_len, char *buf, char *end)
2126{
2127 struct wpabuf *p2p_ie;
2128 int ret;
2129
2130 p2p_ie = ieee802_11_vendor_ie_concat(ies, ies_len, P2P_IE_VENDOR_TYPE);
2131 if (p2p_ie == NULL)
2132 return 0;
2133
2134 ret = p2p_attr_text(p2p_ie, buf, end);
2135 wpabuf_free(p2p_ie);
2136 return ret;
2137}
2138
2139
Dmitry Shmidtc5ec7f52012-03-06 16:33:24 -08002140int p2p_parse_dev_addr(const u8 *ies, size_t ies_len, u8 *dev_addr)
2141{
2142 struct wpabuf *p2p_ie;
2143 struct p2p_message msg;
2144
2145 p2p_ie = ieee802_11_vendor_ie_concat(ies, ies_len,
2146 P2P_IE_VENDOR_TYPE);
2147 if (p2p_ie == NULL)
2148 return -1;
2149 os_memset(&msg, 0, sizeof(msg));
2150 if (p2p_parse_p2p_ie(p2p_ie, &msg)) {
2151 wpabuf_free(p2p_ie);
2152 return -1;
2153 }
2154
Dmitry Shmidt2fb777c2012-05-02 12:29:53 -07002155 if (msg.p2p_device_addr == NULL) {
2156 wpabuf_free(p2p_ie);
2157 return -1;
Dmitry Shmidtc5ec7f52012-03-06 16:33:24 -08002158 }
2159
Dmitry Shmidt2fb777c2012-05-02 12:29:53 -07002160 os_memcpy(dev_addr, msg.p2p_device_addr, ETH_ALEN);
Dmitry Shmidtc5ec7f52012-03-06 16:33:24 -08002161 wpabuf_free(p2p_ie);
Dmitry Shmidt2fb777c2012-05-02 12:29:53 -07002162 return 0;
Dmitry Shmidtc5ec7f52012-03-06 16:33:24 -08002163}
2164
2165
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07002166static void p2p_clear_go_neg(struct p2p_data *p2p)
2167{
2168 p2p->go_neg_peer = NULL;
2169 p2p_clear_timeout(p2p);
2170 p2p_set_state(p2p, P2P_IDLE);
2171}
2172
2173
2174void p2p_wps_success_cb(struct p2p_data *p2p, const u8 *mac_addr)
2175{
2176 if (p2p->go_neg_peer == NULL) {
2177 wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG,
2178 "P2P: No pending Group Formation - "
2179 "ignore WPS registration success notification");
2180 return; /* No pending Group Formation */
2181 }
2182
2183 if (os_memcmp(mac_addr, p2p->go_neg_peer->intended_addr, ETH_ALEN) !=
2184 0) {
2185 wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG,
2186 "P2P: Ignore WPS registration success notification "
2187 "for " MACSTR " (GO Negotiation peer " MACSTR ")",
2188 MAC2STR(mac_addr),
2189 MAC2STR(p2p->go_neg_peer->intended_addr));
2190 return; /* Ignore unexpected peer address */
2191 }
2192
2193 wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG,
2194 "P2P: Group Formation completed successfully with " MACSTR,
2195 MAC2STR(mac_addr));
2196
2197 p2p_clear_go_neg(p2p);
2198}
2199
2200
2201void p2p_group_formation_failed(struct p2p_data *p2p)
2202{
2203 if (p2p->go_neg_peer == NULL) {
2204 wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG,
2205 "P2P: No pending Group Formation - "
2206 "ignore group formation failure notification");
2207 return; /* No pending Group Formation */
2208 }
2209
2210 wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG,
2211 "P2P: Group Formation failed with " MACSTR,
2212 MAC2STR(p2p->go_neg_peer->intended_addr));
2213
2214 p2p_clear_go_neg(p2p);
2215}
2216
2217
2218struct p2p_data * p2p_init(const struct p2p_config *cfg)
2219{
2220 struct p2p_data *p2p;
2221
2222 if (cfg->max_peers < 1)
2223 return NULL;
2224
2225 p2p = os_zalloc(sizeof(*p2p) + sizeof(*cfg));
2226 if (p2p == NULL)
2227 return NULL;
2228 p2p->cfg = (struct p2p_config *) (p2p + 1);
2229 os_memcpy(p2p->cfg, cfg, sizeof(*cfg));
2230 if (cfg->dev_name)
2231 p2p->cfg->dev_name = os_strdup(cfg->dev_name);
2232 if (cfg->manufacturer)
2233 p2p->cfg->manufacturer = os_strdup(cfg->manufacturer);
2234 if (cfg->model_name)
2235 p2p->cfg->model_name = os_strdup(cfg->model_name);
2236 if (cfg->model_number)
2237 p2p->cfg->model_number = os_strdup(cfg->model_number);
2238 if (cfg->serial_number)
2239 p2p->cfg->serial_number = os_strdup(cfg->serial_number);
2240
2241 p2p->min_disc_int = 1;
2242 p2p->max_disc_int = 3;
2243
2244 os_get_random(&p2p->next_tie_breaker, 1);
2245 p2p->next_tie_breaker &= 0x01;
2246 if (cfg->sd_request)
2247 p2p->dev_capab |= P2P_DEV_CAPAB_SERVICE_DISCOVERY;
2248 p2p->dev_capab |= P2P_DEV_CAPAB_INVITATION_PROCEDURE;
2249 if (cfg->concurrent_operations)
2250 p2p->dev_capab |= P2P_DEV_CAPAB_CONCURRENT_OPER;
2251 p2p->dev_capab |= P2P_DEV_CAPAB_CLIENT_DISCOVERABILITY;
2252
2253 dl_list_init(&p2p->devices);
2254
2255 eloop_register_timeout(P2P_PEER_EXPIRATION_INTERVAL, 0,
2256 p2p_expiration_timeout, p2p, NULL);
2257
2258 return p2p;
2259}
2260
2261
2262void p2p_deinit(struct p2p_data *p2p)
2263{
2264 eloop_cancel_timeout(p2p_expiration_timeout, p2p, NULL);
2265 eloop_cancel_timeout(p2p_ext_listen_timeout, p2p, NULL);
2266 eloop_cancel_timeout(p2p_scan_timeout, p2p, NULL);
2267 p2p_flush(p2p);
2268 p2p_free_req_dev_types(p2p);
2269 os_free(p2p->cfg->dev_name);
2270 os_free(p2p->cfg->manufacturer);
2271 os_free(p2p->cfg->model_name);
2272 os_free(p2p->cfg->model_number);
2273 os_free(p2p->cfg->serial_number);
2274 os_free(p2p->groups);
2275 wpabuf_free(p2p->sd_resp);
2276 os_free(p2p->after_scan_tx);
2277 p2p_remove_wps_vendor_extensions(p2p);
2278 os_free(p2p);
2279}
2280
2281
2282void p2p_flush(struct p2p_data *p2p)
2283{
2284 struct p2p_device *dev, *prev;
2285 p2p_clear_timeout(p2p);
2286 p2p_set_state(p2p, P2P_IDLE);
2287 p2p->start_after_scan = P2P_AFTER_SCAN_NOTHING;
2288 p2p->go_neg_peer = NULL;
2289 eloop_cancel_timeout(p2p_find_timeout, p2p, NULL);
2290 dl_list_for_each_safe(dev, prev, &p2p->devices, struct p2p_device,
2291 list) {
2292 dl_list_del(&dev->list);
2293 p2p_device_free(p2p, dev);
2294 }
2295 p2p_free_sd_queries(p2p);
2296 os_free(p2p->after_scan_tx);
2297 p2p->after_scan_tx = NULL;
2298}
2299
2300
2301int p2p_unauthorize(struct p2p_data *p2p, const u8 *addr)
2302{
2303 struct p2p_device *dev;
2304
2305 dev = p2p_get_device(p2p, addr);
2306 if (dev == NULL)
2307 return -1;
2308
2309 wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG, "P2P: Unauthorizing " MACSTR,
2310 MAC2STR(addr));
2311
2312 if (p2p->go_neg_peer == dev)
2313 p2p->go_neg_peer = NULL;
2314
2315 dev->wps_method = WPS_NOT_READY;
2316 dev->flags &= ~P2P_DEV_WAIT_GO_NEG_RESPONSE;
2317 dev->flags &= ~P2P_DEV_WAIT_GO_NEG_CONFIRM;
2318
2319 /* Check if after_scan_tx is for this peer. If so free it */
2320 if (p2p->after_scan_tx &&
2321 os_memcmp(addr, p2p->after_scan_tx->dst, ETH_ALEN) == 0) {
2322 os_free(p2p->after_scan_tx);
2323 p2p->after_scan_tx = NULL;
2324 }
2325
2326 return 0;
2327}
2328
2329
2330int p2p_set_dev_name(struct p2p_data *p2p, const char *dev_name)
2331{
2332 os_free(p2p->cfg->dev_name);
2333 if (dev_name) {
2334 p2p->cfg->dev_name = os_strdup(dev_name);
2335 if (p2p->cfg->dev_name == NULL)
2336 return -1;
2337 } else
2338 p2p->cfg->dev_name = NULL;
2339 return 0;
2340}
2341
2342
2343int p2p_set_manufacturer(struct p2p_data *p2p, const char *manufacturer)
2344{
2345 os_free(p2p->cfg->manufacturer);
2346 p2p->cfg->manufacturer = NULL;
2347 if (manufacturer) {
2348 p2p->cfg->manufacturer = os_strdup(manufacturer);
2349 if (p2p->cfg->manufacturer == NULL)
2350 return -1;
2351 }
2352
2353 return 0;
2354}
2355
2356
2357int p2p_set_model_name(struct p2p_data *p2p, const char *model_name)
2358{
2359 os_free(p2p->cfg->model_name);
2360 p2p->cfg->model_name = NULL;
2361 if (model_name) {
2362 p2p->cfg->model_name = os_strdup(model_name);
2363 if (p2p->cfg->model_name == NULL)
2364 return -1;
2365 }
2366
2367 return 0;
2368}
2369
2370
2371int p2p_set_model_number(struct p2p_data *p2p, const char *model_number)
2372{
2373 os_free(p2p->cfg->model_number);
2374 p2p->cfg->model_number = NULL;
2375 if (model_number) {
2376 p2p->cfg->model_number = os_strdup(model_number);
2377 if (p2p->cfg->model_number == NULL)
2378 return -1;
2379 }
2380
2381 return 0;
2382}
2383
2384
2385int p2p_set_serial_number(struct p2p_data *p2p, const char *serial_number)
2386{
2387 os_free(p2p->cfg->serial_number);
2388 p2p->cfg->serial_number = NULL;
2389 if (serial_number) {
2390 p2p->cfg->serial_number = os_strdup(serial_number);
2391 if (p2p->cfg->serial_number == NULL)
2392 return -1;
2393 }
2394
2395 return 0;
2396}
2397
2398
2399void p2p_set_config_methods(struct p2p_data *p2p, u16 config_methods)
2400{
2401 p2p->cfg->config_methods = config_methods;
2402}
2403
2404
2405void p2p_set_uuid(struct p2p_data *p2p, const u8 *uuid)
2406{
2407 os_memcpy(p2p->cfg->uuid, uuid, 16);
2408}
2409
2410
2411int p2p_set_pri_dev_type(struct p2p_data *p2p, const u8 *pri_dev_type)
2412{
2413 os_memcpy(p2p->cfg->pri_dev_type, pri_dev_type, 8);
2414 return 0;
2415}
2416
2417
2418int p2p_set_sec_dev_types(struct p2p_data *p2p, const u8 dev_types[][8],
2419 size_t num_dev_types)
2420{
2421 if (num_dev_types > P2P_SEC_DEVICE_TYPES)
2422 num_dev_types = P2P_SEC_DEVICE_TYPES;
2423 p2p->cfg->num_sec_dev_types = num_dev_types;
2424 os_memcpy(p2p->cfg->sec_dev_type, dev_types, num_dev_types * 8);
2425 return 0;
2426}
2427
2428
2429void p2p_remove_wps_vendor_extensions(struct p2p_data *p2p)
2430{
2431 int i;
2432
2433 for (i = 0; i < P2P_MAX_WPS_VENDOR_EXT; i++) {
2434 wpabuf_free(p2p->wps_vendor_ext[i]);
2435 p2p->wps_vendor_ext[i] = NULL;
2436 }
2437}
2438
2439
2440int p2p_add_wps_vendor_extension(struct p2p_data *p2p,
2441 const struct wpabuf *vendor_ext)
2442{
2443 int i;
2444
2445 if (vendor_ext == NULL)
2446 return -1;
2447
2448 for (i = 0; i < P2P_MAX_WPS_VENDOR_EXT; i++) {
2449 if (p2p->wps_vendor_ext[i] == NULL)
2450 break;
2451 }
2452 if (i >= P2P_MAX_WPS_VENDOR_EXT)
2453 return -1;
2454
2455 p2p->wps_vendor_ext[i] = wpabuf_dup(vendor_ext);
2456 if (p2p->wps_vendor_ext[i] == NULL)
2457 return -1;
2458
2459 return 0;
2460}
2461
2462
2463int p2p_set_country(struct p2p_data *p2p, const char *country)
2464{
2465 os_memcpy(p2p->cfg->country, country, 3);
2466 return 0;
2467}
2468
2469
2470void p2p_continue_find(struct p2p_data *p2p)
2471{
2472 struct p2p_device *dev;
2473 p2p_set_state(p2p, P2P_SEARCH);
2474 dl_list_for_each(dev, &p2p->devices, struct p2p_device, list) {
2475 if (dev->flags & P2P_DEV_SD_SCHEDULE) {
2476 if (p2p_start_sd(p2p, dev) == 0)
2477 return;
2478 else
2479 break;
2480 } else if (dev->req_config_methods &&
2481 !(dev->flags & P2P_DEV_PD_FOR_JOIN)) {
2482 wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG, "P2P: Send "
Dmitry Shmidt1f69aa52012-01-24 16:10:04 -08002483 "pending Provision Discovery Request to "
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07002484 MACSTR " (config methods 0x%x)",
2485 MAC2STR(dev->info.p2p_device_addr),
2486 dev->req_config_methods);
Dmitry Shmidt1f69aa52012-01-24 16:10:04 -08002487 if (p2p_send_prov_disc_req(p2p, dev, 0, 0) == 0)
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07002488 return;
2489 }
2490 }
2491
2492 p2p_listen_in_find(p2p);
2493}
2494
2495
2496static void p2p_sd_cb(struct p2p_data *p2p, int success)
2497{
2498 wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG,
2499 "P2P: Service Discovery Query TX callback: success=%d",
2500 success);
2501 p2p->pending_action_state = P2P_NO_PENDING_ACTION;
2502
2503 if (!success) {
2504 if (p2p->sd_peer) {
2505 p2p->sd_peer->flags &= ~P2P_DEV_SD_SCHEDULE;
2506 p2p->sd_peer = NULL;
2507 }
2508 p2p_continue_find(p2p);
2509 return;
2510 }
2511
2512 if (p2p->sd_peer == NULL) {
2513 wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG,
2514 "P2P: No SD peer entry known");
2515 p2p_continue_find(p2p);
2516 return;
2517 }
2518
2519 /* Wait for response from the peer */
2520 p2p_set_state(p2p, P2P_SD_DURING_FIND);
2521 p2p_set_timeout(p2p, 0, 200000);
2522}
2523
Jouni Malinen75ecf522011-06-27 15:19:46 -07002524
2525/**
2526 * p2p_retry_pd - Retry any pending provision disc requests in IDLE state
2527 * @p2p: P2P module context from p2p_init()
2528 */
Dmitry Shmidt1f69aa52012-01-24 16:10:04 -08002529static void p2p_retry_pd(struct p2p_data *p2p)
Jouni Malinen75ecf522011-06-27 15:19:46 -07002530{
2531 struct p2p_device *dev;
2532
2533 if (p2p->state != P2P_IDLE)
2534 return;
2535
2536 /*
2537 * Retry the prov disc req attempt only for the peer that the user had
2538 * requested for and provided a join has not been initiated on it
2539 * in the meantime.
2540 */
2541
2542 dl_list_for_each(dev, &p2p->devices, struct p2p_device, list) {
2543 if (os_memcmp(p2p->pending_pd_devaddr,
2544 dev->info.p2p_device_addr, ETH_ALEN) != 0)
2545 continue;
2546 if (!dev->req_config_methods)
2547 continue;
2548 if (dev->flags & P2P_DEV_PD_FOR_JOIN)
2549 continue;
2550
2551 wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG, "P2P: Send "
Dmitry Shmidt1f69aa52012-01-24 16:10:04 -08002552 "pending Provision Discovery Request to "
Jouni Malinen75ecf522011-06-27 15:19:46 -07002553 MACSTR " (config methods 0x%x)",
2554 MAC2STR(dev->info.p2p_device_addr),
2555 dev->req_config_methods);
Dmitry Shmidt1f69aa52012-01-24 16:10:04 -08002556 p2p_send_prov_disc_req(p2p, dev, 0, 0);
Jouni Malinen75ecf522011-06-27 15:19:46 -07002557 return;
2558 }
2559}
2560
2561
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07002562static void p2p_prov_disc_cb(struct p2p_data *p2p, int success)
2563{
2564 wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG,
2565 "P2P: Provision Discovery Request TX callback: success=%d",
2566 success);
Jouni Malinen75ecf522011-06-27 15:19:46 -07002567
2568 /*
2569 * Postpone resetting the pending action state till after we actually
2570 * time out. This allows us to take some action like notifying any
2571 * interested parties about no response to the request.
2572 *
2573 * When the timer (below) goes off we check in IDLE, SEARCH, or
2574 * LISTEN_ONLY state, which are the only allowed states to issue a PD
2575 * requests in, if this was still pending and then raise notification.
2576 */
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07002577
2578 if (!success) {
Jouni Malinen75ecf522011-06-27 15:19:46 -07002579 p2p->pending_action_state = P2P_NO_PENDING_ACTION;
2580
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07002581 if (p2p->state != P2P_IDLE)
2582 p2p_continue_find(p2p);
Jouni Malinen75ecf522011-06-27 15:19:46 -07002583 else if (p2p->user_initiated_pd) {
2584 p2p->pending_action_state = P2P_PENDING_PD;
2585 p2p_set_timeout(p2p, 0, 300000);
2586 }
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07002587 return;
2588 }
2589
Jouni Malinen75ecf522011-06-27 15:19:46 -07002590 /*
2591 * This postponing, of resetting pending_action_state, needs to be
2592 * done only for user initiated PD requests and not internal ones.
2593 */
2594 if (p2p->user_initiated_pd)
2595 p2p->pending_action_state = P2P_PENDING_PD;
2596 else
2597 p2p->pending_action_state = P2P_NO_PENDING_ACTION;
2598
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07002599 /* Wait for response from the peer */
2600 if (p2p->state == P2P_SEARCH)
2601 p2p_set_state(p2p, P2P_PD_DURING_FIND);
2602 p2p_set_timeout(p2p, 0, 200000);
2603}
2604
2605
2606int p2p_scan_res_handler(struct p2p_data *p2p, const u8 *bssid, int freq,
2607 int level, const u8 *ies, size_t ies_len)
2608{
2609 p2p_add_device(p2p, bssid, freq, level, ies, ies_len);
2610
2611 if (p2p->go_neg_peer && p2p->state == P2P_SEARCH &&
2612 os_memcmp(p2p->go_neg_peer->info.p2p_device_addr, bssid, ETH_ALEN)
2613 == 0) {
2614 wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG,
2615 "P2P: Found GO Negotiation peer - try to start GO "
2616 "negotiation");
2617 p2p_connect_send(p2p, p2p->go_neg_peer);
2618 return 1;
2619 }
2620
2621 return 0;
2622}
2623
2624
2625void p2p_scan_res_handled(struct p2p_data *p2p)
2626{
2627 if (!p2p->p2p_scan_running) {
2628 wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG, "P2P: p2p_scan was not "
2629 "running, but scan results received");
2630 }
2631 p2p->p2p_scan_running = 0;
2632 eloop_cancel_timeout(p2p_scan_timeout, p2p, NULL);
2633
2634 if (p2p_run_after_scan(p2p))
2635 return;
2636 if (p2p->state == P2P_SEARCH)
2637 p2p_continue_find(p2p);
2638}
2639
2640
Dmitry Shmidtc5ec7f52012-03-06 16:33:24 -08002641void p2p_scan_ie(struct p2p_data *p2p, struct wpabuf *ies, const u8 *dev_id)
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07002642{
2643 u8 *len = p2p_buf_add_ie_hdr(ies);
2644 p2p_buf_add_capability(ies, p2p->dev_capab, 0);
Dmitry Shmidtc5ec7f52012-03-06 16:33:24 -08002645 if (dev_id)
2646 p2p_buf_add_device_id(ies, dev_id);
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07002647 if (p2p->cfg->reg_class && p2p->cfg->channel)
2648 p2p_buf_add_listen_channel(ies, p2p->cfg->country,
2649 p2p->cfg->reg_class,
2650 p2p->cfg->channel);
2651 if (p2p->ext_listen_interval)
2652 p2p_buf_add_ext_listen_timing(ies, p2p->ext_listen_period,
2653 p2p->ext_listen_interval);
2654 /* TODO: p2p_buf_add_operating_channel() if GO */
2655 p2p_buf_update_ie_hdr(ies, len);
2656}
2657
2658
Dmitry Shmidt1f69aa52012-01-24 16:10:04 -08002659size_t p2p_scan_ie_buf_len(struct p2p_data *p2p)
2660{
2661 return 100;
2662}
2663
2664
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07002665int p2p_ie_text(struct wpabuf *p2p_ie, char *buf, char *end)
2666{
2667 return p2p_attr_text(p2p_ie, buf, end);
2668}
2669
2670
2671static void p2p_go_neg_req_cb(struct p2p_data *p2p, int success)
2672{
2673 struct p2p_device *dev = p2p->go_neg_peer;
2674
2675 wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG,
2676 "P2P: GO Negotiation Request TX callback: success=%d",
2677 success);
2678
2679 if (dev == NULL) {
2680 wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG,
2681 "P2P: No pending GO Negotiation");
2682 return;
2683 }
2684
2685 if (success) {
2686 dev->go_neg_req_sent++;
2687 if (dev->flags & P2P_DEV_USER_REJECTED) {
2688 p2p_set_state(p2p, P2P_IDLE);
2689 return;
2690 }
2691 }
2692
2693 if (!success &&
2694 (dev->info.dev_capab & P2P_DEV_CAPAB_CLIENT_DISCOVERABILITY) &&
2695 !is_zero_ether_addr(dev->member_in_go_dev)) {
2696 wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG,
2697 "P2P: Peer " MACSTR " did not acknowledge request - "
2698 "try to use device discoverability through its GO",
2699 MAC2STR(dev->info.p2p_device_addr));
2700 p2p->cfg->send_action_done(p2p->cfg->cb_ctx);
2701 p2p_send_dev_disc_req(p2p, dev);
2702 return;
2703 }
2704
2705 /*
2706 * Use P2P find, if needed, to find the other device from its listen
2707 * channel.
2708 */
2709 p2p_set_state(p2p, P2P_CONNECT);
2710 p2p_set_timeout(p2p, 0, 100000);
2711}
2712
2713
2714static void p2p_go_neg_resp_cb(struct p2p_data *p2p, int success)
2715{
2716 wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG,
2717 "P2P: GO Negotiation Response TX callback: success=%d",
2718 success);
2719 if (!p2p->go_neg_peer && p2p->state == P2P_PROVISIONING) {
2720 wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG,
2721 "P2P: Ignore TX callback event - GO Negotiation is "
2722 "not running anymore");
2723 return;
2724 }
2725 p2p_set_state(p2p, P2P_CONNECT);
2726 p2p_set_timeout(p2p, 0, 100000);
2727}
2728
2729
2730static void p2p_go_neg_resp_failure_cb(struct p2p_data *p2p, int success)
2731{
2732 wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG,
2733 "P2P: GO Negotiation Response (failure) TX callback: "
2734 "success=%d", success);
2735 if (p2p->go_neg_peer && p2p->go_neg_peer->status != P2P_SC_SUCCESS) {
2736 p2p_go_neg_failed(p2p, p2p->go_neg_peer,
2737 p2p->go_neg_peer->status);
2738 }
2739}
2740
2741
2742static void p2p_go_neg_conf_cb(struct p2p_data *p2p,
2743 enum p2p_send_action_result result)
2744{
2745 struct p2p_device *dev;
2746
2747 wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG,
2748 "P2P: GO Negotiation Confirm TX callback: result=%d",
2749 result);
2750 p2p->cfg->send_action_done(p2p->cfg->cb_ctx);
2751 if (result == P2P_SEND_ACTION_FAILED) {
2752 p2p_go_neg_failed(p2p, p2p->go_neg_peer, -1);
2753 return;
2754 }
2755 if (result == P2P_SEND_ACTION_NO_ACK) {
2756 /*
2757 * It looks like the TX status for GO Negotiation Confirm is
2758 * often showing failure even when the peer has actually
2759 * received the frame. Since the peer may change channels
2760 * immediately after having received the frame, we may not see
2761 * an Ack for retries, so just dropping a single frame may
2762 * trigger this. To allow the group formation to succeed if the
2763 * peer did indeed receive the frame, continue regardless of
2764 * the TX status.
2765 */
2766 wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG,
2767 "P2P: Assume GO Negotiation Confirm TX was actually "
2768 "received by the peer even though Ack was not "
2769 "reported");
2770 }
2771
2772 dev = p2p->go_neg_peer;
2773 if (dev == NULL)
2774 return;
2775
2776 p2p_go_complete(p2p, dev);
2777}
2778
2779
2780void p2p_send_action_cb(struct p2p_data *p2p, unsigned int freq, const u8 *dst,
2781 const u8 *src, const u8 *bssid,
2782 enum p2p_send_action_result result)
2783{
2784 enum p2p_pending_action_state state;
2785 int success;
2786
2787 wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG,
2788 "P2P: Action frame TX callback (state=%d freq=%u dst=" MACSTR
2789 " src=" MACSTR " bssid=" MACSTR " result=%d",
2790 p2p->pending_action_state, freq, MAC2STR(dst), MAC2STR(src),
2791 MAC2STR(bssid), result);
2792 success = result == P2P_SEND_ACTION_SUCCESS;
2793 state = p2p->pending_action_state;
2794 p2p->pending_action_state = P2P_NO_PENDING_ACTION;
2795 switch (state) {
2796 case P2P_NO_PENDING_ACTION:
2797 break;
2798 case P2P_PENDING_GO_NEG_REQUEST:
2799 p2p_go_neg_req_cb(p2p, success);
2800 break;
2801 case P2P_PENDING_GO_NEG_RESPONSE:
2802 p2p_go_neg_resp_cb(p2p, success);
2803 break;
2804 case P2P_PENDING_GO_NEG_RESPONSE_FAILURE:
2805 p2p_go_neg_resp_failure_cb(p2p, success);
2806 break;
2807 case P2P_PENDING_GO_NEG_CONFIRM:
2808 p2p_go_neg_conf_cb(p2p, result);
2809 break;
2810 case P2P_PENDING_SD:
2811 p2p_sd_cb(p2p, success);
2812 break;
2813 case P2P_PENDING_PD:
2814 p2p_prov_disc_cb(p2p, success);
2815 break;
2816 case P2P_PENDING_INVITATION_REQUEST:
2817 p2p_invitation_req_cb(p2p, success);
2818 break;
2819 case P2P_PENDING_INVITATION_RESPONSE:
2820 p2p_invitation_resp_cb(p2p, success);
2821 break;
2822 case P2P_PENDING_DEV_DISC_REQUEST:
2823 p2p_dev_disc_req_cb(p2p, success);
2824 break;
2825 case P2P_PENDING_DEV_DISC_RESPONSE:
2826 p2p_dev_disc_resp_cb(p2p, success);
2827 break;
2828 case P2P_PENDING_GO_DISC_REQ:
2829 p2p_go_disc_req_cb(p2p, success);
2830 break;
2831 }
2832}
2833
2834
2835void p2p_listen_cb(struct p2p_data *p2p, unsigned int freq,
2836 unsigned int duration)
2837{
2838 if (freq == p2p->pending_client_disc_freq) {
2839 wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG,
2840 "P2P: Client discoverability remain-awake completed");
2841 p2p->pending_client_disc_freq = 0;
2842 return;
2843 }
2844
2845 if (freq != p2p->pending_listen_freq) {
2846 wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG,
2847 "P2P: Unexpected listen callback for freq=%u "
2848 "duration=%u (pending_listen_freq=%u)",
2849 freq, duration, p2p->pending_listen_freq);
2850 return;
2851 }
2852
2853 wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG,
2854 "P2P: Starting Listen timeout(%u,%u) on freq=%u based on "
2855 "callback",
2856 p2p->pending_listen_sec, p2p->pending_listen_usec,
2857 p2p->pending_listen_freq);
2858 p2p->in_listen = 1;
2859 p2p->drv_in_listen = freq;
2860 if (p2p->pending_listen_sec || p2p->pending_listen_usec) {
2861 /*
2862 * Add 20 msec extra wait to avoid race condition with driver
2863 * remain-on-channel end event, i.e., give driver more time to
2864 * complete the operation before our timeout expires.
2865 */
2866 p2p_set_timeout(p2p, p2p->pending_listen_sec,
2867 p2p->pending_listen_usec + 20000);
2868 }
2869
2870 p2p->pending_listen_freq = 0;
2871}
2872
2873
2874int p2p_listen_end(struct p2p_data *p2p, unsigned int freq)
2875{
2876 wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG, "P2P: Driver ended Listen "
2877 "state (freq=%u)", freq);
2878 p2p->drv_in_listen = 0;
2879 if (p2p->in_listen)
2880 return 0; /* Internal timeout will trigger the next step */
2881
2882 if (p2p->state == P2P_CONNECT_LISTEN && p2p->go_neg_peer) {
2883 if (p2p->go_neg_peer->connect_reqs >= 120) {
2884 wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG,
2885 "P2P: Timeout on sending GO Negotiation "
2886 "Request without getting response");
2887 p2p_go_neg_failed(p2p, p2p->go_neg_peer, -1);
2888 return 0;
2889 }
2890
2891 p2p_set_state(p2p, P2P_CONNECT);
2892 p2p_connect_send(p2p, p2p->go_neg_peer);
2893 return 1;
2894 } else if (p2p->state == P2P_SEARCH) {
Dmitry Shmidtc5ec7f52012-03-06 16:33:24 -08002895 if (p2p->p2p_scan_running) {
2896 /*
2897 * Search is already in progress. This can happen if
2898 * an Action frame RX is reported immediately after
2899 * the end of a remain-on-channel operation and the
2900 * response frame to that is sent using an offchannel
2901 * operation while in p2p_find. Avoid an attempt to
2902 * restart a scan here.
2903 */
2904 wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG, "P2P: p2p_scan "
2905 "already in progress - do not try to start a "
2906 "new one");
2907 return 1;
2908 }
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07002909 p2p_search(p2p);
2910 return 1;
2911 }
2912
2913 return 0;
2914}
2915
2916
2917static void p2p_timeout_connect(struct p2p_data *p2p)
2918{
2919 p2p->cfg->send_action_done(p2p->cfg->cb_ctx);
2920 p2p_set_state(p2p, P2P_CONNECT_LISTEN);
2921 p2p_listen_in_find(p2p);
2922}
2923
2924
2925static void p2p_timeout_connect_listen(struct p2p_data *p2p)
2926{
2927 if (p2p->go_neg_peer) {
2928 if (p2p->drv_in_listen) {
2929 wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG, "P2P: Driver is "
2930 "still in Listen state; wait for it to "
2931 "complete");
2932 return;
2933 }
2934
2935 if (p2p->go_neg_peer->connect_reqs >= 120) {
2936 wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG,
2937 "P2P: Timeout on sending GO Negotiation "
2938 "Request without getting response");
2939 p2p_go_neg_failed(p2p, p2p->go_neg_peer, -1);
2940 return;
2941 }
2942
2943 p2p_set_state(p2p, P2P_CONNECT);
2944 p2p_connect_send(p2p, p2p->go_neg_peer);
2945 } else
2946 p2p_set_state(p2p, P2P_IDLE);
2947}
2948
2949
2950static void p2p_timeout_wait_peer_connect(struct p2p_data *p2p)
2951{
2952 /*
2953 * TODO: could remain constantly in Listen state for some time if there
2954 * are no other concurrent uses for the radio. For now, go to listen
2955 * state once per second to give other uses a chance to use the radio.
2956 */
2957 p2p_set_state(p2p, P2P_WAIT_PEER_IDLE);
Dmitry Shmidt1f69aa52012-01-24 16:10:04 -08002958 p2p_set_timeout(p2p, 0, 500000);
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07002959}
2960
2961
2962static void p2p_timeout_wait_peer_idle(struct p2p_data *p2p)
2963{
2964 struct p2p_device *dev = p2p->go_neg_peer;
2965
2966 if (dev == NULL) {
2967 wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG,
2968 "P2P: Unknown GO Neg peer - stop GO Neg wait");
2969 return;
2970 }
2971
2972 dev->wait_count++;
2973 if (dev->wait_count >= 120) {
2974 wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG,
2975 "P2P: Timeout on waiting peer to become ready for GO "
2976 "Negotiation");
2977 p2p_go_neg_failed(p2p, dev, -1);
2978 return;
2979 }
2980
2981 wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG,
2982 "P2P: Go to Listen state while waiting for the peer to become "
2983 "ready for GO Negotiation");
2984 p2p_set_state(p2p, P2P_WAIT_PEER_CONNECT);
2985 p2p_listen_in_find(p2p);
2986}
2987
2988
2989static void p2p_timeout_sd_during_find(struct p2p_data *p2p)
2990{
2991 wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG,
2992 "P2P: Service Discovery Query timeout");
2993 if (p2p->sd_peer) {
2994 p2p->cfg->send_action_done(p2p->cfg->cb_ctx);
2995 p2p->sd_peer->flags &= ~P2P_DEV_SD_SCHEDULE;
2996 p2p->sd_peer = NULL;
2997 }
2998 p2p_continue_find(p2p);
2999}
3000
3001
3002static void p2p_timeout_prov_disc_during_find(struct p2p_data *p2p)
3003{
3004 wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG,
3005 "P2P: Provision Discovery Request timeout");
3006 p2p->cfg->send_action_done(p2p->cfg->cb_ctx);
3007 p2p_continue_find(p2p);
3008}
3009
3010
Jouni Malinen75ecf522011-06-27 15:19:46 -07003011static void p2p_timeout_prov_disc_req(struct p2p_data *p2p)
3012{
3013 p2p->pending_action_state = P2P_NO_PENDING_ACTION;
3014
3015 /*
3016 * For user initiated PD requests that we have not gotten any responses
3017 * for while in IDLE state, we retry them a couple of times before
3018 * giving up.
3019 */
3020 if (!p2p->user_initiated_pd)
3021 return;
3022
3023 wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG,
3024 "P2P: User initiated Provision Discovery Request timeout");
3025
3026 if (p2p->pd_retries) {
3027 p2p->pd_retries--;
3028 p2p_retry_pd(p2p);
3029 } else {
3030 if (p2p->cfg->prov_disc_fail)
3031 p2p->cfg->prov_disc_fail(p2p->cfg->cb_ctx,
3032 p2p->pending_pd_devaddr,
3033 P2P_PROV_DISC_TIMEOUT);
3034 p2p_reset_pending_pd(p2p);
3035 }
3036}
3037
3038
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07003039static void p2p_timeout_invite(struct p2p_data *p2p)
3040{
3041 p2p->cfg->send_action_done(p2p->cfg->cb_ctx);
3042 p2p_set_state(p2p, P2P_INVITE_LISTEN);
3043 if (p2p->inv_role == P2P_INVITE_ROLE_ACTIVE_GO) {
3044 /*
3045 * Better remain on operating channel instead of listen channel
3046 * when running a group.
3047 */
3048 wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG, "P2P: Inviting in "
3049 "active GO role - wait on operating channel");
3050 p2p_set_timeout(p2p, 0, 100000);
3051 return;
3052 }
3053 p2p_listen_in_find(p2p);
3054}
3055
3056
3057static void p2p_timeout_invite_listen(struct p2p_data *p2p)
3058{
3059 if (p2p->invite_peer && p2p->invite_peer->invitation_reqs < 100) {
3060 p2p_set_state(p2p, P2P_INVITE);
3061 p2p_invite_send(p2p, p2p->invite_peer,
3062 p2p->invite_go_dev_addr);
3063 } else {
3064 if (p2p->invite_peer) {
3065 wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG,
3066 "P2P: Invitation Request retry limit reached");
3067 if (p2p->cfg->invitation_result)
3068 p2p->cfg->invitation_result(
3069 p2p->cfg->cb_ctx, -1, NULL);
3070 }
3071 p2p_set_state(p2p, P2P_IDLE);
3072 }
3073}
3074
3075
3076static void p2p_state_timeout(void *eloop_ctx, void *timeout_ctx)
3077{
3078 struct p2p_data *p2p = eloop_ctx;
3079
3080 wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG, "P2P: Timeout (state=%s)",
3081 p2p_state_txt(p2p->state));
3082
3083 p2p->in_listen = 0;
3084
3085 switch (p2p->state) {
3086 case P2P_IDLE:
Jouni Malinen75ecf522011-06-27 15:19:46 -07003087 /* Check if we timed out waiting for PD req */
3088 if (p2p->pending_action_state == P2P_PENDING_PD)
3089 p2p_timeout_prov_disc_req(p2p);
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07003090 break;
3091 case P2P_SEARCH:
Jouni Malinen75ecf522011-06-27 15:19:46 -07003092 /* Check if we timed out waiting for PD req */
3093 if (p2p->pending_action_state == P2P_PENDING_PD)
3094 p2p_timeout_prov_disc_req(p2p);
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07003095 p2p_search(p2p);
3096 break;
3097 case P2P_CONNECT:
3098 p2p_timeout_connect(p2p);
3099 break;
3100 case P2P_CONNECT_LISTEN:
3101 p2p_timeout_connect_listen(p2p);
3102 break;
3103 case P2P_GO_NEG:
3104 break;
3105 case P2P_LISTEN_ONLY:
Jouni Malinen75ecf522011-06-27 15:19:46 -07003106 /* Check if we timed out waiting for PD req */
3107 if (p2p->pending_action_state == P2P_PENDING_PD)
3108 p2p_timeout_prov_disc_req(p2p);
3109
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07003110 if (p2p->ext_listen_only) {
3111 wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG,
3112 "P2P: Extended Listen Timing - Listen State "
3113 "completed");
3114 p2p->ext_listen_only = 0;
3115 p2p_set_state(p2p, P2P_IDLE);
3116 }
3117 break;
3118 case P2P_WAIT_PEER_CONNECT:
3119 p2p_timeout_wait_peer_connect(p2p);
3120 break;
3121 case P2P_WAIT_PEER_IDLE:
3122 p2p_timeout_wait_peer_idle(p2p);
3123 break;
3124 case P2P_SD_DURING_FIND:
3125 p2p_timeout_sd_during_find(p2p);
3126 break;
3127 case P2P_PROVISIONING:
3128 break;
3129 case P2P_PD_DURING_FIND:
3130 p2p_timeout_prov_disc_during_find(p2p);
3131 break;
3132 case P2P_INVITE:
3133 p2p_timeout_invite(p2p);
3134 break;
3135 case P2P_INVITE_LISTEN:
3136 p2p_timeout_invite_listen(p2p);
3137 break;
Dmitry Shmidt1f69aa52012-01-24 16:10:04 -08003138 case P2P_SEARCH_WHEN_READY:
3139 break;
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07003140 }
3141}
3142
3143
3144int p2p_reject(struct p2p_data *p2p, const u8 *peer_addr)
3145{
3146 struct p2p_device *dev;
3147
3148 dev = p2p_get_device(p2p, peer_addr);
3149 wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG, "P2P: Local request to reject "
3150 "connection attempts by peer " MACSTR, MAC2STR(peer_addr));
3151 if (dev == NULL) {
3152 wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG, "P2P: Peer " MACSTR
3153 " unknown", MAC2STR(peer_addr));
3154 return -1;
3155 }
3156 dev->status = P2P_SC_FAIL_REJECTED_BY_USER;
3157 dev->flags |= P2P_DEV_USER_REJECTED;
3158 return 0;
3159}
3160
3161
Dmitry Shmidt1f69aa52012-01-24 16:10:04 -08003162const char * p2p_wps_method_text(enum p2p_wps_method method)
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07003163{
3164 switch (method) {
3165 case WPS_NOT_READY:
3166 return "not-ready";
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07003167 case WPS_PIN_DISPLAY:
3168 return "Display";
3169 case WPS_PIN_KEYPAD:
3170 return "Keypad";
3171 case WPS_PBC:
3172 return "PBC";
3173 }
3174
3175 return "??";
3176}
3177
3178
3179static const char * p2p_go_state_text(enum p2p_go_state go_state)
3180{
3181 switch (go_state) {
3182 case UNKNOWN_GO:
3183 return "unknown";
3184 case LOCAL_GO:
3185 return "local";
3186 case REMOTE_GO:
3187 return "remote";
3188 }
3189
3190 return "??";
3191}
3192
3193
Dmitry Shmidt1f69aa52012-01-24 16:10:04 -08003194const struct p2p_peer_info * p2p_get_peer_info(struct p2p_data *p2p,
3195 const u8 *addr, int next)
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07003196{
3197 struct p2p_device *dev;
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07003198
3199 if (addr)
3200 dev = p2p_get_device(p2p, addr);
3201 else
3202 dev = dl_list_first(&p2p->devices, struct p2p_device, list);
3203
3204 if (dev && next) {
3205 dev = dl_list_first(&dev->list, struct p2p_device, list);
3206 if (&dev->list == &p2p->devices)
3207 dev = NULL;
3208 }
3209
3210 if (dev == NULL)
Dmitry Shmidt1f69aa52012-01-24 16:10:04 -08003211 return NULL;
3212
3213 return &dev->info;
3214}
3215
3216
3217int p2p_get_peer_info_txt(const struct p2p_peer_info *info,
3218 char *buf, size_t buflen)
3219{
3220 struct p2p_device *dev;
3221 int res;
3222 char *pos, *end;
3223 struct os_time now;
3224
3225 if (info == NULL)
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07003226 return -1;
3227
Dmitry Shmidt1f69aa52012-01-24 16:10:04 -08003228 dev = (struct p2p_device *) (((u8 *) info) -
3229 offsetof(struct p2p_device, info));
3230
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07003231 pos = buf;
3232 end = buf + buflen;
3233
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07003234 os_get_time(&now);
3235 res = os_snprintf(pos, end - pos,
3236 "age=%d\n"
3237 "listen_freq=%d\n"
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07003238 "wps_method=%s\n"
3239 "interface_addr=" MACSTR "\n"
3240 "member_in_go_dev=" MACSTR "\n"
3241 "member_in_go_iface=" MACSTR "\n"
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07003242 "go_neg_req_sent=%d\n"
3243 "go_state=%s\n"
3244 "dialog_token=%u\n"
3245 "intended_addr=" MACSTR "\n"
3246 "country=%c%c\n"
3247 "oper_freq=%d\n"
3248 "req_config_methods=0x%x\n"
3249 "flags=%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s\n"
3250 "status=%d\n"
3251 "wait_count=%u\n"
3252 "invitation_reqs=%u\n",
3253 (int) (now.sec - dev->last_seen.sec),
3254 dev->listen_freq,
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07003255 p2p_wps_method_text(dev->wps_method),
3256 MAC2STR(dev->interface_addr),
3257 MAC2STR(dev->member_in_go_dev),
3258 MAC2STR(dev->member_in_go_iface),
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07003259 dev->go_neg_req_sent,
3260 p2p_go_state_text(dev->go_state),
3261 dev->dialog_token,
3262 MAC2STR(dev->intended_addr),
3263 dev->country[0] ? dev->country[0] : '_',
3264 dev->country[1] ? dev->country[1] : '_',
3265 dev->oper_freq,
3266 dev->req_config_methods,
3267 dev->flags & P2P_DEV_PROBE_REQ_ONLY ?
3268 "[PROBE_REQ_ONLY]" : "",
3269 dev->flags & P2P_DEV_REPORTED ? "[REPORTED]" : "",
3270 dev->flags & P2P_DEV_NOT_YET_READY ?
3271 "[NOT_YET_READY]" : "",
3272 dev->flags & P2P_DEV_SD_INFO ? "[SD_INFO]" : "",
3273 dev->flags & P2P_DEV_SD_SCHEDULE ? "[SD_SCHEDULE]" :
3274 "",
3275 dev->flags & P2P_DEV_PD_PEER_DISPLAY ?
3276 "[PD_PEER_DISPLAY]" : "",
3277 dev->flags & P2P_DEV_PD_PEER_KEYPAD ?
3278 "[PD_PEER_KEYPAD]" : "",
3279 dev->flags & P2P_DEV_USER_REJECTED ?
3280 "[USER_REJECTED]" : "",
3281 dev->flags & P2P_DEV_PEER_WAITING_RESPONSE ?
3282 "[PEER_WAITING_RESPONSE]" : "",
3283 dev->flags & P2P_DEV_PREFER_PERSISTENT_GROUP ?
3284 "[PREFER_PERSISTENT_GROUP]" : "",
3285 dev->flags & P2P_DEV_WAIT_GO_NEG_RESPONSE ?
3286 "[WAIT_GO_NEG_RESPONSE]" : "",
3287 dev->flags & P2P_DEV_WAIT_GO_NEG_CONFIRM ?
3288 "[WAIT_GO_NEG_CONFIRM]" : "",
3289 dev->flags & P2P_DEV_GROUP_CLIENT_ONLY ?
3290 "[GROUP_CLIENT_ONLY]" : "",
3291 dev->flags & P2P_DEV_FORCE_FREQ ?
3292 "[FORCE_FREQ]" : "",
3293 dev->flags & P2P_DEV_PD_FOR_JOIN ?
3294 "[PD_FOR_JOIN]" : "",
3295 dev->status,
3296 dev->wait_count,
3297 dev->invitation_reqs);
3298 if (res < 0 || res >= end - pos)
3299 return pos - buf;
3300 pos += res;
3301
3302 if (dev->ext_listen_period) {
3303 res = os_snprintf(pos, end - pos,
3304 "ext_listen_period=%u\n"
3305 "ext_listen_interval=%u\n",
3306 dev->ext_listen_period,
3307 dev->ext_listen_interval);
3308 if (res < 0 || res >= end - pos)
3309 return pos - buf;
3310 pos += res;
3311 }
3312
3313 if (dev->oper_ssid_len) {
3314 res = os_snprintf(pos, end - pos,
3315 "oper_ssid=%s\n",
3316 wpa_ssid_txt(dev->oper_ssid,
3317 dev->oper_ssid_len));
3318 if (res < 0 || res >= end - pos)
3319 return pos - buf;
3320 pos += res;
3321 }
3322
3323 return pos - buf;
3324}
3325
3326
Dmitry Shmidt1f69aa52012-01-24 16:10:04 -08003327int p2p_peer_known(struct p2p_data *p2p, const u8 *addr)
3328{
3329 return p2p_get_device(p2p, addr) != NULL;
3330}
3331
3332
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07003333void p2p_set_client_discoverability(struct p2p_data *p2p, int enabled)
3334{
3335 if (enabled) {
3336 wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG, "P2P: Client "
3337 "discoverability enabled");
3338 p2p->dev_capab |= P2P_DEV_CAPAB_CLIENT_DISCOVERABILITY;
3339 } else {
3340 wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG, "P2P: Client "
3341 "discoverability disabled");
3342 p2p->dev_capab &= ~P2P_DEV_CAPAB_CLIENT_DISCOVERABILITY;
3343 }
3344}
3345
3346
3347static struct wpabuf * p2p_build_presence_req(u32 duration1, u32 interval1,
3348 u32 duration2, u32 interval2)
3349{
3350 struct wpabuf *req;
3351 struct p2p_noa_desc desc1, desc2, *ptr1 = NULL, *ptr2 = NULL;
3352 u8 *len;
3353
3354 req = wpabuf_alloc(100);
3355 if (req == NULL)
3356 return NULL;
3357
3358 if (duration1 || interval1) {
3359 os_memset(&desc1, 0, sizeof(desc1));
3360 desc1.count_type = 1;
3361 desc1.duration = duration1;
3362 desc1.interval = interval1;
3363 ptr1 = &desc1;
3364
3365 if (duration2 || interval2) {
3366 os_memset(&desc2, 0, sizeof(desc2));
3367 desc2.count_type = 2;
3368 desc2.duration = duration2;
3369 desc2.interval = interval2;
3370 ptr2 = &desc2;
3371 }
3372 }
3373
3374 p2p_buf_add_action_hdr(req, P2P_PRESENCE_REQ, 1);
3375 len = p2p_buf_add_ie_hdr(req);
3376 p2p_buf_add_noa(req, 0, 0, 0, ptr1, ptr2);
3377 p2p_buf_update_ie_hdr(req, len);
3378
3379 return req;
3380}
3381
3382
3383int p2p_presence_req(struct p2p_data *p2p, const u8 *go_interface_addr,
3384 const u8 *own_interface_addr, unsigned int freq,
3385 u32 duration1, u32 interval1, u32 duration2,
3386 u32 interval2)
3387{
3388 struct wpabuf *req;
3389
3390 wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG, "P2P: Send Presence Request to "
3391 "GO " MACSTR " (own interface " MACSTR ") freq=%u dur1=%u "
3392 "int1=%u dur2=%u int2=%u",
3393 MAC2STR(go_interface_addr), MAC2STR(own_interface_addr),
3394 freq, duration1, interval1, duration2, interval2);
3395
3396 req = p2p_build_presence_req(duration1, interval1, duration2,
3397 interval2);
3398 if (req == NULL)
3399 return -1;
3400
3401 p2p->pending_action_state = P2P_NO_PENDING_ACTION;
3402 if (p2p_send_action(p2p, freq, go_interface_addr, own_interface_addr,
3403 go_interface_addr,
3404 wpabuf_head(req), wpabuf_len(req), 200) < 0) {
3405 wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG,
3406 "P2P: Failed to send Action frame");
3407 }
3408 wpabuf_free(req);
3409
3410 return 0;
3411}
3412
3413
3414static struct wpabuf * p2p_build_presence_resp(u8 status, const u8 *noa,
3415 size_t noa_len, u8 dialog_token)
3416{
3417 struct wpabuf *resp;
3418 u8 *len;
3419
3420 resp = wpabuf_alloc(100 + noa_len);
3421 if (resp == NULL)
3422 return NULL;
3423
3424 p2p_buf_add_action_hdr(resp, P2P_PRESENCE_RESP, dialog_token);
3425 len = p2p_buf_add_ie_hdr(resp);
3426 p2p_buf_add_status(resp, status);
3427 if (noa) {
3428 wpabuf_put_u8(resp, P2P_ATTR_NOTICE_OF_ABSENCE);
3429 wpabuf_put_le16(resp, noa_len);
3430 wpabuf_put_data(resp, noa, noa_len);
3431 } else
3432 p2p_buf_add_noa(resp, 0, 0, 0, NULL, NULL);
3433 p2p_buf_update_ie_hdr(resp, len);
3434
3435 return resp;
3436}
3437
3438
3439static void p2p_process_presence_req(struct p2p_data *p2p, const u8 *da,
3440 const u8 *sa, const u8 *data, size_t len,
3441 int rx_freq)
3442{
3443 struct p2p_message msg;
3444 u8 status;
3445 struct wpabuf *resp;
3446 size_t g;
3447 struct p2p_group *group = NULL;
3448 int parsed = 0;
3449 u8 noa[50];
3450 int noa_len;
3451
3452 wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG,
3453 "P2P: Received P2P Action - P2P Presence Request");
3454
3455 for (g = 0; g < p2p->num_groups; g++) {
3456 if (os_memcmp(da, p2p_group_get_interface_addr(p2p->groups[g]),
3457 ETH_ALEN) == 0) {
3458 group = p2p->groups[g];
3459 break;
3460 }
3461 }
3462 if (group == NULL) {
3463 wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG,
3464 "P2P: Ignore P2P Presence Request for unknown group "
3465 MACSTR, MAC2STR(da));
3466 return;
3467 }
3468
3469 if (p2p_parse(data, len, &msg) < 0) {
3470 wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG,
3471 "P2P: Failed to parse P2P Presence Request");
3472 status = P2P_SC_FAIL_INVALID_PARAMS;
3473 goto fail;
3474 }
3475 parsed = 1;
3476
3477 if (msg.noa == NULL) {
3478 wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG,
3479 "P2P: No NoA attribute in P2P Presence Request");
3480 status = P2P_SC_FAIL_INVALID_PARAMS;
3481 goto fail;
3482 }
3483
3484 status = p2p_group_presence_req(group, sa, msg.noa, msg.noa_len);
3485
3486fail:
3487 if (p2p->cfg->get_noa)
3488 noa_len = p2p->cfg->get_noa(p2p->cfg->cb_ctx, da, noa,
3489 sizeof(noa));
3490 else
3491 noa_len = -1;
3492 resp = p2p_build_presence_resp(status, noa_len > 0 ? noa : NULL,
3493 noa_len > 0 ? noa_len : 0,
3494 msg.dialog_token);
3495 if (parsed)
3496 p2p_parse_free(&msg);
3497 if (resp == NULL)
3498 return;
3499
3500 p2p->pending_action_state = P2P_NO_PENDING_ACTION;
3501 if (p2p_send_action(p2p, rx_freq, sa, da, da,
3502 wpabuf_head(resp), wpabuf_len(resp), 200) < 0) {
3503 wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG,
3504 "P2P: Failed to send Action frame");
3505 }
3506 wpabuf_free(resp);
3507}
3508
3509
3510static void p2p_process_presence_resp(struct p2p_data *p2p, const u8 *da,
3511 const u8 *sa, const u8 *data, size_t len)
3512{
3513 struct p2p_message msg;
3514
3515 wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG,
3516 "P2P: Received P2P Action - P2P Presence Response");
3517
3518 if (p2p_parse(data, len, &msg) < 0) {
3519 wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG,
3520 "P2P: Failed to parse P2P Presence Response");
3521 return;
3522 }
3523
3524 if (msg.status == NULL || msg.noa == NULL) {
3525 wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG,
3526 "P2P: No Status or NoA attribute in P2P Presence "
3527 "Response");
3528 p2p_parse_free(&msg);
3529 return;
3530 }
3531
3532 if (*msg.status) {
3533 wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG,
3534 "P2P: P2P Presence Request was rejected: status %u",
3535 *msg.status);
3536 p2p_parse_free(&msg);
3537 return;
3538 }
3539
3540 wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG,
3541 "P2P: P2P Presence Request was accepted");
3542 wpa_hexdump(MSG_DEBUG, "P2P: P2P Presence Response - NoA",
3543 msg.noa, msg.noa_len);
3544 /* TODO: process NoA */
3545 p2p_parse_free(&msg);
3546}
3547
3548
3549static void p2p_ext_listen_timeout(void *eloop_ctx, void *timeout_ctx)
3550{
3551 struct p2p_data *p2p = eloop_ctx;
3552
3553 if (p2p->ext_listen_interval) {
3554 /* Schedule next extended listen timeout */
3555 eloop_register_timeout(p2p->ext_listen_interval_sec,
3556 p2p->ext_listen_interval_usec,
3557 p2p_ext_listen_timeout, p2p, NULL);
3558 }
3559
3560 if (p2p->state == P2P_LISTEN_ONLY && p2p->ext_listen_only) {
3561 /*
3562 * This should not really happen, but it looks like the Listen
3563 * command may fail is something else (e.g., a scan) was
3564 * running at an inconvenient time. As a workaround, allow new
3565 * Extended Listen operation to be started.
3566 */
3567 wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG, "P2P: Previous "
3568 "Extended Listen operation had not been completed - "
3569 "try again");
3570 p2p->ext_listen_only = 0;
3571 p2p_set_state(p2p, P2P_IDLE);
3572 }
3573
3574 if (p2p->state != P2P_IDLE) {
3575 wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG, "P2P: Skip Extended "
3576 "Listen timeout in active state (%s)",
3577 p2p_state_txt(p2p->state));
3578 return;
3579 }
3580
3581 wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG, "P2P: Extended Listen timeout");
3582 p2p->ext_listen_only = 1;
3583 if (p2p_listen(p2p, p2p->ext_listen_period) < 0) {
3584 wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG, "P2P: Failed to start "
3585 "Listen state for Extended Listen Timing");
3586 p2p->ext_listen_only = 0;
3587 }
3588}
3589
3590
3591int p2p_ext_listen(struct p2p_data *p2p, unsigned int period,
3592 unsigned int interval)
3593{
3594 if (period > 65535 || interval > 65535 || period > interval ||
3595 (period == 0 && interval > 0) || (period > 0 && interval == 0)) {
3596 wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG,
3597 "P2P: Invalid Extended Listen Timing request: "
3598 "period=%u interval=%u", period, interval);
3599 return -1;
3600 }
3601
3602 eloop_cancel_timeout(p2p_ext_listen_timeout, p2p, NULL);
3603
3604 if (interval == 0) {
3605 wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG,
3606 "P2P: Disabling Extended Listen Timing");
3607 p2p->ext_listen_period = 0;
3608 p2p->ext_listen_interval = 0;
3609 return 0;
3610 }
3611
3612 wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG,
3613 "P2P: Enabling Extended Listen Timing: period %u msec, "
3614 "interval %u msec", period, interval);
3615 p2p->ext_listen_period = period;
3616 p2p->ext_listen_interval = interval;
3617 p2p->ext_listen_interval_sec = interval / 1000;
3618 p2p->ext_listen_interval_usec = (interval % 1000) * 1000;
3619
3620 eloop_register_timeout(p2p->ext_listen_interval_sec,
3621 p2p->ext_listen_interval_usec,
3622 p2p_ext_listen_timeout, p2p, NULL);
3623
3624 return 0;
3625}
3626
3627
3628void p2p_deauth_notif(struct p2p_data *p2p, const u8 *bssid, u16 reason_code,
3629 const u8 *ie, size_t ie_len)
3630{
3631 struct p2p_message msg;
3632
3633 if (bssid == NULL || ie == NULL)
3634 return;
3635
3636 os_memset(&msg, 0, sizeof(msg));
3637 if (p2p_parse_ies(ie, ie_len, &msg))
3638 return;
3639 if (msg.minor_reason_code == NULL)
3640 return;
3641
3642 wpa_msg(p2p->cfg->msg_ctx, MSG_INFO,
3643 "P2P: Deauthentication notification BSSID " MACSTR
3644 " reason_code=%u minor_reason_code=%u",
3645 MAC2STR(bssid), reason_code, *msg.minor_reason_code);
3646
3647 p2p_parse_free(&msg);
3648}
3649
3650
3651void p2p_disassoc_notif(struct p2p_data *p2p, const u8 *bssid, u16 reason_code,
3652 const u8 *ie, size_t ie_len)
3653{
3654 struct p2p_message msg;
3655
3656 if (bssid == NULL || ie == NULL)
3657 return;
3658
3659 os_memset(&msg, 0, sizeof(msg));
3660 if (p2p_parse_ies(ie, ie_len, &msg))
3661 return;
3662 if (msg.minor_reason_code == NULL)
3663 return;
3664
3665 wpa_msg(p2p->cfg->msg_ctx, MSG_INFO,
3666 "P2P: Disassociation notification BSSID " MACSTR
3667 " reason_code=%u minor_reason_code=%u",
3668 MAC2STR(bssid), reason_code, *msg.minor_reason_code);
3669
3670 p2p_parse_free(&msg);
3671}
3672
3673
3674void p2p_set_managed_oper(struct p2p_data *p2p, int enabled)
3675{
3676 if (enabled) {
3677 wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG, "P2P: Managed P2P "
3678 "Device operations enabled");
3679 p2p->dev_capab |= P2P_DEV_CAPAB_INFRA_MANAGED;
3680 } else {
3681 wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG, "P2P: Managed P2P "
3682 "Device operations disabled");
3683 p2p->dev_capab &= ~P2P_DEV_CAPAB_INFRA_MANAGED;
3684 }
3685}
3686
3687
3688int p2p_set_listen_channel(struct p2p_data *p2p, u8 reg_class, u8 channel)
3689{
3690 if (p2p_channel_to_freq(p2p->cfg->country, reg_class, channel) < 0)
3691 return -1;
3692
3693 wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG, "P2P: Set Listen channel: "
3694 "reg_class %u channel %u", reg_class, channel);
3695 p2p->cfg->reg_class = reg_class;
3696 p2p->cfg->channel = channel;
3697
3698 return 0;
3699}
3700
3701
3702int p2p_set_ssid_postfix(struct p2p_data *p2p, const u8 *postfix, size_t len)
3703{
3704 wpa_hexdump_ascii(MSG_DEBUG, "P2P: New SSID postfix", postfix, len);
3705 if (postfix == NULL) {
3706 p2p->cfg->ssid_postfix_len = 0;
3707 return 0;
3708 }
3709 if (len > sizeof(p2p->cfg->ssid_postfix))
3710 return -1;
3711 os_memcpy(p2p->cfg->ssid_postfix, postfix, len);
3712 p2p->cfg->ssid_postfix_len = len;
3713 return 0;
3714}
3715
3716
Jouni Malinen75ecf522011-06-27 15:19:46 -07003717int p2p_set_oper_channel(struct p2p_data *p2p, u8 op_reg_class, u8 op_channel,
3718 int cfg_op_channel)
3719{
3720 if (p2p_channel_to_freq(p2p->cfg->country, op_reg_class, op_channel)
3721 < 0)
3722 return -1;
3723
3724 wpa_msg(p2p->cfg->msg_ctx, MSG_INFO, "P2P: Set Operating channel: "
3725 "reg_class %u channel %u", op_reg_class, op_channel);
3726 p2p->cfg->op_reg_class = op_reg_class;
3727 p2p->cfg->op_channel = op_channel;
3728 p2p->cfg->cfg_op_channel = cfg_op_channel;
3729 return 0;
3730}
3731
3732
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07003733int p2p_get_interface_addr(struct p2p_data *p2p, const u8 *dev_addr,
3734 u8 *iface_addr)
3735{
3736 struct p2p_device *dev = p2p_get_device(p2p, dev_addr);
3737 if (dev == NULL || is_zero_ether_addr(dev->interface_addr))
3738 return -1;
3739 os_memcpy(iface_addr, dev->interface_addr, ETH_ALEN);
3740 return 0;
3741}
3742
3743
3744int p2p_get_dev_addr(struct p2p_data *p2p, const u8 *iface_addr,
3745 u8 *dev_addr)
3746{
3747 struct p2p_device *dev = p2p_get_device_interface(p2p, iface_addr);
3748 if (dev == NULL)
3749 return -1;
3750 os_memcpy(dev_addr, dev->info.p2p_device_addr, ETH_ALEN);
3751 return 0;
3752}
3753
3754
3755void p2p_set_peer_filter(struct p2p_data *p2p, const u8 *addr)
3756{
3757 os_memcpy(p2p->peer_filter, addr, ETH_ALEN);
3758 if (is_zero_ether_addr(p2p->peer_filter))
3759 wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG, "P2P: Disable peer "
3760 "filter");
3761 else
3762 wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG, "P2P: Enable peer "
3763 "filter for " MACSTR, MAC2STR(p2p->peer_filter));
3764}
3765
3766
3767void p2p_set_cross_connect(struct p2p_data *p2p, int enabled)
3768{
3769 wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG, "P2P: Cross connection %s",
3770 enabled ? "enabled" : "disabled");
3771 if (p2p->cross_connect == enabled)
3772 return;
3773 p2p->cross_connect = enabled;
3774 /* TODO: may need to tear down any action group where we are GO(?) */
3775}
3776
3777
3778int p2p_get_oper_freq(struct p2p_data *p2p, const u8 *iface_addr)
3779{
3780 struct p2p_device *dev = p2p_get_device_interface(p2p, iface_addr);
3781 if (dev == NULL)
3782 return -1;
3783 if (dev->oper_freq <= 0)
3784 return -1;
3785 return dev->oper_freq;
3786}
3787
3788
3789void p2p_set_intra_bss_dist(struct p2p_data *p2p, int enabled)
3790{
3791 wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG, "P2P: Intra BSS distribution %s",
3792 enabled ? "enabled" : "disabled");
3793 p2p->cfg->p2p_intra_bss = enabled;
3794}
3795
3796
3797void p2p_update_channel_list(struct p2p_data *p2p, struct p2p_channels *chan)
3798{
3799 wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG, "P2P: Update channel list");
3800 os_memcpy(&p2p->cfg->channels, chan, sizeof(struct p2p_channels));
3801}
3802
3803
3804int p2p_send_action(struct p2p_data *p2p, unsigned int freq, const u8 *dst,
3805 const u8 *src, const u8 *bssid, const u8 *buf,
3806 size_t len, unsigned int wait_time)
3807{
3808 if (p2p->p2p_scan_running) {
3809 wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG, "P2P: Delay Action "
3810 "frame TX until p2p_scan completes");
3811 if (p2p->after_scan_tx) {
3812 wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG, "P2P: Dropped "
3813 "previous pending Action frame TX");
3814 os_free(p2p->after_scan_tx);
3815 }
3816 p2p->after_scan_tx = os_malloc(sizeof(*p2p->after_scan_tx) +
3817 len);
3818 if (p2p->after_scan_tx == NULL)
3819 return -1;
3820 p2p->after_scan_tx->freq = freq;
3821 os_memcpy(p2p->after_scan_tx->dst, dst, ETH_ALEN);
3822 os_memcpy(p2p->after_scan_tx->src, src, ETH_ALEN);
3823 os_memcpy(p2p->after_scan_tx->bssid, bssid, ETH_ALEN);
3824 p2p->after_scan_tx->len = len;
3825 p2p->after_scan_tx->wait_time = wait_time;
3826 os_memcpy(p2p->after_scan_tx + 1, buf, len);
3827 return 0;
3828 }
3829
3830 return p2p->cfg->send_action(p2p->cfg->cb_ctx, freq, dst, src, bssid,
3831 buf, len, wait_time);
3832}
3833
3834
3835void p2p_set_best_channels(struct p2p_data *p2p, int freq_24, int freq_5,
3836 int freq_overall)
3837{
3838 wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG, "P2P: Best channel: 2.4 GHz: %d,"
3839 " 5 GHz: %d, overall: %d", freq_24, freq_5, freq_overall);
3840 p2p->best_freq_24 = freq_24;
3841 p2p->best_freq_5 = freq_5;
3842 p2p->best_freq_overall = freq_overall;
3843}
3844
3845
3846const u8 * p2p_get_go_neg_peer(struct p2p_data *p2p)
3847{
3848 if (p2p == NULL || p2p->go_neg_peer == NULL)
3849 return NULL;
3850 return p2p->go_neg_peer->info.p2p_device_addr;
3851}
3852
3853
3854const struct p2p_peer_info *
3855p2p_get_peer_found(struct p2p_data *p2p, const u8 *addr, int next)
3856{
3857 struct p2p_device *dev;
3858
3859 if (addr) {
3860 dev = p2p_get_device(p2p, addr);
3861 if (!dev)
3862 return NULL;
3863
3864 if (!next) {
3865 if (dev->flags & P2P_DEV_PROBE_REQ_ONLY)
3866 return NULL;
3867
3868 return &dev->info;
3869 } else {
3870 do {
3871 dev = dl_list_first(&dev->list,
3872 struct p2p_device,
3873 list);
3874 if (&dev->list == &p2p->devices)
3875 return NULL;
3876 } while (dev->flags & P2P_DEV_PROBE_REQ_ONLY);
3877 }
3878 } else {
3879 dev = dl_list_first(&p2p->devices, struct p2p_device, list);
3880 if (!dev)
3881 return NULL;
3882 while (dev->flags & P2P_DEV_PROBE_REQ_ONLY) {
3883 dev = dl_list_first(&dev->list,
3884 struct p2p_device,
3885 list);
3886 if (&dev->list == &p2p->devices)
3887 return NULL;
3888 }
3889 }
3890
3891 return &dev->info;
3892}
Dmitry Shmidt1f69aa52012-01-24 16:10:04 -08003893
3894#ifdef ANDROID_P2P
3895int p2p_search_in_progress(struct p2p_data *p2p)
3896{
3897 if (p2p == NULL)
3898 return 0;
3899
3900 return p2p->state == P2P_SEARCH;
3901}
3902#endif
3903
3904int p2p_in_progress(struct p2p_data *p2p)
3905{
3906 if (p2p == NULL)
3907 return 0;
3908 return p2p->state != P2P_IDLE && p2p->state != P2P_PROVISIONING;
3909}