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