blob: b122f7ce5127074f09d51beb6e9afff33f6d03b6 [file] [log] [blame]
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07001/*
2 * Wi-Fi Direct - P2P module
3 * Copyright (c) 2009-2010, Atheros Communications
4 *
Dmitry Shmidtc5ec7f52012-03-06 16:33:24 -08005 * This software may be distributed under the terms of the BSD license.
6 * See README for more details.
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07007 */
8
9#include "includes.h"
10
11#include "common.h"
12#include "eloop.h"
13#include "common/ieee802_11_defs.h"
14#include "common/ieee802_11_common.h"
Dmitry Shmidtc5ec7f52012-03-06 16:33:24 -080015#include "common/wpa_ctrl.h"
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -070016#include "wps/wps_i.h"
17#include "p2p_i.h"
18#include "p2p.h"
19
20
21static void p2p_state_timeout(void *eloop_ctx, void *timeout_ctx);
22static void p2p_device_free(struct p2p_data *p2p, struct p2p_device *dev);
23static void p2p_process_presence_req(struct p2p_data *p2p, const u8 *da,
24 const u8 *sa, const u8 *data, size_t len,
25 int rx_freq);
26static void p2p_process_presence_resp(struct p2p_data *p2p, const u8 *da,
27 const u8 *sa, const u8 *data,
28 size_t len);
29static void p2p_ext_listen_timeout(void *eloop_ctx, void *timeout_ctx);
30static void p2p_scan_timeout(void *eloop_ctx, void *timeout_ctx);
31
32
33/*
34 * p2p_scan recovery timeout
35 *
36 * Many drivers are using 30 second timeout on scan results. Allow a bit larger
37 * timeout for this to avoid hitting P2P timeout unnecessarily.
38 */
39#define P2P_SCAN_TIMEOUT 35
40
41/**
42 * P2P_PEER_EXPIRATION_AGE - Number of seconds after which inactive peer
43 * entries will be removed
44 */
Dmitry Shmidt2fb777c2012-05-02 12:29:53 -070045#ifdef ANDROID_P2P
46#define P2P_PEER_EXPIRATION_AGE 30
47#else
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -070048#define P2P_PEER_EXPIRATION_AGE 300
Dmitry Shmidt2fb777c2012-05-02 12:29:53 -070049#endif
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -070050
51#define P2P_PEER_EXPIRATION_INTERVAL (P2P_PEER_EXPIRATION_AGE / 2)
52
Dmitry Shmidt2fb777c2012-05-02 12:29:53 -070053#ifdef ANDROID_P2P
54int p2p_connection_in_progress(struct p2p_data *p2p)
55{
56 int ret = 0;
57
58 switch (p2p->state) {
59 case P2P_CONNECT:
60 case P2P_CONNECT_LISTEN:
61 case P2P_GO_NEG:
62 case P2P_WAIT_PEER_CONNECT:
Dmitry Shmidt98f9e762012-05-30 11:18:46 -070063 case P2P_WAIT_PEER_IDLE:
Dmitry Shmidt2fb777c2012-05-02 12:29:53 -070064 case P2P_PROVISIONING:
65 case P2P_INVITE:
66 case P2P_INVITE_LISTEN:
67 ret = 1;
68 break;
69
70 default:
Dmitry Shmidt98f9e762012-05-30 11:18:46 -070071 wpa_printf(MSG_DEBUG, "p2p_connection_in_progress state %d", p2p->state);
Dmitry Shmidt2fb777c2012-05-02 12:29:53 -070072 ret = 0;
73 }
74
75 return ret;
76}
77#endif
78
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -070079static void p2p_expire_peers(struct p2p_data *p2p)
80{
81 struct p2p_device *dev, *n;
82 struct os_time now;
Dmitry Shmidtc5ec7f52012-03-06 16:33:24 -080083 size_t i;
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -070084
85 os_get_time(&now);
86 dl_list_for_each_safe(dev, n, &p2p->devices, struct p2p_device, list) {
87 if (dev->last_seen.sec + P2P_PEER_EXPIRATION_AGE >= now.sec)
88 continue;
Dmitry Shmidtc5ec7f52012-03-06 16:33:24 -080089
90 if (p2p->cfg->go_connected &&
91 p2p->cfg->go_connected(p2p->cfg->cb_ctx,
92 dev->info.p2p_device_addr)) {
93 /*
94 * We are connected as a client to a group in which the
95 * peer is the GO, so do not expire the peer entry.
96 */
97 os_get_time(&dev->last_seen);
98 continue;
99 }
100
101 for (i = 0; i < p2p->num_groups; i++) {
102 if (p2p_group_is_client_connected(
103 p2p->groups[i], dev->info.p2p_device_addr))
104 break;
105 }
106 if (i < p2p->num_groups) {
107 /*
108 * The peer is connected as a client in a group where
109 * we are the GO, so do not expire the peer entry.
110 */
111 os_get_time(&dev->last_seen);
112 continue;
113 }
114
Dmitry Shmidt2fb777c2012-05-02 12:29:53 -0700115#ifdef ANDROID_P2P
116 /* If Connection is in progress, don't expire the peer
117 */
118 if (p2p_connection_in_progress(p2p))
119 continue;
120#endif
121
Dmitry Shmidt04949592012-07-19 12:16:46 -0700122 wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG, "P2P: Expiring old peer "
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -0700123 "entry " MACSTR, MAC2STR(dev->info.p2p_device_addr));
Irfan Sherifff44b9c42012-06-13 11:09:23 -0700124#ifdef ANDROID_P2P
125 /* SD_FAIR_POLICY: Update the current sd_dev_list pointer to next device */
126 if(&dev->list == p2p->sd_dev_list)
127 p2p->sd_dev_list = dev->list.next;
128#endif
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -0700129 dl_list_del(&dev->list);
130 p2p_device_free(p2p, dev);
131 }
132}
133
134
135static void p2p_expiration_timeout(void *eloop_ctx, void *timeout_ctx)
136{
137 struct p2p_data *p2p = eloop_ctx;
138 p2p_expire_peers(p2p);
139 eloop_register_timeout(P2P_PEER_EXPIRATION_INTERVAL, 0,
140 p2p_expiration_timeout, p2p, NULL);
141}
142
143
144static const char * p2p_state_txt(int state)
145{
146 switch (state) {
147 case P2P_IDLE:
148 return "IDLE";
149 case P2P_SEARCH:
150 return "SEARCH";
151 case P2P_CONNECT:
152 return "CONNECT";
153 case P2P_CONNECT_LISTEN:
154 return "CONNECT_LISTEN";
155 case P2P_GO_NEG:
156 return "GO_NEG";
157 case P2P_LISTEN_ONLY:
158 return "LISTEN_ONLY";
159 case P2P_WAIT_PEER_CONNECT:
160 return "WAIT_PEER_CONNECT";
161 case P2P_WAIT_PEER_IDLE:
162 return "WAIT_PEER_IDLE";
163 case P2P_SD_DURING_FIND:
164 return "SD_DURING_FIND";
165 case P2P_PROVISIONING:
166 return "PROVISIONING";
167 case P2P_PD_DURING_FIND:
168 return "PD_DURING_FIND";
169 case P2P_INVITE:
170 return "INVITE";
171 case P2P_INVITE_LISTEN:
172 return "INVITE_LISTEN";
Dmitry Shmidt1f69aa52012-01-24 16:10:04 -0800173 case P2P_SEARCH_WHEN_READY:
174 return "SEARCH_WHEN_READY";
Dmitry Shmidt61d9df32012-08-29 16:22:06 -0700175 case P2P_CONTINUE_SEARCH_WHEN_READY:
176 return "CONTINUE_SEARCH_WHEN_READY";
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -0700177 default:
178 return "?";
179 }
180}
181
182
Dmitry Shmidt1f69aa52012-01-24 16:10:04 -0800183u16 p2p_get_provisioning_info(struct p2p_data *p2p, const u8 *addr)
184{
185 struct p2p_device *dev = NULL;
186
187 if (!addr || !p2p)
188 return 0;
189
190 dev = p2p_get_device(p2p, addr);
191 if (dev)
192 return dev->wps_prov_info;
193 else
194 return 0;
195}
196
197
Dmitry Shmidt04949592012-07-19 12:16:46 -0700198void p2p_clear_provisioning_info(struct p2p_data *p2p, const u8 *addr)
Dmitry Shmidt1f69aa52012-01-24 16:10:04 -0800199{
200 struct p2p_device *dev = NULL;
201
Dmitry Shmidt04949592012-07-19 12:16:46 -0700202 if (!addr || !p2p)
Dmitry Shmidt1f69aa52012-01-24 16:10:04 -0800203 return;
204
Dmitry Shmidt04949592012-07-19 12:16:46 -0700205 dev = p2p_get_device(p2p, addr);
Dmitry Shmidt1f69aa52012-01-24 16:10:04 -0800206 if (dev)
207 dev->wps_prov_info = 0;
208}
209
210
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -0700211void p2p_set_state(struct p2p_data *p2p, int new_state)
212{
213 wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG, "P2P: State %s -> %s",
214 p2p_state_txt(p2p->state), p2p_state_txt(new_state));
215 p2p->state = new_state;
216}
217
218
219void p2p_set_timeout(struct p2p_data *p2p, unsigned int sec, unsigned int usec)
220{
221 wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG,
222 "P2P: Set timeout (state=%s): %u.%06u sec",
223 p2p_state_txt(p2p->state), sec, usec);
224 eloop_cancel_timeout(p2p_state_timeout, p2p, NULL);
225 eloop_register_timeout(sec, usec, p2p_state_timeout, p2p, NULL);
226}
227
228
229void p2p_clear_timeout(struct p2p_data *p2p)
230{
231 wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG, "P2P: Clear timeout (state=%s)",
232 p2p_state_txt(p2p->state));
233 eloop_cancel_timeout(p2p_state_timeout, p2p, NULL);
234}
235
236
237void p2p_go_neg_failed(struct p2p_data *p2p, struct p2p_device *peer,
238 int status)
239{
240 struct p2p_go_neg_results res;
241 p2p_clear_timeout(p2p);
242 p2p_set_state(p2p, P2P_IDLE);
Dmitry Shmidt1f69aa52012-01-24 16:10:04 -0800243 if (p2p->go_neg_peer)
244 p2p->go_neg_peer->wps_method = WPS_NOT_READY;
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -0700245 p2p->go_neg_peer = NULL;
246
247 os_memset(&res, 0, sizeof(res));
248 res.status = status;
249 if (peer) {
250 os_memcpy(res.peer_device_addr, peer->info.p2p_device_addr,
251 ETH_ALEN);
252 os_memcpy(res.peer_interface_addr, peer->intended_addr,
253 ETH_ALEN);
254 }
255 p2p->cfg->go_neg_completed(p2p->cfg->cb_ctx, &res);
256}
257
258
Dmitry Shmidtd5e49232012-12-03 15:08:10 -0800259static void p2p_listen_in_find(struct p2p_data *p2p, int dev_disc)
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -0700260{
261 unsigned int r, tu;
262 int freq;
263 struct wpabuf *ies;
264
265 wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG,
266 "P2P: Starting short listen state (state=%s)",
267 p2p_state_txt(p2p->state));
268
269 freq = p2p_channel_to_freq(p2p->cfg->country, p2p->cfg->reg_class,
270 p2p->cfg->channel);
271 if (freq < 0) {
272 wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG,
273 "P2P: Unknown regulatory class/channel");
274 return;
275 }
276
277 os_get_random((u8 *) &r, sizeof(r));
278 tu = (r % ((p2p->max_disc_int - p2p->min_disc_int) + 1) +
279 p2p->min_disc_int) * 100;
Dmitry Shmidtd5e49232012-12-03 15:08:10 -0800280 if (p2p->max_disc_tu >= 0 && tu > (unsigned int) p2p->max_disc_tu)
281 tu = p2p->max_disc_tu;
282 if (!dev_disc && tu < 100)
283 tu = 100; /* Need to wait in non-device discovery use cases */
284 if (p2p->cfg->max_listen && 1024 * tu / 1000 > p2p->cfg->max_listen)
285 tu = p2p->cfg->max_listen * 1000 / 1024;
286
287 if (tu == 0) {
288 wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG, "P2P: Skip listen state "
289 "since duration was 0 TU");
290 p2p_set_timeout(p2p, 0, 0);
291 return;
292 }
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -0700293
294 p2p->pending_listen_freq = freq;
295 p2p->pending_listen_sec = 0;
296 p2p->pending_listen_usec = 1024 * tu;
297
298 ies = p2p_build_probe_resp_ies(p2p);
299 if (ies == NULL)
300 return;
301
302 if (p2p->cfg->start_listen(p2p->cfg->cb_ctx, freq, 1024 * tu / 1000,
303 ies) < 0) {
304 wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG,
305 "P2P: Failed to start listen mode");
306 p2p->pending_listen_freq = 0;
307 }
308 wpabuf_free(ies);
309}
310
311
312int p2p_listen(struct p2p_data *p2p, unsigned int timeout)
313{
314 int freq;
315 struct wpabuf *ies;
316
317 wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG,
318 "P2P: Going to listen(only) state");
319
320 freq = p2p_channel_to_freq(p2p->cfg->country, p2p->cfg->reg_class,
321 p2p->cfg->channel);
322 if (freq < 0) {
323 wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG,
324 "P2P: Unknown regulatory class/channel");
325 return -1;
326 }
327
328 p2p->pending_listen_freq = freq;
329 p2p->pending_listen_sec = timeout / 1000;
330 p2p->pending_listen_usec = (timeout % 1000) * 1000;
331
332 if (p2p->p2p_scan_running) {
Dmitry Shmidt04949592012-07-19 12:16:46 -0700333 if (p2p->start_after_scan == P2P_AFTER_SCAN_CONNECT) {
Dmitry Shmidt1f69aa52012-01-24 16:10:04 -0800334 wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG,
335 "P2P: p2p_scan running - connect is already "
336 "pending - skip listen");
337 return 0;
338 }
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -0700339 wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG,
340 "P2P: p2p_scan running - delay start of listen state");
341 p2p->start_after_scan = P2P_AFTER_SCAN_LISTEN;
342 return 0;
343 }
344
345 ies = p2p_build_probe_resp_ies(p2p);
346 if (ies == NULL)
347 return -1;
348
349 if (p2p->cfg->start_listen(p2p->cfg->cb_ctx, freq, timeout, ies) < 0) {
350 wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG,
351 "P2P: Failed to start listen mode");
352 p2p->pending_listen_freq = 0;
353 wpabuf_free(ies);
354 return -1;
355 }
356 wpabuf_free(ies);
357
358 p2p_set_state(p2p, P2P_LISTEN_ONLY);
359
360 return 0;
361}
362
363
364static void p2p_device_clear_reported(struct p2p_data *p2p)
365{
366 struct p2p_device *dev;
367 dl_list_for_each(dev, &p2p->devices, struct p2p_device, list)
368 dev->flags &= ~P2P_DEV_REPORTED;
369}
370
371
372/**
373 * p2p_get_device - Fetch a peer entry
374 * @p2p: P2P module context from p2p_init()
375 * @addr: P2P Device Address of the peer
376 * Returns: Pointer to the device entry or %NULL if not found
377 */
378struct p2p_device * p2p_get_device(struct p2p_data *p2p, const u8 *addr)
379{
380 struct p2p_device *dev;
381 dl_list_for_each(dev, &p2p->devices, struct p2p_device, list) {
382 if (os_memcmp(dev->info.p2p_device_addr, addr, ETH_ALEN) == 0)
383 return dev;
384 }
385 return NULL;
386}
387
388
389/**
390 * p2p_get_device_interface - Fetch a peer entry based on P2P Interface Address
391 * @p2p: P2P module context from p2p_init()
392 * @addr: P2P Interface Address of the peer
393 * Returns: Pointer to the device entry or %NULL if not found
394 */
395struct p2p_device * p2p_get_device_interface(struct p2p_data *p2p,
396 const u8 *addr)
397{
398 struct p2p_device *dev;
399 dl_list_for_each(dev, &p2p->devices, struct p2p_device, list) {
400 if (os_memcmp(dev->interface_addr, addr, ETH_ALEN) == 0)
401 return dev;
402 }
403 return NULL;
404}
405
406
407/**
408 * p2p_create_device - Create a peer entry
409 * @p2p: P2P module context from p2p_init()
410 * @addr: P2P Device Address of the peer
411 * Returns: Pointer to the device entry or %NULL on failure
412 *
413 * If there is already an entry for the peer, it will be returned instead of
414 * creating a new one.
415 */
416static struct p2p_device * p2p_create_device(struct p2p_data *p2p,
417 const u8 *addr)
418{
419 struct p2p_device *dev, *oldest = NULL;
420 size_t count = 0;
421
422 dev = p2p_get_device(p2p, addr);
423 if (dev)
424 return dev;
425
426 dl_list_for_each(dev, &p2p->devices, struct p2p_device, list) {
427 count++;
428 if (oldest == NULL ||
429 os_time_before(&dev->last_seen, &oldest->last_seen))
430 oldest = dev;
431 }
432 if (count + 1 > p2p->cfg->max_peers && oldest) {
433 wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG,
434 "P2P: Remove oldest peer entry to make room for a new "
435 "peer");
Irfan Sherifff44b9c42012-06-13 11:09:23 -0700436#ifdef ANDROID_P2P
437 /* SD_FAIR_POLICY: Update the current sd_dev_list pointer to next device */
438 if(&oldest->list == p2p->sd_dev_list)
439 p2p->sd_dev_list = oldest->list.next;
440#endif
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -0700441 dl_list_del(&oldest->list);
442 p2p_device_free(p2p, oldest);
443 }
444
445 dev = os_zalloc(sizeof(*dev));
446 if (dev == NULL)
447 return NULL;
448 dl_list_add(&p2p->devices, &dev->list);
449 os_memcpy(dev->info.p2p_device_addr, addr, ETH_ALEN);
450
451 return dev;
452}
453
454
455static void p2p_copy_client_info(struct p2p_device *dev,
456 struct p2p_client_info *cli)
457{
458 os_memcpy(dev->info.device_name, cli->dev_name, cli->dev_name_len);
459 dev->info.device_name[cli->dev_name_len] = '\0';
460 dev->info.dev_capab = cli->dev_capab;
461 dev->info.config_methods = cli->config_methods;
462 os_memcpy(dev->info.pri_dev_type, cli->pri_dev_type, 8);
463 dev->info.wps_sec_dev_type_list_len = 8 * cli->num_sec_dev_types;
464 os_memcpy(dev->info.wps_sec_dev_type_list, cli->sec_dev_types,
465 dev->info.wps_sec_dev_type_list_len);
466}
467
468
469static int p2p_add_group_clients(struct p2p_data *p2p, const u8 *go_dev_addr,
470 const u8 *go_interface_addr, int freq,
471 const u8 *gi, size_t gi_len)
472{
473 struct p2p_group_info info;
474 size_t c;
475 struct p2p_device *dev;
476
477 if (gi == NULL)
478 return 0;
479
480 if (p2p_group_info_parse(gi, gi_len, &info) < 0)
481 return -1;
482
483 /*
484 * Clear old data for this group; if the devices are still in the
485 * group, the information will be restored in the loop following this.
486 */
487 dl_list_for_each(dev, &p2p->devices, struct p2p_device, list) {
Dmitry Shmidt1f69aa52012-01-24 16:10:04 -0800488 if (os_memcmp(dev->member_in_go_iface, go_interface_addr,
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -0700489 ETH_ALEN) == 0) {
490 os_memset(dev->member_in_go_iface, 0, ETH_ALEN);
491 os_memset(dev->member_in_go_dev, 0, ETH_ALEN);
492 }
493 }
494
495 for (c = 0; c < info.num_clients; c++) {
496 struct p2p_client_info *cli = &info.client[c];
Dmitry Shmidt1f69aa52012-01-24 16:10:04 -0800497 if (os_memcmp(cli->p2p_device_addr, p2p->cfg->dev_addr,
498 ETH_ALEN) == 0)
499 continue; /* ignore our own entry */
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -0700500 dev = p2p_get_device(p2p, cli->p2p_device_addr);
501 if (dev) {
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -0700502 if (dev->flags & (P2P_DEV_GROUP_CLIENT_ONLY |
Dmitry Shmidt04949592012-07-19 12:16:46 -0700503 P2P_DEV_PROBE_REQ_ONLY)) {
504 /*
505 * Update information since we have not
506 * received this directly from the client.
507 */
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -0700508 p2p_copy_client_info(dev, cli);
Dmitry Shmidt04949592012-07-19 12:16:46 -0700509 } else {
510 /*
511 * Need to update P2P Client Discoverability
512 * flag since it is valid only in P2P Group
513 * Info attribute.
514 */
515 dev->info.dev_capab &=
516 ~P2P_DEV_CAPAB_CLIENT_DISCOVERABILITY;
517 dev->info.dev_capab |=
518 cli->dev_capab &
519 P2P_DEV_CAPAB_CLIENT_DISCOVERABILITY;
520 }
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -0700521 if (dev->flags & P2P_DEV_PROBE_REQ_ONLY) {
522 dev->flags &= ~P2P_DEV_PROBE_REQ_ONLY;
523 }
524 } else {
525 dev = p2p_create_device(p2p, cli->p2p_device_addr);
526 if (dev == NULL)
527 continue;
528 dev->flags |= P2P_DEV_GROUP_CLIENT_ONLY;
529 p2p_copy_client_info(dev, cli);
530 dev->oper_freq = freq;
531 p2p->cfg->dev_found(p2p->cfg->cb_ctx,
532 dev->info.p2p_device_addr,
533 &dev->info, 1);
534 dev->flags |= P2P_DEV_REPORTED | P2P_DEV_REPORTED_ONCE;
535 }
536
537 os_memcpy(dev->interface_addr, cli->p2p_interface_addr,
538 ETH_ALEN);
539 os_get_time(&dev->last_seen);
540 os_memcpy(dev->member_in_go_dev, go_dev_addr, ETH_ALEN);
541 os_memcpy(dev->member_in_go_iface, go_interface_addr,
542 ETH_ALEN);
543 }
544
545 return 0;
546}
547
548
549static void p2p_copy_wps_info(struct p2p_device *dev, int probe_req,
550 const struct p2p_message *msg)
551{
552 os_memcpy(dev->info.device_name, msg->device_name,
553 sizeof(dev->info.device_name));
554
555 if (msg->manufacturer &&
556 msg->manufacturer_len < sizeof(dev->info.manufacturer)) {
557 os_memset(dev->info.manufacturer, 0,
558 sizeof(dev->info.manufacturer));
559 os_memcpy(dev->info.manufacturer, msg->manufacturer,
560 msg->manufacturer_len);
561 }
562
563 if (msg->model_name &&
564 msg->model_name_len < sizeof(dev->info.model_name)) {
565 os_memset(dev->info.model_name, 0,
566 sizeof(dev->info.model_name));
567 os_memcpy(dev->info.model_name, msg->model_name,
568 msg->model_name_len);
569 }
570
571 if (msg->model_number &&
572 msg->model_number_len < sizeof(dev->info.model_number)) {
573 os_memset(dev->info.model_number, 0,
574 sizeof(dev->info.model_number));
575 os_memcpy(dev->info.model_number, msg->model_number,
576 msg->model_number_len);
577 }
578
579 if (msg->serial_number &&
580 msg->serial_number_len < sizeof(dev->info.serial_number)) {
581 os_memset(dev->info.serial_number, 0,
582 sizeof(dev->info.serial_number));
583 os_memcpy(dev->info.serial_number, msg->serial_number,
584 msg->serial_number_len);
585 }
586
587 if (msg->pri_dev_type)
588 os_memcpy(dev->info.pri_dev_type, msg->pri_dev_type,
589 sizeof(dev->info.pri_dev_type));
590 else if (msg->wps_pri_dev_type)
591 os_memcpy(dev->info.pri_dev_type, msg->wps_pri_dev_type,
592 sizeof(dev->info.pri_dev_type));
593
594 if (msg->wps_sec_dev_type_list) {
595 os_memcpy(dev->info.wps_sec_dev_type_list,
596 msg->wps_sec_dev_type_list,
597 msg->wps_sec_dev_type_list_len);
598 dev->info.wps_sec_dev_type_list_len =
599 msg->wps_sec_dev_type_list_len;
600 }
601
602 if (msg->capability) {
Dmitry Shmidt04949592012-07-19 12:16:46 -0700603 /*
604 * P2P Client Discoverability bit is reserved in all frames
605 * that use this function, so do not change its value here.
606 */
607 dev->info.dev_capab &= P2P_DEV_CAPAB_CLIENT_DISCOVERABILITY;
608 dev->info.dev_capab |= msg->capability[0] &
609 ~P2P_DEV_CAPAB_CLIENT_DISCOVERABILITY;
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -0700610 dev->info.group_capab = msg->capability[1];
611 }
612
613 if (msg->ext_listen_timing) {
614 dev->ext_listen_period = WPA_GET_LE16(msg->ext_listen_timing);
615 dev->ext_listen_interval =
616 WPA_GET_LE16(msg->ext_listen_timing + 2);
617 }
Dmitry Shmidt04949592012-07-19 12:16:46 -0700618
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -0700619 if (!probe_req) {
620 dev->info.config_methods = msg->config_methods ?
621 msg->config_methods : msg->wps_config_methods;
622 }
623}
624
625
626/**
Dmitry Shmidt04949592012-07-19 12:16:46 -0700627 * p2p_add_device - Add peer entries based on scan results or P2P frames
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -0700628 * @p2p: P2P module context from p2p_init()
629 * @addr: Source address of Beacon or Probe Response frame (may be either
630 * P2P Device Address or P2P Interface Address)
631 * @level: Signal level (signal strength of the received frame from the peer)
632 * @freq: Frequency on which the Beacon or Probe Response frame was received
633 * @ies: IEs from the Beacon or Probe Response frame
634 * @ies_len: Length of ies buffer in octets
Dmitry Shmidt04949592012-07-19 12:16:46 -0700635 * @scan_res: Whether this was based on scan results
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -0700636 * Returns: 0 on success, -1 on failure
637 *
638 * If the scan result is for a GO, the clients in the group will also be added
639 * to the peer table. This function can also be used with some other frames
640 * like Provision Discovery Request that contains P2P Capability and P2P Device
641 * Info attributes.
642 */
643int p2p_add_device(struct p2p_data *p2p, const u8 *addr, int freq, int level,
Dmitry Shmidt04949592012-07-19 12:16:46 -0700644 const u8 *ies, size_t ies_len, int scan_res)
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -0700645{
646 struct p2p_device *dev;
647 struct p2p_message msg;
648 const u8 *p2p_dev_addr;
649 int i;
650
651 os_memset(&msg, 0, sizeof(msg));
652 if (p2p_parse_ies(ies, ies_len, &msg)) {
653 wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG,
654 "P2P: Failed to parse P2P IE for a device entry");
655 p2p_parse_free(&msg);
656 return -1;
657 }
658
659 if (msg.p2p_device_addr)
660 p2p_dev_addr = msg.p2p_device_addr;
661 else if (msg.device_id)
662 p2p_dev_addr = msg.device_id;
663 else {
664 wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG,
665 "P2P: Ignore scan data without P2P Device Info or "
666 "P2P Device Id");
667 p2p_parse_free(&msg);
668 return -1;
669 }
670
671 if (!is_zero_ether_addr(p2p->peer_filter) &&
672 os_memcmp(p2p_dev_addr, p2p->peer_filter, ETH_ALEN) != 0) {
673 wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG, "P2P: Do not add peer "
674 "filter for " MACSTR " due to peer filter",
675 MAC2STR(p2p_dev_addr));
676 return 0;
677 }
678
679 dev = p2p_create_device(p2p, p2p_dev_addr);
680 if (dev == NULL) {
681 p2p_parse_free(&msg);
682 return -1;
683 }
684 os_get_time(&dev->last_seen);
685 dev->flags &= ~(P2P_DEV_PROBE_REQ_ONLY | P2P_DEV_GROUP_CLIENT_ONLY);
686
687 if (os_memcmp(addr, p2p_dev_addr, ETH_ALEN) != 0)
688 os_memcpy(dev->interface_addr, addr, ETH_ALEN);
689 if (msg.ssid &&
690 (msg.ssid[1] != P2P_WILDCARD_SSID_LEN ||
691 os_memcmp(msg.ssid + 2, P2P_WILDCARD_SSID, P2P_WILDCARD_SSID_LEN)
692 != 0)) {
693 os_memcpy(dev->oper_ssid, msg.ssid + 2, msg.ssid[1]);
694 dev->oper_ssid_len = msg.ssid[1];
695 }
696
697 if (freq >= 2412 && freq <= 2484 && msg.ds_params &&
698 *msg.ds_params >= 1 && *msg.ds_params <= 14) {
699 int ds_freq;
700 if (*msg.ds_params == 14)
701 ds_freq = 2484;
702 else
703 ds_freq = 2407 + *msg.ds_params * 5;
704 if (freq != ds_freq) {
705 wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG,
706 "P2P: Update Listen frequency based on DS "
707 "Parameter Set IE: %d -> %d MHz",
708 freq, ds_freq);
709 freq = ds_freq;
710 }
711 }
712
Dmitry Shmidt04949592012-07-19 12:16:46 -0700713 if (dev->listen_freq && dev->listen_freq != freq && scan_res) {
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -0700714 wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG,
715 "P2P: Update Listen frequency based on scan "
716 "results (" MACSTR " %d -> %d MHz (DS param %d)",
717 MAC2STR(dev->info.p2p_device_addr), dev->listen_freq,
718 freq, msg.ds_params ? *msg.ds_params : -1);
719 }
Dmitry Shmidt04949592012-07-19 12:16:46 -0700720 if (scan_res) {
721 dev->listen_freq = freq;
722 if (msg.group_info)
723 dev->oper_freq = freq;
724 }
Jouni Malinen75ecf522011-06-27 15:19:46 -0700725 dev->info.level = level;
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -0700726
727 p2p_copy_wps_info(dev, 0, &msg);
728
729 for (i = 0; i < P2P_MAX_WPS_VENDOR_EXT; i++) {
730 wpabuf_free(dev->info.wps_vendor_ext[i]);
731 dev->info.wps_vendor_ext[i] = NULL;
732 }
733
734 for (i = 0; i < P2P_MAX_WPS_VENDOR_EXT; i++) {
735 if (msg.wps_vendor_ext[i] == NULL)
736 break;
737 dev->info.wps_vendor_ext[i] = wpabuf_alloc_copy(
738 msg.wps_vendor_ext[i], msg.wps_vendor_ext_len[i]);
739 if (dev->info.wps_vendor_ext[i] == NULL)
740 break;
741 }
742
Dmitry Shmidt61d9df32012-08-29 16:22:06 -0700743 if (msg.wfd_subelems) {
744 wpabuf_free(dev->info.wfd_subelems);
745 dev->info.wfd_subelems = wpabuf_dup(msg.wfd_subelems);
746 }
747
Dmitry Shmidt04949592012-07-19 12:16:46 -0700748 if (scan_res) {
749 p2p_add_group_clients(p2p, p2p_dev_addr, addr, freq,
750 msg.group_info, msg.group_info_len);
751 }
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -0700752
753 p2p_parse_free(&msg);
754
755 if (p2p_pending_sd_req(p2p, dev))
756 dev->flags |= P2P_DEV_SD_SCHEDULE;
757
758 if (dev->flags & P2P_DEV_REPORTED)
759 return 0;
760
761 wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG,
762 "P2P: Peer found with Listen frequency %d MHz", freq);
763 if (dev->flags & P2P_DEV_USER_REJECTED) {
764 wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG,
765 "P2P: Do not report rejected device");
766 return 0;
767 }
768
769 p2p->cfg->dev_found(p2p->cfg->cb_ctx, addr, &dev->info,
770 !(dev->flags & P2P_DEV_REPORTED_ONCE));
771 dev->flags |= P2P_DEV_REPORTED | P2P_DEV_REPORTED_ONCE;
772
773 return 0;
774}
775
776
777static void p2p_device_free(struct p2p_data *p2p, struct p2p_device *dev)
778{
779 int i;
780
Dmitry Shmidt497c1d52011-07-21 15:19:46 -0700781 if (p2p->go_neg_peer == dev) {
Dmitry Shmidt1f69aa52012-01-24 16:10:04 -0800782 /*
783 * If GO Negotiation is in progress, report that it has failed.
784 */
Dmitry Shmidt497c1d52011-07-21 15:19:46 -0700785 p2p_go_neg_failed(p2p, dev, -1);
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -0700786 p2p->go_neg_peer = NULL;
Dmitry Shmidt497c1d52011-07-21 15:19:46 -0700787 }
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -0700788 if (p2p->invite_peer == dev)
789 p2p->invite_peer = NULL;
790 if (p2p->sd_peer == dev)
791 p2p->sd_peer = NULL;
792 if (p2p->pending_client_disc_go == dev)
793 p2p->pending_client_disc_go = NULL;
794
Dmitry Shmidtc55524a2011-07-07 11:18:38 -0700795 /* dev_lost() device, but only if it was previously dev_found() */
796 if (dev->flags & P2P_DEV_REPORTED_ONCE)
797 p2p->cfg->dev_lost(p2p->cfg->cb_ctx,
798 dev->info.p2p_device_addr);
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -0700799
800 for (i = 0; i < P2P_MAX_WPS_VENDOR_EXT; i++) {
801 wpabuf_free(dev->info.wps_vendor_ext[i]);
802 dev->info.wps_vendor_ext[i] = NULL;
803 }
804
Dmitry Shmidt61d9df32012-08-29 16:22:06 -0700805 wpabuf_free(dev->info.wfd_subelems);
806
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -0700807 os_free(dev);
808}
809
810
811static int p2p_get_next_prog_freq(struct p2p_data *p2p)
812{
813 struct p2p_channels *c;
814 struct p2p_reg_class *cla;
815 size_t cl, ch;
816 int found = 0;
817 u8 reg_class;
818 u8 channel;
819 int freq;
820
821 c = &p2p->cfg->channels;
822 for (cl = 0; cl < c->reg_classes; cl++) {
823 cla = &c->reg_class[cl];
824 if (cla->reg_class != p2p->last_prog_scan_class)
825 continue;
826 for (ch = 0; ch < cla->channels; ch++) {
827 if (cla->channel[ch] == p2p->last_prog_scan_chan) {
828 found = 1;
829 break;
830 }
831 }
832 if (found)
833 break;
834 }
835
836 if (!found) {
837 /* Start from beginning */
838 reg_class = c->reg_class[0].reg_class;
839 channel = c->reg_class[0].channel[0];
840 } else {
841 /* Pick the next channel */
842 ch++;
843 if (ch == cla->channels) {
844 cl++;
845 if (cl == c->reg_classes)
846 cl = 0;
847 ch = 0;
848 }
849 reg_class = c->reg_class[cl].reg_class;
850 channel = c->reg_class[cl].channel[ch];
851 }
852
853 freq = p2p_channel_to_freq(p2p->cfg->country, reg_class, channel);
854 wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG, "P2P: Next progressive search "
855 "channel: reg_class %u channel %u -> %d MHz",
856 reg_class, channel, freq);
857 p2p->last_prog_scan_class = reg_class;
858 p2p->last_prog_scan_chan = channel;
859
860 if (freq == 2412 || freq == 2437 || freq == 2462)
861 return 0; /* No need to add social channels */
862 return freq;
863}
864
865
866static void p2p_search(struct p2p_data *p2p)
867{
868 int freq = 0;
869 enum p2p_scan_type type;
Dmitry Shmidt04949592012-07-19 12:16:46 -0700870 u16 pw_id = DEV_PW_DEFAULT;
Dmitry Shmidt61d9df32012-08-29 16:22:06 -0700871 int res;
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -0700872
873 if (p2p->drv_in_listen) {
874 wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG, "P2P: Driver is still "
875 "in Listen state - wait for it to end before "
876 "continuing");
877 return;
878 }
879 p2p->cfg->stop_listen(p2p->cfg->cb_ctx);
880
Dmitry Shmidt04949592012-07-19 12:16:46 -0700881 if (p2p->find_type == P2P_FIND_PROGRESSIVE &&
882 (freq = p2p_get_next_prog_freq(p2p)) > 0) {
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -0700883 type = P2P_SCAN_SOCIAL_PLUS_ONE;
884 wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG, "P2P: Starting search "
885 "(+ freq %u)", freq);
886 } else {
887 type = P2P_SCAN_SOCIAL;
888 wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG, "P2P: Starting search");
889 }
890
Dmitry Shmidt61d9df32012-08-29 16:22:06 -0700891 res = p2p->cfg->p2p_scan(p2p->cfg->cb_ctx, type, freq,
892 p2p->num_req_dev_types, p2p->req_dev_types,
893 p2p->find_dev_id, pw_id);
894 if (res < 0) {
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -0700895 wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG,
896 "P2P: Scan request failed");
897 p2p_continue_find(p2p);
Dmitry Shmidt61d9df32012-08-29 16:22:06 -0700898 } else if (res == 1) {
899 wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG, "P2P: Could not start "
900 "p2p_scan at this point - will try again after "
901 "previous scan completes");
902 p2p_set_state(p2p, P2P_CONTINUE_SEARCH_WHEN_READY);
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -0700903 } else {
904 wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG, "P2P: Running p2p_scan");
905 p2p->p2p_scan_running = 1;
906 eloop_cancel_timeout(p2p_scan_timeout, p2p, NULL);
907 eloop_register_timeout(P2P_SCAN_TIMEOUT, 0, p2p_scan_timeout,
908 p2p, NULL);
909 }
910}
911
912
913static void p2p_find_timeout(void *eloop_ctx, void *timeout_ctx)
914{
915 struct p2p_data *p2p = eloop_ctx;
916 wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG, "P2P: Find timeout -> stop");
917 p2p_stop_find(p2p);
918}
919
920
921static int p2p_run_after_scan(struct p2p_data *p2p)
922{
923 struct p2p_device *dev;
924 enum p2p_after_scan op;
925
926 if (p2p->after_scan_tx) {
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -0700927 /* TODO: schedule p2p_run_after_scan to be called from TX
928 * status callback(?) */
929 wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG, "P2P: Send pending "
930 "Action frame at p2p_scan completion");
Dmitry Shmidt1f69aa52012-01-24 16:10:04 -0800931 p2p->cfg->send_action(p2p->cfg->cb_ctx,
932 p2p->after_scan_tx->freq,
933 p2p->after_scan_tx->dst,
934 p2p->after_scan_tx->src,
935 p2p->after_scan_tx->bssid,
936 (u8 *) (p2p->after_scan_tx + 1),
937 p2p->after_scan_tx->len,
938 p2p->after_scan_tx->wait_time);
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -0700939 os_free(p2p->after_scan_tx);
940 p2p->after_scan_tx = NULL;
Irfan Sherifff44b9c42012-06-13 11:09:23 -0700941#ifdef ANDROID_P2P
942 /* For SD frames, there is a scenario, where we can receive a SD request frame during p2p_scan.
943 * At that moment, we will send the SD response from this context. After sending the SD response,
944 * we need to continue p2p_find. But if we return 1 from here, p2p_find is going to be stopped.
945 */
946 return 0;
947#else
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -0700948 return 1;
Irfan Sherifff44b9c42012-06-13 11:09:23 -0700949#endif
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -0700950 }
951
952 op = p2p->start_after_scan;
953 p2p->start_after_scan = P2P_AFTER_SCAN_NOTHING;
954 switch (op) {
955 case P2P_AFTER_SCAN_NOTHING:
956 break;
957 case P2P_AFTER_SCAN_LISTEN:
958 wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG, "P2P: Start previously "
959 "requested Listen state");
960 p2p_listen(p2p, p2p->pending_listen_sec * 1000 +
961 p2p->pending_listen_usec / 1000);
962 return 1;
963 case P2P_AFTER_SCAN_CONNECT:
964 wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG, "P2P: Start previously "
965 "requested connect with " MACSTR,
966 MAC2STR(p2p->after_scan_peer));
967 dev = p2p_get_device(p2p, p2p->after_scan_peer);
968 if (dev == NULL) {
969 wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG, "P2P: Peer not "
970 "known anymore");
971 break;
972 }
973 p2p_connect_send(p2p, dev);
974 return 1;
975 }
976
977 return 0;
978}
979
980
981static void p2p_scan_timeout(void *eloop_ctx, void *timeout_ctx)
982{
983 struct p2p_data *p2p = eloop_ctx;
984 int running;
985 wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG, "P2P: p2p_scan timeout "
986 "(running=%d)", p2p->p2p_scan_running);
987 running = p2p->p2p_scan_running;
988 /* Make sure we recover from missed scan results callback */
989 p2p->p2p_scan_running = 0;
990
991 if (running)
992 p2p_run_after_scan(p2p);
993}
994
995
996static void p2p_free_req_dev_types(struct p2p_data *p2p)
997{
998 p2p->num_req_dev_types = 0;
999 os_free(p2p->req_dev_types);
1000 p2p->req_dev_types = NULL;
1001}
1002
1003
1004int p2p_find(struct p2p_data *p2p, unsigned int timeout,
1005 enum p2p_discovery_type type,
Dmitry Shmidtc5ec7f52012-03-06 16:33:24 -08001006 unsigned int num_req_dev_types, const u8 *req_dev_types,
Dmitry Shmidt61d9df32012-08-29 16:22:06 -07001007 const u8 *dev_id, unsigned int search_delay)
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07001008{
1009 int res;
1010
1011 wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG, "P2P: Starting find (type=%d)",
1012 type);
1013 if (p2p->p2p_scan_running) {
1014 wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG, "P2P: p2p_scan is "
1015 "already running");
1016 }
1017
1018 p2p_free_req_dev_types(p2p);
1019 if (req_dev_types && num_req_dev_types) {
1020 p2p->req_dev_types = os_malloc(num_req_dev_types *
1021 WPS_DEV_TYPE_LEN);
1022 if (p2p->req_dev_types == NULL)
1023 return -1;
1024 os_memcpy(p2p->req_dev_types, req_dev_types,
1025 num_req_dev_types * WPS_DEV_TYPE_LEN);
1026 p2p->num_req_dev_types = num_req_dev_types;
1027 }
1028
Dmitry Shmidtc5ec7f52012-03-06 16:33:24 -08001029 if (dev_id) {
1030 os_memcpy(p2p->find_dev_id_buf, dev_id, ETH_ALEN);
1031 p2p->find_dev_id = p2p->find_dev_id_buf;
1032 } else
1033 p2p->find_dev_id = NULL;
1034
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07001035 p2p->start_after_scan = P2P_AFTER_SCAN_NOTHING;
1036 p2p_clear_timeout(p2p);
1037 p2p->cfg->stop_listen(p2p->cfg->cb_ctx);
1038 p2p->find_type = type;
1039 p2p_device_clear_reported(p2p);
1040 p2p_set_state(p2p, P2P_SEARCH);
Dmitry Shmidt61d9df32012-08-29 16:22:06 -07001041 p2p->search_delay = search_delay;
1042 p2p->in_search_delay = 0;
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07001043 eloop_cancel_timeout(p2p_find_timeout, p2p, NULL);
Dmitry Shmidt1f69aa52012-01-24 16:10:04 -08001044 p2p->last_p2p_find_timeout = timeout;
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07001045 if (timeout)
1046 eloop_register_timeout(timeout, 0, p2p_find_timeout,
1047 p2p, NULL);
1048 switch (type) {
1049 case P2P_FIND_START_WITH_FULL:
1050 case P2P_FIND_PROGRESSIVE:
1051 res = p2p->cfg->p2p_scan(p2p->cfg->cb_ctx, P2P_SCAN_FULL, 0,
1052 p2p->num_req_dev_types,
Dmitry Shmidt04949592012-07-19 12:16:46 -07001053 p2p->req_dev_types, dev_id,
1054 DEV_PW_DEFAULT);
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07001055 break;
1056 case P2P_FIND_ONLY_SOCIAL:
1057 res = p2p->cfg->p2p_scan(p2p->cfg->cb_ctx, P2P_SCAN_SOCIAL, 0,
1058 p2p->num_req_dev_types,
Dmitry Shmidt04949592012-07-19 12:16:46 -07001059 p2p->req_dev_types, dev_id,
1060 DEV_PW_DEFAULT);
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07001061 break;
1062 default:
1063 return -1;
1064 }
1065
1066 if (res == 0) {
1067 wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG, "P2P: Running p2p_scan");
1068 p2p->p2p_scan_running = 1;
1069 eloop_cancel_timeout(p2p_scan_timeout, p2p, NULL);
1070 eloop_register_timeout(P2P_SCAN_TIMEOUT, 0, p2p_scan_timeout,
1071 p2p, NULL);
Dmitry Shmidt1f69aa52012-01-24 16:10:04 -08001072 } else if (res == 1) {
1073 wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG, "P2P: Could not start "
1074 "p2p_scan at this point - will try again after "
1075 "previous scan completes");
1076 res = 0;
1077 p2p_set_state(p2p, P2P_SEARCH_WHEN_READY);
1078 eloop_cancel_timeout(p2p_find_timeout, p2p, NULL);
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07001079 } else {
1080 wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG, "P2P: Failed to start "
1081 "p2p_scan");
Dmitry Shmidt1f69aa52012-01-24 16:10:04 -08001082 p2p_set_state(p2p, P2P_IDLE);
1083 eloop_cancel_timeout(p2p_find_timeout, p2p, NULL);
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07001084 }
1085
1086 return res;
1087}
1088
Dmitry Shmidt2fb777c2012-05-02 12:29:53 -07001089#ifdef ANDROID_P2P
1090int p2p_search_pending(struct p2p_data *p2p)
1091{
1092 if(p2p == NULL)
1093 return 0;
1094
1095 if(p2p->state == P2P_SEARCH_WHEN_READY)
1096 return 1;
1097
1098 return 0;
1099}
1100#endif
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07001101
Dmitry Shmidt1f69aa52012-01-24 16:10:04 -08001102int p2p_other_scan_completed(struct p2p_data *p2p)
1103{
Dmitry Shmidt61d9df32012-08-29 16:22:06 -07001104 if (p2p->state == P2P_CONTINUE_SEARCH_WHEN_READY) {
1105 p2p_set_state(p2p, P2P_SEARCH);
1106 p2p_search(p2p);
1107 return 1;
1108 }
Dmitry Shmidt1f69aa52012-01-24 16:10:04 -08001109 if (p2p->state != P2P_SEARCH_WHEN_READY)
1110 return 0;
1111 wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG, "P2P: Starting pending P2P find "
1112 "now that previous scan was completed");
1113 if (p2p_find(p2p, p2p->last_p2p_find_timeout, p2p->find_type,
Dmitry Shmidtc5ec7f52012-03-06 16:33:24 -08001114 p2p->num_req_dev_types, p2p->req_dev_types,
Dmitry Shmidt61d9df32012-08-29 16:22:06 -07001115 p2p->find_dev_id, p2p->search_delay) < 0)
Dmitry Shmidt1f69aa52012-01-24 16:10:04 -08001116 return 0;
1117 return 1;
1118}
1119
1120
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07001121void p2p_stop_find_for_freq(struct p2p_data *p2p, int freq)
1122{
1123 wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG, "P2P: Stopping find");
1124 eloop_cancel_timeout(p2p_find_timeout, p2p, NULL);
1125 p2p_clear_timeout(p2p);
Dmitry Shmidtc5ec7f52012-03-06 16:33:24 -08001126 if (p2p->state == P2P_SEARCH)
1127 wpa_msg(p2p->cfg->msg_ctx, MSG_INFO, P2P_EVENT_FIND_STOPPED);
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07001128 p2p_set_state(p2p, P2P_IDLE);
1129 p2p_free_req_dev_types(p2p);
1130 p2p->start_after_scan = P2P_AFTER_SCAN_NOTHING;
1131 p2p->go_neg_peer = NULL;
1132 p2p->sd_peer = NULL;
1133 p2p->invite_peer = NULL;
Dmitry Shmidt04949592012-07-19 12:16:46 -07001134 p2p_stop_listen_for_freq(p2p, freq);
1135}
1136
1137
1138void p2p_stop_listen_for_freq(struct p2p_data *p2p, int freq)
1139{
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07001140 if (freq > 0 && p2p->drv_in_listen == freq && p2p->in_listen) {
1141 wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG, "P2P: Skip stop_listen "
1142 "since we are on correct channel for response");
1143 return;
1144 }
Dmitry Shmidt04949592012-07-19 12:16:46 -07001145 if (p2p->in_listen) {
1146 p2p->in_listen = 0;
1147 p2p_clear_timeout(p2p);
1148 }
Dmitry Shmidt1f69aa52012-01-24 16:10:04 -08001149 if (p2p->drv_in_listen) {
1150 /*
1151 * The driver may not deliver callback to p2p_listen_end()
1152 * when the operation gets canceled, so clear the internal
1153 * variable that is tracking driver state.
1154 */
1155 wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG, "P2P: Clear "
1156 "drv_in_listen (%d)", p2p->drv_in_listen);
1157 p2p->drv_in_listen = 0;
1158 }
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07001159 p2p->cfg->stop_listen(p2p->cfg->cb_ctx);
1160}
1161
1162
1163void p2p_stop_find(struct p2p_data *p2p)
1164{
1165 p2p_stop_find_for_freq(p2p, 0);
1166}
1167
1168
Dmitry Shmidtd5e49232012-12-03 15:08:10 -08001169static int p2p_prepare_channel(struct p2p_data *p2p, unsigned int force_freq,
1170 unsigned int pref_freq)
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07001171{
Dmitry Shmidtd5e49232012-12-03 15:08:10 -08001172 if (force_freq || pref_freq) {
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07001173 u8 op_reg_class, op_channel;
Dmitry Shmidtd5e49232012-12-03 15:08:10 -08001174 unsigned int freq = force_freq ? force_freq : pref_freq;
1175 if (p2p_freq_to_channel(p2p->cfg->country, freq,
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07001176 &op_reg_class, &op_channel) < 0) {
1177 wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG,
1178 "P2P: Unsupported frequency %u MHz",
Dmitry Shmidtd5e49232012-12-03 15:08:10 -08001179 freq);
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07001180 return -1;
1181 }
1182 if (!p2p_channels_includes(&p2p->cfg->channels, op_reg_class,
1183 op_channel)) {
1184 wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG,
1185 "P2P: Frequency %u MHz (oper_class %u "
1186 "channel %u) not allowed for P2P",
Dmitry Shmidtd5e49232012-12-03 15:08:10 -08001187 freq, op_reg_class, op_channel);
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07001188 return -1;
1189 }
1190 p2p->op_reg_class = op_reg_class;
1191 p2p->op_channel = op_channel;
Dmitry Shmidtd5e49232012-12-03 15:08:10 -08001192 if (force_freq) {
Dmitry Shmidt04abaa92012-08-17 16:22:31 -07001193 p2p->channels.reg_classes = 1;
1194 p2p->channels.reg_class[0].channels = 1;
Dmitry Shmidtd5e49232012-12-03 15:08:10 -08001195 p2p->channels.reg_class[0].reg_class =
1196 p2p->op_reg_class;
Dmitry Shmidt04abaa92012-08-17 16:22:31 -07001197 p2p->channels.reg_class[0].channel[0] = p2p->op_channel;
Dmitry Shmidtd5e49232012-12-03 15:08:10 -08001198 } else {
1199 os_memcpy(&p2p->channels, &p2p->cfg->channels,
1200 sizeof(struct p2p_channels));
Dmitry Shmidt04abaa92012-08-17 16:22:31 -07001201 }
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07001202 } else {
1203 u8 op_reg_class, op_channel;
1204
1205 if (!p2p->cfg->cfg_op_channel && p2p->best_freq_overall > 0 &&
1206 p2p_supported_freq(p2p, p2p->best_freq_overall) &&
1207 p2p_freq_to_channel(p2p->cfg->country,
1208 p2p->best_freq_overall,
1209 &op_reg_class, &op_channel) == 0) {
1210 wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG,
1211 "P2P: Select best overall channel as "
1212 "operating channel preference");
1213 p2p->op_reg_class = op_reg_class;
1214 p2p->op_channel = op_channel;
1215 } else if (!p2p->cfg->cfg_op_channel && p2p->best_freq_5 > 0 &&
1216 p2p_supported_freq(p2p, p2p->best_freq_5) &&
1217 p2p_freq_to_channel(p2p->cfg->country,
1218 p2p->best_freq_5,
1219 &op_reg_class, &op_channel) ==
1220 0) {
1221 wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG,
1222 "P2P: Select best 5 GHz channel as "
1223 "operating channel preference");
1224 p2p->op_reg_class = op_reg_class;
1225 p2p->op_channel = op_channel;
1226 } else if (!p2p->cfg->cfg_op_channel &&
1227 p2p->best_freq_24 > 0 &&
1228 p2p_supported_freq(p2p, p2p->best_freq_24) &&
1229 p2p_freq_to_channel(p2p->cfg->country,
1230 p2p->best_freq_24,
1231 &op_reg_class, &op_channel) ==
1232 0) {
1233 wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG,
1234 "P2P: Select best 2.4 GHz channel as "
1235 "operating channel preference");
1236 p2p->op_reg_class = op_reg_class;
1237 p2p->op_channel = op_channel;
1238 } else {
1239 p2p->op_reg_class = p2p->cfg->op_reg_class;
1240 p2p->op_channel = p2p->cfg->op_channel;
1241 }
1242
1243 os_memcpy(&p2p->channels, &p2p->cfg->channels,
1244 sizeof(struct p2p_channels));
1245 }
1246 wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG,
1247 "P2P: Own preference for operation channel: "
1248 "Operating Class %u Channel %u%s",
1249 p2p->op_reg_class, p2p->op_channel,
1250 force_freq ? " (forced)" : "");
1251
1252 return 0;
1253}
1254
1255
Dmitry Shmidt1f69aa52012-01-24 16:10:04 -08001256static void p2p_set_dev_persistent(struct p2p_device *dev,
1257 int persistent_group)
1258{
1259 switch (persistent_group) {
1260 case 0:
1261 dev->flags &= ~(P2P_DEV_PREFER_PERSISTENT_GROUP |
1262 P2P_DEV_PREFER_PERSISTENT_RECONN);
1263 break;
1264 case 1:
1265 dev->flags |= P2P_DEV_PREFER_PERSISTENT_GROUP;
1266 dev->flags &= ~P2P_DEV_PREFER_PERSISTENT_RECONN;
1267 break;
1268 case 2:
1269 dev->flags |= P2P_DEV_PREFER_PERSISTENT_GROUP |
1270 P2P_DEV_PREFER_PERSISTENT_RECONN;
1271 break;
1272 }
1273}
1274
1275
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07001276int p2p_connect(struct p2p_data *p2p, const u8 *peer_addr,
1277 enum p2p_wps_method wps_method,
1278 int go_intent, const u8 *own_interface_addr,
Dmitry Shmidt04949592012-07-19 12:16:46 -07001279 unsigned int force_freq, int persistent_group,
1280 const u8 *force_ssid, size_t force_ssid_len,
Dmitry Shmidtd5e49232012-12-03 15:08:10 -08001281 int pd_before_go_neg, unsigned int pref_freq)
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07001282{
1283 struct p2p_device *dev;
1284
1285 wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG,
1286 "P2P: Request to start group negotiation - peer=" MACSTR
1287 " GO Intent=%d Intended Interface Address=" MACSTR
Dmitry Shmidtd5e49232012-12-03 15:08:10 -08001288 " wps_method=%d persistent_group=%d pd_before_go_neg=%d",
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07001289 MAC2STR(peer_addr), go_intent, MAC2STR(own_interface_addr),
Dmitry Shmidtd5e49232012-12-03 15:08:10 -08001290 wps_method, persistent_group, pd_before_go_neg);
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07001291
Dmitry Shmidtd5e49232012-12-03 15:08:10 -08001292 if (p2p_prepare_channel(p2p, force_freq, pref_freq) < 0)
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07001293 return -1;
1294
1295 dev = p2p_get_device(p2p, peer_addr);
1296 if (dev == NULL || (dev->flags & P2P_DEV_PROBE_REQ_ONLY)) {
1297 wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG,
1298 "P2P: Cannot connect to unknown P2P Device " MACSTR,
1299 MAC2STR(peer_addr));
1300 return -1;
1301 }
1302
1303 if (dev->flags & P2P_DEV_GROUP_CLIENT_ONLY) {
1304 if (!(dev->info.dev_capab &
1305 P2P_DEV_CAPAB_CLIENT_DISCOVERABILITY)) {
1306 wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG,
1307 "P2P: Cannot connect to P2P Device " MACSTR
1308 " that is in a group and is not discoverable",
1309 MAC2STR(peer_addr));
1310 return -1;
1311 }
1312 if (dev->oper_freq <= 0) {
1313 wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG,
1314 "P2P: Cannot connect to P2P Device " MACSTR
1315 " with incomplete information",
1316 MAC2STR(peer_addr));
1317 return -1;
1318 }
1319
1320 /*
1321 * First, try to connect directly. If the peer does not
1322 * acknowledge frames, assume it is sleeping and use device
1323 * discoverability via the GO at that point.
1324 */
1325 }
1326
Dmitry Shmidt04949592012-07-19 12:16:46 -07001327 p2p->ssid_set = 0;
1328 if (force_ssid) {
1329 wpa_hexdump_ascii(MSG_DEBUG, "P2P: Forced SSID",
1330 force_ssid, force_ssid_len);
1331 os_memcpy(p2p->ssid, force_ssid, force_ssid_len);
1332 p2p->ssid_len = force_ssid_len;
1333 p2p->ssid_set = 1;
1334 }
1335
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07001336 dev->flags &= ~P2P_DEV_NOT_YET_READY;
1337 dev->flags &= ~P2P_DEV_USER_REJECTED;
1338 dev->flags &= ~P2P_DEV_WAIT_GO_NEG_RESPONSE;
1339 dev->flags &= ~P2P_DEV_WAIT_GO_NEG_CONFIRM;
Dmitry Shmidt04949592012-07-19 12:16:46 -07001340 if (pd_before_go_neg)
1341 dev->flags |= P2P_DEV_PD_BEFORE_GO_NEG;
1342 else
1343 dev->flags &= ~P2P_DEV_PD_BEFORE_GO_NEG;
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07001344 dev->connect_reqs = 0;
1345 dev->go_neg_req_sent = 0;
1346 dev->go_state = UNKNOWN_GO;
Dmitry Shmidt1f69aa52012-01-24 16:10:04 -08001347 p2p_set_dev_persistent(dev, persistent_group);
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07001348 p2p->go_intent = go_intent;
1349 os_memcpy(p2p->intended_addr, own_interface_addr, ETH_ALEN);
1350
1351 if (p2p->state != P2P_IDLE)
1352 p2p_stop_find(p2p);
1353
1354 if (p2p->after_scan_tx) {
1355 /*
1356 * We need to drop the pending frame to avoid issues with the
1357 * new GO Negotiation, e.g., when the pending frame was from a
1358 * previous attempt at starting a GO Negotiation.
1359 */
1360 wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG, "P2P: Dropped "
1361 "previous pending Action frame TX that was waiting "
1362 "for p2p_scan completion");
1363 os_free(p2p->after_scan_tx);
1364 p2p->after_scan_tx = NULL;
1365 }
1366
1367 dev->wps_method = wps_method;
1368 dev->status = P2P_SC_SUCCESS;
1369
1370 if (force_freq)
1371 dev->flags |= P2P_DEV_FORCE_FREQ;
1372 else
1373 dev->flags &= ~P2P_DEV_FORCE_FREQ;
1374
1375 if (p2p->p2p_scan_running) {
1376 wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG,
1377 "P2P: p2p_scan running - delay connect send");
1378 p2p->start_after_scan = P2P_AFTER_SCAN_CONNECT;
1379 os_memcpy(p2p->after_scan_peer, peer_addr, ETH_ALEN);
1380 return 0;
1381 }
1382 p2p->start_after_scan = P2P_AFTER_SCAN_NOTHING;
1383
1384 return p2p_connect_send(p2p, dev);
1385}
1386
1387
1388int p2p_authorize(struct p2p_data *p2p, const u8 *peer_addr,
1389 enum p2p_wps_method wps_method,
1390 int go_intent, const u8 *own_interface_addr,
Dmitry Shmidt04949592012-07-19 12:16:46 -07001391 unsigned int force_freq, int persistent_group,
Dmitry Shmidtd5e49232012-12-03 15:08:10 -08001392 const u8 *force_ssid, size_t force_ssid_len,
1393 unsigned int pref_freq)
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07001394{
1395 struct p2p_device *dev;
1396
1397 wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG,
1398 "P2P: Request to authorize group negotiation - peer=" MACSTR
1399 " GO Intent=%d Intended Interface Address=" MACSTR
1400 " wps_method=%d persistent_group=%d",
1401 MAC2STR(peer_addr), go_intent, MAC2STR(own_interface_addr),
1402 wps_method, persistent_group);
1403
Dmitry Shmidtd5e49232012-12-03 15:08:10 -08001404 if (p2p_prepare_channel(p2p, force_freq, pref_freq) < 0)
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07001405 return -1;
1406
1407 dev = p2p_get_device(p2p, peer_addr);
1408 if (dev == NULL) {
1409 wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG,
1410 "P2P: Cannot authorize unknown P2P Device " MACSTR,
1411 MAC2STR(peer_addr));
1412 return -1;
1413 }
1414
Dmitry Shmidt04949592012-07-19 12:16:46 -07001415 p2p->ssid_set = 0;
1416 if (force_ssid) {
1417 wpa_hexdump_ascii(MSG_DEBUG, "P2P: Forced SSID",
1418 force_ssid, force_ssid_len);
1419 os_memcpy(p2p->ssid, force_ssid, force_ssid_len);
1420 p2p->ssid_len = force_ssid_len;
1421 p2p->ssid_set = 1;
1422 }
1423
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07001424 dev->flags &= ~P2P_DEV_NOT_YET_READY;
1425 dev->flags &= ~P2P_DEV_USER_REJECTED;
1426 dev->go_neg_req_sent = 0;
1427 dev->go_state = UNKNOWN_GO;
Dmitry Shmidt1f69aa52012-01-24 16:10:04 -08001428 p2p_set_dev_persistent(dev, persistent_group);
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07001429 p2p->go_intent = go_intent;
1430 os_memcpy(p2p->intended_addr, own_interface_addr, ETH_ALEN);
1431
1432 dev->wps_method = wps_method;
1433 dev->status = P2P_SC_SUCCESS;
1434
1435 if (force_freq)
1436 dev->flags |= P2P_DEV_FORCE_FREQ;
1437 else
1438 dev->flags &= ~P2P_DEV_FORCE_FREQ;
1439
1440 return 0;
1441}
1442
1443
1444void p2p_add_dev_info(struct p2p_data *p2p, const u8 *addr,
1445 struct p2p_device *dev, struct p2p_message *msg)
1446{
1447 os_get_time(&dev->last_seen);
1448
1449 p2p_copy_wps_info(dev, 0, msg);
1450
1451 if (msg->listen_channel) {
1452 int freq;
1453 freq = p2p_channel_to_freq((char *) msg->listen_channel,
1454 msg->listen_channel[3],
1455 msg->listen_channel[4]);
1456 if (freq < 0) {
1457 wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG,
1458 "P2P: Unknown peer Listen channel: "
1459 "country=%c%c(0x%02x) reg_class=%u channel=%u",
1460 msg->listen_channel[0],
1461 msg->listen_channel[1],
1462 msg->listen_channel[2],
1463 msg->listen_channel[3],
1464 msg->listen_channel[4]);
1465 } else {
1466 wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG, "P2P: Update "
1467 "peer " MACSTR " Listen channel: %u -> %u MHz",
1468 MAC2STR(dev->info.p2p_device_addr),
1469 dev->listen_freq, freq);
1470 dev->listen_freq = freq;
1471 }
1472 }
1473
Dmitry Shmidt61d9df32012-08-29 16:22:06 -07001474 if (msg->wfd_subelems) {
1475 wpabuf_free(dev->info.wfd_subelems);
1476 dev->info.wfd_subelems = wpabuf_dup(msg->wfd_subelems);
1477 }
1478
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07001479 if (dev->flags & P2P_DEV_PROBE_REQ_ONLY) {
1480 dev->flags &= ~P2P_DEV_PROBE_REQ_ONLY;
1481 wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG,
1482 "P2P: Completed device entry based on data from "
1483 "GO Negotiation Request");
1484 } else {
1485 wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG,
1486 "P2P: Created device entry based on GO Neg Req: "
1487 MACSTR " dev_capab=0x%x group_capab=0x%x name='%s' "
1488 "listen_freq=%d",
1489 MAC2STR(dev->info.p2p_device_addr),
1490 dev->info.dev_capab, dev->info.group_capab,
1491 dev->info.device_name, dev->listen_freq);
1492 }
1493
1494 dev->flags &= ~P2P_DEV_GROUP_CLIENT_ONLY;
1495
1496 if (dev->flags & P2P_DEV_USER_REJECTED) {
1497 wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG,
1498 "P2P: Do not report rejected device");
1499 return;
1500 }
1501
1502 p2p->cfg->dev_found(p2p->cfg->cb_ctx, addr, &dev->info,
1503 !(dev->flags & P2P_DEV_REPORTED_ONCE));
1504 dev->flags |= P2P_DEV_REPORTED | P2P_DEV_REPORTED_ONCE;
1505}
1506
1507
1508void p2p_build_ssid(struct p2p_data *p2p, u8 *ssid, size_t *ssid_len)
1509{
1510 os_memcpy(ssid, P2P_WILDCARD_SSID, P2P_WILDCARD_SSID_LEN);
1511 p2p_random((char *) &ssid[P2P_WILDCARD_SSID_LEN], 2);
1512 os_memcpy(&ssid[P2P_WILDCARD_SSID_LEN + 2],
1513 p2p->cfg->ssid_postfix, p2p->cfg->ssid_postfix_len);
1514 *ssid_len = P2P_WILDCARD_SSID_LEN + 2 + p2p->cfg->ssid_postfix_len;
1515}
1516
1517
1518int p2p_go_params(struct p2p_data *p2p, struct p2p_go_neg_results *params)
1519{
1520 p2p_build_ssid(p2p, params->ssid, &params->ssid_len);
1521 p2p_random(params->passphrase, 8);
1522 return 0;
1523}
1524
1525
1526void p2p_go_complete(struct p2p_data *p2p, struct p2p_device *peer)
1527{
1528 struct p2p_go_neg_results res;
1529 int go = peer->go_state == LOCAL_GO;
1530 struct p2p_channels intersection;
1531 int freqs;
1532 size_t i, j;
1533
1534 wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG,
1535 "P2P: GO Negotiation with " MACSTR " completed (%s will be "
1536 "GO)", MAC2STR(peer->info.p2p_device_addr),
1537 go ? "local end" : "peer");
1538
1539 os_memset(&res, 0, sizeof(res));
1540 res.role_go = go;
1541 os_memcpy(res.peer_device_addr, peer->info.p2p_device_addr, ETH_ALEN);
1542 os_memcpy(res.peer_interface_addr, peer->intended_addr, ETH_ALEN);
1543 res.wps_method = peer->wps_method;
Dmitry Shmidt1f69aa52012-01-24 16:10:04 -08001544 if (peer->flags & P2P_DEV_PREFER_PERSISTENT_GROUP) {
1545 if (peer->flags & P2P_DEV_PREFER_PERSISTENT_RECONN)
1546 res.persistent_group = 2;
1547 else
1548 res.persistent_group = 1;
1549 }
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07001550
1551 if (go) {
1552 /* Setup AP mode for WPS provisioning */
1553 res.freq = p2p_channel_to_freq(p2p->cfg->country,
1554 p2p->op_reg_class,
1555 p2p->op_channel);
1556 os_memcpy(res.ssid, p2p->ssid, p2p->ssid_len);
1557 res.ssid_len = p2p->ssid_len;
1558 p2p_random(res.passphrase, 8);
1559 } else {
1560 res.freq = peer->oper_freq;
1561 if (p2p->ssid_len) {
1562 os_memcpy(res.ssid, p2p->ssid, p2p->ssid_len);
1563 res.ssid_len = p2p->ssid_len;
1564 }
1565 }
1566
1567 p2p_channels_intersect(&p2p->channels, &peer->channels,
1568 &intersection);
1569 freqs = 0;
1570 for (i = 0; i < intersection.reg_classes; i++) {
1571 struct p2p_reg_class *c = &intersection.reg_class[i];
1572 if (freqs + 1 == P2P_MAX_CHANNELS)
1573 break;
1574 for (j = 0; j < c->channels; j++) {
1575 int freq;
1576 if (freqs + 1 == P2P_MAX_CHANNELS)
1577 break;
1578 freq = p2p_channel_to_freq(peer->country, c->reg_class,
1579 c->channel[j]);
1580 if (freq < 0)
1581 continue;
1582 res.freq_list[freqs++] = freq;
1583 }
1584 }
1585
1586 res.peer_config_timeout = go ? peer->client_timeout : peer->go_timeout;
1587
1588 p2p_clear_timeout(p2p);
Dmitry Shmidt1f69aa52012-01-24 16:10:04 -08001589 p2p->ssid_set = 0;
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07001590 peer->go_neg_req_sent = 0;
1591 peer->wps_method = WPS_NOT_READY;
1592
1593 p2p_set_state(p2p, P2P_PROVISIONING);
1594 p2p->cfg->go_neg_completed(p2p->cfg->cb_ctx, &res);
1595}
1596
1597
1598static void p2p_rx_p2p_action(struct p2p_data *p2p, const u8 *sa,
1599 const u8 *data, size_t len, int rx_freq)
1600{
1601 wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG,
1602 "P2P: RX P2P Public Action from " MACSTR, MAC2STR(sa));
1603 wpa_hexdump(MSG_MSGDUMP, "P2P: P2P Public Action contents", data, len);
1604
1605 if (len < 1)
1606 return;
1607
1608 switch (data[0]) {
1609 case P2P_GO_NEG_REQ:
1610 p2p_process_go_neg_req(p2p, sa, data + 1, len - 1, rx_freq);
1611 break;
1612 case P2P_GO_NEG_RESP:
1613 p2p_process_go_neg_resp(p2p, sa, data + 1, len - 1, rx_freq);
1614 break;
1615 case P2P_GO_NEG_CONF:
1616 p2p_process_go_neg_conf(p2p, sa, data + 1, len - 1);
1617 break;
1618 case P2P_INVITATION_REQ:
1619 p2p_process_invitation_req(p2p, sa, data + 1, len - 1,
1620 rx_freq);
1621 break;
1622 case P2P_INVITATION_RESP:
1623 p2p_process_invitation_resp(p2p, sa, data + 1, len - 1);
1624 break;
1625 case P2P_PROV_DISC_REQ:
1626 p2p_process_prov_disc_req(p2p, sa, data + 1, len - 1, rx_freq);
1627 break;
1628 case P2P_PROV_DISC_RESP:
1629 p2p_process_prov_disc_resp(p2p, sa, data + 1, len - 1);
1630 break;
1631 case P2P_DEV_DISC_REQ:
1632 p2p_process_dev_disc_req(p2p, sa, data + 1, len - 1, rx_freq);
1633 break;
1634 case P2P_DEV_DISC_RESP:
1635 p2p_process_dev_disc_resp(p2p, sa, data + 1, len - 1);
1636 break;
1637 default:
1638 wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG,
1639 "P2P: Unsupported P2P Public Action frame type %d",
1640 data[0]);
1641 break;
1642 }
1643}
1644
1645
Dmitry Shmidt1f69aa52012-01-24 16:10:04 -08001646static void p2p_rx_action_public(struct p2p_data *p2p, const u8 *da,
1647 const u8 *sa, const u8 *bssid, const u8 *data,
1648 size_t len, int freq)
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07001649{
1650 if (len < 1)
1651 return;
1652
1653 switch (data[0]) {
1654 case WLAN_PA_VENDOR_SPECIFIC:
1655 data++;
1656 len--;
1657 if (len < 3)
1658 return;
1659 if (WPA_GET_BE24(data) != OUI_WFA)
1660 return;
1661
1662 data += 3;
1663 len -= 3;
1664 if (len < 1)
1665 return;
1666
1667 if (*data != P2P_OUI_TYPE)
1668 return;
1669
1670 p2p_rx_p2p_action(p2p, sa, data + 1, len - 1, freq);
1671 break;
1672 case WLAN_PA_GAS_INITIAL_REQ:
1673 p2p_rx_gas_initial_req(p2p, sa, data + 1, len - 1, freq);
1674 break;
1675 case WLAN_PA_GAS_INITIAL_RESP:
1676 p2p_rx_gas_initial_resp(p2p, sa, data + 1, len - 1, freq);
1677 break;
1678 case WLAN_PA_GAS_COMEBACK_REQ:
1679 p2p_rx_gas_comeback_req(p2p, sa, data + 1, len - 1, freq);
1680 break;
1681 case WLAN_PA_GAS_COMEBACK_RESP:
1682 p2p_rx_gas_comeback_resp(p2p, sa, data + 1, len - 1, freq);
1683 break;
1684 }
1685}
1686
1687
1688void p2p_rx_action(struct p2p_data *p2p, const u8 *da, const u8 *sa,
1689 const u8 *bssid, u8 category,
1690 const u8 *data, size_t len, int freq)
1691{
1692 if (category == WLAN_ACTION_PUBLIC) {
1693 p2p_rx_action_public(p2p, da, sa, bssid, data, len, freq);
1694 return;
1695 }
1696
1697 if (category != WLAN_ACTION_VENDOR_SPECIFIC)
1698 return;
1699
1700 if (len < 4)
1701 return;
1702
1703 if (WPA_GET_BE24(data) != OUI_WFA)
1704 return;
1705 data += 3;
1706 len -= 3;
1707
1708 if (*data != P2P_OUI_TYPE)
1709 return;
1710 data++;
1711 len--;
1712
1713 /* P2P action frame */
1714 wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG,
1715 "P2P: RX P2P Action from " MACSTR, MAC2STR(sa));
1716 wpa_hexdump(MSG_MSGDUMP, "P2P: P2P Action contents", data, len);
1717
1718 if (len < 1)
1719 return;
1720 switch (data[0]) {
1721 case P2P_NOA:
1722 wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG,
1723 "P2P: Received P2P Action - Notice of Absence");
1724 /* TODO */
1725 break;
1726 case P2P_PRESENCE_REQ:
1727 p2p_process_presence_req(p2p, da, sa, data + 1, len - 1, freq);
1728 break;
1729 case P2P_PRESENCE_RESP:
1730 p2p_process_presence_resp(p2p, da, sa, data + 1, len - 1);
1731 break;
1732 case P2P_GO_DISC_REQ:
1733 p2p_process_go_disc_req(p2p, da, sa, data + 1, len - 1, freq);
1734 break;
1735 default:
1736 wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG,
1737 "P2P: Received P2P Action - unknown type %u", data[0]);
1738 break;
1739 }
1740}
1741
1742
1743static void p2p_go_neg_start(void *eloop_ctx, void *timeout_ctx)
1744{
1745 struct p2p_data *p2p = eloop_ctx;
1746 if (p2p->go_neg_peer == NULL)
1747 return;
1748 p2p->cfg->stop_listen(p2p->cfg->cb_ctx);
1749 p2p->go_neg_peer->status = P2P_SC_SUCCESS;
1750 p2p_connect_send(p2p, p2p->go_neg_peer);
1751}
1752
1753
1754static void p2p_invite_start(void *eloop_ctx, void *timeout_ctx)
1755{
1756 struct p2p_data *p2p = eloop_ctx;
1757 if (p2p->invite_peer == NULL)
1758 return;
1759 p2p->cfg->stop_listen(p2p->cfg->cb_ctx);
1760 p2p_invite_send(p2p, p2p->invite_peer, p2p->invite_go_dev_addr);
1761}
1762
1763
1764static void p2p_add_dev_from_probe_req(struct p2p_data *p2p, const u8 *addr,
1765 const u8 *ie, size_t ie_len)
1766{
1767 struct p2p_message msg;
1768 struct p2p_device *dev;
1769
1770 os_memset(&msg, 0, sizeof(msg));
1771 if (p2p_parse_ies(ie, ie_len, &msg) < 0 || msg.p2p_attributes == NULL)
1772 {
1773 p2p_parse_free(&msg);
1774 return; /* not a P2P probe */
1775 }
1776
1777 if (msg.ssid == NULL || msg.ssid[1] != P2P_WILDCARD_SSID_LEN ||
1778 os_memcmp(msg.ssid + 2, P2P_WILDCARD_SSID, P2P_WILDCARD_SSID_LEN)
1779 != 0) {
1780 /* The Probe Request is not part of P2P Device Discovery. It is
1781 * not known whether the source address of the frame is the P2P
1782 * Device Address or P2P Interface Address. Do not add a new
1783 * peer entry based on this frames.
1784 */
1785 p2p_parse_free(&msg);
1786 return;
1787 }
1788
1789 dev = p2p_get_device(p2p, addr);
1790 if (dev) {
1791 if (dev->country[0] == 0 && msg.listen_channel)
1792 os_memcpy(dev->country, msg.listen_channel, 3);
Dmitry Shmidt1f69aa52012-01-24 16:10:04 -08001793 os_get_time(&dev->last_seen);
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07001794 p2p_parse_free(&msg);
1795 return; /* already known */
1796 }
1797
1798 dev = p2p_create_device(p2p, addr);
1799 if (dev == NULL) {
1800 p2p_parse_free(&msg);
1801 return;
1802 }
1803
1804 os_get_time(&dev->last_seen);
1805 dev->flags |= P2P_DEV_PROBE_REQ_ONLY;
1806
1807 if (msg.listen_channel) {
1808 os_memcpy(dev->country, msg.listen_channel, 3);
1809 dev->listen_freq = p2p_channel_to_freq(dev->country,
1810 msg.listen_channel[3],
1811 msg.listen_channel[4]);
1812 }
1813
1814 p2p_copy_wps_info(dev, 1, &msg);
1815
Dmitry Shmidt61d9df32012-08-29 16:22:06 -07001816 if (msg.wfd_subelems) {
1817 wpabuf_free(dev->info.wfd_subelems);
1818 dev->info.wfd_subelems = wpabuf_dup(msg.wfd_subelems);
1819 }
1820
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07001821 p2p_parse_free(&msg);
1822
1823 wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG,
1824 "P2P: Created device entry based on Probe Req: " MACSTR
1825 " dev_capab=0x%x group_capab=0x%x name='%s' listen_freq=%d",
1826 MAC2STR(dev->info.p2p_device_addr), dev->info.dev_capab,
1827 dev->info.group_capab, dev->info.device_name,
1828 dev->listen_freq);
1829}
1830
1831
1832struct p2p_device * p2p_add_dev_from_go_neg_req(struct p2p_data *p2p,
1833 const u8 *addr,
1834 struct p2p_message *msg)
1835{
1836 struct p2p_device *dev;
1837
1838 dev = p2p_get_device(p2p, addr);
1839 if (dev) {
1840 os_get_time(&dev->last_seen);
1841 return dev; /* already known */
1842 }
1843
1844 dev = p2p_create_device(p2p, addr);
1845 if (dev == NULL)
1846 return NULL;
1847
1848 p2p_add_dev_info(p2p, addr, dev, msg);
1849
1850 return dev;
1851}
1852
1853
1854static int dev_type_match(const u8 *dev_type, const u8 *req_dev_type)
1855{
1856 if (os_memcmp(dev_type, req_dev_type, WPS_DEV_TYPE_LEN) == 0)
1857 return 1;
1858 if (os_memcmp(dev_type, req_dev_type, 2) == 0 &&
1859 WPA_GET_BE32(&req_dev_type[2]) == 0 &&
1860 WPA_GET_BE16(&req_dev_type[6]) == 0)
1861 return 1; /* Category match with wildcard OUI/sub-category */
1862 return 0;
1863}
1864
1865
1866int dev_type_list_match(const u8 *dev_type, const u8 *req_dev_type[],
1867 size_t num_req_dev_type)
1868{
1869 size_t i;
1870 for (i = 0; i < num_req_dev_type; i++) {
1871 if (dev_type_match(dev_type, req_dev_type[i]))
1872 return 1;
1873 }
1874 return 0;
1875}
1876
1877
1878/**
1879 * p2p_match_dev_type - Match local device type with requested type
1880 * @p2p: P2P module context from p2p_init()
1881 * @wps: WPS TLVs from Probe Request frame (concatenated WPS IEs)
1882 * Returns: 1 on match, 0 on mismatch
1883 *
1884 * This function can be used to match the Requested Device Type attribute in
1885 * WPS IE with the local device types for deciding whether to reply to a Probe
1886 * Request frame.
1887 */
1888int p2p_match_dev_type(struct p2p_data *p2p, struct wpabuf *wps)
1889{
1890 struct wps_parse_attr attr;
1891 size_t i;
1892
1893 if (wps_parse_msg(wps, &attr))
1894 return 1; /* assume no Requested Device Type attributes */
1895
1896 if (attr.num_req_dev_type == 0)
1897 return 1; /* no Requested Device Type attributes -> match */
1898
1899 if (dev_type_list_match(p2p->cfg->pri_dev_type, attr.req_dev_type,
1900 attr.num_req_dev_type))
1901 return 1; /* Own Primary Device Type matches */
1902
1903 for (i = 0; i < p2p->cfg->num_sec_dev_types; i++)
1904 if (dev_type_list_match(p2p->cfg->sec_dev_type[i],
1905 attr.req_dev_type,
1906 attr.num_req_dev_type))
1907 return 1; /* Own Secondary Device Type matches */
1908
1909 /* No matching device type found */
1910 return 0;
1911}
1912
1913
1914struct wpabuf * p2p_build_probe_resp_ies(struct p2p_data *p2p)
1915{
1916 struct wpabuf *buf;
1917 u8 *len;
Dmitry Shmidt04949592012-07-19 12:16:46 -07001918 int pw_id = -1;
Dmitry Shmidt61d9df32012-08-29 16:22:06 -07001919 size_t extra = 0;
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07001920
Dmitry Shmidt61d9df32012-08-29 16:22:06 -07001921#ifdef CONFIG_WIFI_DISPLAY
1922 if (p2p->wfd_ie_probe_resp)
1923 extra = wpabuf_len(p2p->wfd_ie_probe_resp);
1924#endif /* CONFIG_WIFI_DISPLAY */
1925
1926 buf = wpabuf_alloc(1000 + extra);
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07001927 if (buf == NULL)
1928 return NULL;
1929
Dmitry Shmidt04949592012-07-19 12:16:46 -07001930 if (p2p->go_neg_peer) {
1931 /* Advertise immediate availability of WPS credential */
1932 pw_id = p2p_wps_method_pw_id(p2p->go_neg_peer->wps_method);
1933 }
1934
1935 p2p_build_wps_ie(p2p, buf, pw_id, 1);
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07001936
Dmitry Shmidt61d9df32012-08-29 16:22:06 -07001937#ifdef CONFIG_WIFI_DISPLAY
1938 if (p2p->wfd_ie_probe_resp)
1939 wpabuf_put_buf(buf, p2p->wfd_ie_probe_resp);
1940#endif /* CONFIG_WIFI_DISPLAY */
1941
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07001942 /* P2P IE */
1943 len = p2p_buf_add_ie_hdr(buf);
Dmitry Shmidt04949592012-07-19 12:16:46 -07001944 p2p_buf_add_capability(buf, p2p->dev_capab &
1945 ~P2P_DEV_CAPAB_CLIENT_DISCOVERABILITY, 0);
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07001946 if (p2p->ext_listen_interval)
1947 p2p_buf_add_ext_listen_timing(buf, p2p->ext_listen_period,
1948 p2p->ext_listen_interval);
1949 p2p_buf_add_device_info(buf, p2p, NULL);
1950 p2p_buf_update_ie_hdr(buf, len);
1951
1952 return buf;
1953}
1954
1955
Dmitry Shmidt1f69aa52012-01-24 16:10:04 -08001956static int is_11b(u8 rate)
1957{
1958 return rate == 0x02 || rate == 0x04 || rate == 0x0b || rate == 0x16;
1959}
1960
1961
1962static int supp_rates_11b_only(struct ieee802_11_elems *elems)
1963{
1964 int num_11b = 0, num_others = 0;
1965 int i;
1966
1967 if (elems->supp_rates == NULL && elems->ext_supp_rates == NULL)
1968 return 0;
1969
1970 for (i = 0; elems->supp_rates && i < elems->supp_rates_len; i++) {
1971 if (is_11b(elems->supp_rates[i]))
1972 num_11b++;
1973 else
1974 num_others++;
1975 }
1976
1977 for (i = 0; elems->ext_supp_rates && i < elems->ext_supp_rates_len;
1978 i++) {
1979 if (is_11b(elems->ext_supp_rates[i]))
1980 num_11b++;
1981 else
1982 num_others++;
1983 }
1984
1985 return num_11b > 0 && num_others == 0;
1986}
1987
1988
Dmitry Shmidt04949592012-07-19 12:16:46 -07001989static enum p2p_probe_req_status
1990p2p_reply_probe(struct p2p_data *p2p, const u8 *addr, const u8 *dst,
1991 const u8 *bssid, const u8 *ie, size_t ie_len)
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07001992{
1993 struct ieee802_11_elems elems;
1994 struct wpabuf *buf;
1995 struct ieee80211_mgmt *resp;
Dmitry Shmidt1f69aa52012-01-24 16:10:04 -08001996 struct p2p_message msg;
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07001997 struct wpabuf *ies;
1998
1999 if (!p2p->in_listen || !p2p->drv_in_listen) {
2000 /* not in Listen state - ignore Probe Request */
Dmitry Shmidt04949592012-07-19 12:16:46 -07002001 return P2P_PREQ_NOT_LISTEN;
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07002002 }
2003
2004 if (ieee802_11_parse_elems((u8 *) ie, ie_len, &elems, 0) ==
2005 ParseFailed) {
2006 /* Ignore invalid Probe Request frames */
Dmitry Shmidt04949592012-07-19 12:16:46 -07002007 return P2P_PREQ_MALFORMED;
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07002008 }
2009
2010 if (elems.p2p == NULL) {
2011 /* not a P2P probe - ignore it */
Dmitry Shmidt04949592012-07-19 12:16:46 -07002012 return P2P_PREQ_NOT_P2P;
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07002013 }
2014
Dmitry Shmidt1f69aa52012-01-24 16:10:04 -08002015 if (dst && !is_broadcast_ether_addr(dst) &&
2016 os_memcmp(dst, p2p->cfg->dev_addr, ETH_ALEN) != 0) {
2017 /* Not sent to the broadcast address or our P2P Device Address
2018 */
Dmitry Shmidt04949592012-07-19 12:16:46 -07002019 return P2P_PREQ_NOT_PROCESSED;
Dmitry Shmidt1f69aa52012-01-24 16:10:04 -08002020 }
2021
2022 if (bssid && !is_broadcast_ether_addr(bssid)) {
2023 /* Not sent to the Wildcard BSSID */
Dmitry Shmidt04949592012-07-19 12:16:46 -07002024 return P2P_PREQ_NOT_PROCESSED;
Dmitry Shmidt1f69aa52012-01-24 16:10:04 -08002025 }
2026
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07002027 if (elems.ssid == NULL || elems.ssid_len != P2P_WILDCARD_SSID_LEN ||
2028 os_memcmp(elems.ssid, P2P_WILDCARD_SSID, P2P_WILDCARD_SSID_LEN) !=
2029 0) {
2030 /* not using P2P Wildcard SSID - ignore */
Dmitry Shmidt04949592012-07-19 12:16:46 -07002031 return P2P_PREQ_NOT_PROCESSED;
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07002032 }
2033
Dmitry Shmidt1f69aa52012-01-24 16:10:04 -08002034 if (supp_rates_11b_only(&elems)) {
2035 /* Indicates support for 11b rates only */
Dmitry Shmidt04949592012-07-19 12:16:46 -07002036 return P2P_PREQ_NOT_P2P;
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07002037 }
Dmitry Shmidt1f69aa52012-01-24 16:10:04 -08002038
2039 os_memset(&msg, 0, sizeof(msg));
2040 if (p2p_parse_ies(ie, ie_len, &msg) < 0) {
2041 /* Could not parse P2P attributes */
Dmitry Shmidt04949592012-07-19 12:16:46 -07002042 return P2P_PREQ_NOT_P2P;
Dmitry Shmidt1f69aa52012-01-24 16:10:04 -08002043 }
2044
2045 if (msg.device_id &&
Dmitry Shmidt04949592012-07-19 12:16:46 -07002046 os_memcmp(msg.device_id, p2p->cfg->dev_addr, ETH_ALEN) != 0) {
Dmitry Shmidt1f69aa52012-01-24 16:10:04 -08002047 /* Device ID did not match */
2048 p2p_parse_free(&msg);
Dmitry Shmidt04949592012-07-19 12:16:46 -07002049 return P2P_PREQ_NOT_PROCESSED;
Dmitry Shmidt1f69aa52012-01-24 16:10:04 -08002050 }
2051
2052 /* Check Requested Device Type match */
2053 if (msg.wps_attributes &&
2054 !p2p_match_dev_type(p2p, msg.wps_attributes)) {
2055 /* No match with Requested Device Type */
2056 p2p_parse_free(&msg);
Dmitry Shmidt04949592012-07-19 12:16:46 -07002057 return P2P_PREQ_NOT_PROCESSED;
Dmitry Shmidt1f69aa52012-01-24 16:10:04 -08002058 }
2059 p2p_parse_free(&msg);
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07002060
Dmitry Shmidt04949592012-07-19 12:16:46 -07002061 if (!p2p->cfg->send_probe_resp) {
2062 /* Response generated elsewhere */
2063 return P2P_PREQ_NOT_PROCESSED;
2064 }
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07002065
2066 wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG,
2067 "P2P: Reply to P2P Probe Request in Listen state");
2068
2069 /*
2070 * We do not really have a specific BSS that this frame is advertising,
2071 * so build a frame that has some information in valid format. This is
2072 * really only used for discovery purposes, not to learn exact BSS
2073 * parameters.
2074 */
2075 ies = p2p_build_probe_resp_ies(p2p);
2076 if (ies == NULL)
Dmitry Shmidt04949592012-07-19 12:16:46 -07002077 return P2P_PREQ_NOT_PROCESSED;
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07002078
2079 buf = wpabuf_alloc(200 + wpabuf_len(ies));
2080 if (buf == NULL) {
2081 wpabuf_free(ies);
Dmitry Shmidt04949592012-07-19 12:16:46 -07002082 return P2P_PREQ_NOT_PROCESSED;
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07002083 }
2084
2085 resp = NULL;
2086 resp = wpabuf_put(buf, resp->u.probe_resp.variable - (u8 *) resp);
2087
2088 resp->frame_control = host_to_le16((WLAN_FC_TYPE_MGMT << 2) |
2089 (WLAN_FC_STYPE_PROBE_RESP << 4));
2090 os_memcpy(resp->da, addr, ETH_ALEN);
2091 os_memcpy(resp->sa, p2p->cfg->dev_addr, ETH_ALEN);
2092 os_memcpy(resp->bssid, p2p->cfg->dev_addr, ETH_ALEN);
2093 resp->u.probe_resp.beacon_int = host_to_le16(100);
2094 /* hardware or low-level driver will setup seq_ctrl and timestamp */
2095 resp->u.probe_resp.capab_info =
2096 host_to_le16(WLAN_CAPABILITY_SHORT_PREAMBLE |
2097 WLAN_CAPABILITY_PRIVACY |
2098 WLAN_CAPABILITY_SHORT_SLOT_TIME);
2099
2100 wpabuf_put_u8(buf, WLAN_EID_SSID);
2101 wpabuf_put_u8(buf, P2P_WILDCARD_SSID_LEN);
2102 wpabuf_put_data(buf, P2P_WILDCARD_SSID, P2P_WILDCARD_SSID_LEN);
2103
2104 wpabuf_put_u8(buf, WLAN_EID_SUPP_RATES);
2105 wpabuf_put_u8(buf, 8);
2106 wpabuf_put_u8(buf, (60 / 5) | 0x80);
2107 wpabuf_put_u8(buf, 90 / 5);
2108 wpabuf_put_u8(buf, (120 / 5) | 0x80);
2109 wpabuf_put_u8(buf, 180 / 5);
2110 wpabuf_put_u8(buf, (240 / 5) | 0x80);
2111 wpabuf_put_u8(buf, 360 / 5);
2112 wpabuf_put_u8(buf, 480 / 5);
2113 wpabuf_put_u8(buf, 540 / 5);
2114
2115 wpabuf_put_u8(buf, WLAN_EID_DS_PARAMS);
2116 wpabuf_put_u8(buf, 1);
2117 wpabuf_put_u8(buf, p2p->cfg->channel);
2118
2119 wpabuf_put_buf(buf, ies);
2120 wpabuf_free(ies);
2121
2122 p2p->cfg->send_probe_resp(p2p->cfg->cb_ctx, buf);
2123
2124 wpabuf_free(buf);
Dmitry Shmidt04949592012-07-19 12:16:46 -07002125
2126 return P2P_PREQ_NOT_PROCESSED;
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07002127}
2128
2129
Dmitry Shmidt04949592012-07-19 12:16:46 -07002130enum p2p_probe_req_status
2131p2p_probe_req_rx(struct p2p_data *p2p, const u8 *addr, const u8 *dst,
2132 const u8 *bssid, const u8 *ie, size_t ie_len)
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07002133{
Dmitry Shmidt04949592012-07-19 12:16:46 -07002134 enum p2p_probe_req_status res;
2135
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07002136 p2p_add_dev_from_probe_req(p2p, addr, ie, ie_len);
2137
Dmitry Shmidt04949592012-07-19 12:16:46 -07002138 res = p2p_reply_probe(p2p, addr, dst, bssid, ie, ie_len);
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07002139
2140 if ((p2p->state == P2P_CONNECT || p2p->state == P2P_CONNECT_LISTEN) &&
2141 p2p->go_neg_peer &&
2142 os_memcmp(addr, p2p->go_neg_peer->info.p2p_device_addr, ETH_ALEN)
2143 == 0) {
2144 /* Received a Probe Request from GO Negotiation peer */
2145 wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG,
2146 "P2P: Found GO Negotiation peer - try to start GO "
2147 "negotiation from timeout");
2148 eloop_register_timeout(0, 0, p2p_go_neg_start, p2p, NULL);
Dmitry Shmidt04949592012-07-19 12:16:46 -07002149 return P2P_PREQ_PROCESSED;
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07002150 }
2151
2152 if ((p2p->state == P2P_INVITE || p2p->state == P2P_INVITE_LISTEN) &&
2153 p2p->invite_peer &&
2154 os_memcmp(addr, p2p->invite_peer->info.p2p_device_addr, ETH_ALEN)
2155 == 0) {
2156 /* Received a Probe Request from Invite peer */
2157 wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG,
2158 "P2P: Found Invite peer - try to start Invite from "
2159 "timeout");
2160 eloop_register_timeout(0, 0, p2p_invite_start, p2p, NULL);
Dmitry Shmidt04949592012-07-19 12:16:46 -07002161 return P2P_PREQ_PROCESSED;
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07002162 }
2163
Dmitry Shmidt04949592012-07-19 12:16:46 -07002164 return res;
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07002165}
2166
2167
2168static int p2p_assoc_req_ie_wlan_ap(struct p2p_data *p2p, const u8 *bssid,
2169 u8 *buf, size_t len, struct wpabuf *p2p_ie)
2170{
2171 struct wpabuf *tmp;
2172 u8 *lpos;
2173 size_t tmplen;
2174 int res;
2175 u8 group_capab;
2176
2177 if (p2p_ie == NULL)
2178 return 0; /* WLAN AP is not a P2P manager */
2179
2180 /*
2181 * (Re)Association Request - P2P IE
2182 * P2P Capability attribute (shall be present)
2183 * P2P Interface attribute (present if concurrent device and
2184 * P2P Management is enabled)
2185 */
2186 tmp = wpabuf_alloc(200);
2187 if (tmp == NULL)
2188 return -1;
2189
2190 lpos = p2p_buf_add_ie_hdr(tmp);
2191 group_capab = 0;
2192 if (p2p->num_groups > 0) {
2193 group_capab |= P2P_GROUP_CAPAB_GROUP_OWNER;
2194 if ((p2p->dev_capab & P2P_DEV_CAPAB_CONCURRENT_OPER) &&
2195 (p2p->dev_capab & P2P_DEV_CAPAB_INFRA_MANAGED) &&
2196 p2p->cross_connect)
2197 group_capab |= P2P_GROUP_CAPAB_CROSS_CONN;
2198 }
2199 p2p_buf_add_capability(tmp, p2p->dev_capab, group_capab);
2200 if ((p2p->dev_capab & P2P_DEV_CAPAB_CONCURRENT_OPER) &&
2201 (p2p->dev_capab & P2P_DEV_CAPAB_INFRA_MANAGED))
2202 p2p_buf_add_p2p_interface(tmp, p2p);
2203 p2p_buf_update_ie_hdr(tmp, lpos);
2204
2205 tmplen = wpabuf_len(tmp);
2206 if (tmplen > len)
2207 res = -1;
2208 else {
2209 os_memcpy(buf, wpabuf_head(tmp), tmplen);
2210 res = tmplen;
2211 }
2212 wpabuf_free(tmp);
2213
2214 return res;
2215}
2216
2217
2218int p2p_assoc_req_ie(struct p2p_data *p2p, const u8 *bssid, u8 *buf,
2219 size_t len, int p2p_group, struct wpabuf *p2p_ie)
2220{
2221 struct wpabuf *tmp;
2222 u8 *lpos;
2223 struct p2p_device *peer;
2224 size_t tmplen;
2225 int res;
Dmitry Shmidt61d9df32012-08-29 16:22:06 -07002226 size_t extra = 0;
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07002227
2228 if (!p2p_group)
2229 return p2p_assoc_req_ie_wlan_ap(p2p, bssid, buf, len, p2p_ie);
2230
Dmitry Shmidt61d9df32012-08-29 16:22:06 -07002231#ifdef CONFIG_WIFI_DISPLAY
2232 if (p2p->wfd_ie_assoc_req)
2233 extra = wpabuf_len(p2p->wfd_ie_assoc_req);
2234#endif /* CONFIG_WIFI_DISPLAY */
2235
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07002236 /*
2237 * (Re)Association Request - P2P IE
2238 * P2P Capability attribute (shall be present)
2239 * Extended Listen Timing (may be present)
2240 * P2P Device Info attribute (shall be present)
2241 */
Dmitry Shmidt61d9df32012-08-29 16:22:06 -07002242 tmp = wpabuf_alloc(200 + extra);
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07002243 if (tmp == NULL)
2244 return -1;
2245
Dmitry Shmidt61d9df32012-08-29 16:22:06 -07002246#ifdef CONFIG_WIFI_DISPLAY
2247 if (p2p->wfd_ie_assoc_req)
2248 wpabuf_put_buf(tmp, p2p->wfd_ie_assoc_req);
2249#endif /* CONFIG_WIFI_DISPLAY */
2250
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07002251 peer = bssid ? p2p_get_device(p2p, bssid) : NULL;
2252
2253 lpos = p2p_buf_add_ie_hdr(tmp);
2254 p2p_buf_add_capability(tmp, p2p->dev_capab, 0);
2255 if (p2p->ext_listen_interval)
2256 p2p_buf_add_ext_listen_timing(tmp, p2p->ext_listen_period,
2257 p2p->ext_listen_interval);
2258 p2p_buf_add_device_info(tmp, p2p, peer);
2259 p2p_buf_update_ie_hdr(tmp, lpos);
2260
2261 tmplen = wpabuf_len(tmp);
2262 if (tmplen > len)
2263 res = -1;
2264 else {
2265 os_memcpy(buf, wpabuf_head(tmp), tmplen);
2266 res = tmplen;
2267 }
2268 wpabuf_free(tmp);
2269
2270 return res;
2271}
2272
2273
2274int p2p_scan_result_text(const u8 *ies, size_t ies_len, char *buf, char *end)
2275{
2276 struct wpabuf *p2p_ie;
2277 int ret;
2278
2279 p2p_ie = ieee802_11_vendor_ie_concat(ies, ies_len, P2P_IE_VENDOR_TYPE);
2280 if (p2p_ie == NULL)
2281 return 0;
2282
2283 ret = p2p_attr_text(p2p_ie, buf, end);
2284 wpabuf_free(p2p_ie);
2285 return ret;
2286}
2287
2288
Dmitry Shmidt04949592012-07-19 12:16:46 -07002289int p2p_parse_dev_addr_in_p2p_ie(struct wpabuf *p2p_ie, u8 *dev_addr)
2290{
2291 struct p2p_message msg;
2292
2293 os_memset(&msg, 0, sizeof(msg));
2294 if (p2p_parse_p2p_ie(p2p_ie, &msg))
2295 return -1;
2296
2297 if (msg.p2p_device_addr) {
2298 os_memcpy(dev_addr, msg.p2p_device_addr, ETH_ALEN);
2299 return 0;
2300 } else if (msg.device_id) {
2301 os_memcpy(dev_addr, msg.device_id, ETH_ALEN);
2302 return 0;
2303 }
2304 return -1;
2305}
2306
2307
Dmitry Shmidtc5ec7f52012-03-06 16:33:24 -08002308int p2p_parse_dev_addr(const u8 *ies, size_t ies_len, u8 *dev_addr)
2309{
2310 struct wpabuf *p2p_ie;
Dmitry Shmidt04949592012-07-19 12:16:46 -07002311 int ret;
Dmitry Shmidtc5ec7f52012-03-06 16:33:24 -08002312
2313 p2p_ie = ieee802_11_vendor_ie_concat(ies, ies_len,
2314 P2P_IE_VENDOR_TYPE);
2315 if (p2p_ie == NULL)
2316 return -1;
Dmitry Shmidt04949592012-07-19 12:16:46 -07002317 ret = p2p_parse_dev_addr_in_p2p_ie(p2p_ie, dev_addr);
Dmitry Shmidtc5ec7f52012-03-06 16:33:24 -08002318 wpabuf_free(p2p_ie);
Dmitry Shmidt04949592012-07-19 12:16:46 -07002319 return ret;
Dmitry Shmidtc5ec7f52012-03-06 16:33:24 -08002320}
2321
2322
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07002323static void p2p_clear_go_neg(struct p2p_data *p2p)
2324{
2325 p2p->go_neg_peer = NULL;
2326 p2p_clear_timeout(p2p);
2327 p2p_set_state(p2p, P2P_IDLE);
2328}
2329
2330
2331void p2p_wps_success_cb(struct p2p_data *p2p, const u8 *mac_addr)
2332{
2333 if (p2p->go_neg_peer == NULL) {
2334 wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG,
2335 "P2P: No pending Group Formation - "
2336 "ignore WPS registration success notification");
2337 return; /* No pending Group Formation */
2338 }
2339
2340 if (os_memcmp(mac_addr, p2p->go_neg_peer->intended_addr, ETH_ALEN) !=
2341 0) {
2342 wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG,
2343 "P2P: Ignore WPS registration success notification "
2344 "for " MACSTR " (GO Negotiation peer " MACSTR ")",
2345 MAC2STR(mac_addr),
2346 MAC2STR(p2p->go_neg_peer->intended_addr));
2347 return; /* Ignore unexpected peer address */
2348 }
2349
2350 wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG,
2351 "P2P: Group Formation completed successfully with " MACSTR,
2352 MAC2STR(mac_addr));
2353
2354 p2p_clear_go_neg(p2p);
2355}
2356
2357
2358void p2p_group_formation_failed(struct p2p_data *p2p)
2359{
2360 if (p2p->go_neg_peer == NULL) {
2361 wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG,
2362 "P2P: No pending Group Formation - "
2363 "ignore group formation failure notification");
2364 return; /* No pending Group Formation */
2365 }
2366
2367 wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG,
2368 "P2P: Group Formation failed with " MACSTR,
2369 MAC2STR(p2p->go_neg_peer->intended_addr));
2370
2371 p2p_clear_go_neg(p2p);
2372}
2373
2374
2375struct p2p_data * p2p_init(const struct p2p_config *cfg)
2376{
2377 struct p2p_data *p2p;
2378
2379 if (cfg->max_peers < 1)
2380 return NULL;
2381
2382 p2p = os_zalloc(sizeof(*p2p) + sizeof(*cfg));
2383 if (p2p == NULL)
2384 return NULL;
2385 p2p->cfg = (struct p2p_config *) (p2p + 1);
2386 os_memcpy(p2p->cfg, cfg, sizeof(*cfg));
2387 if (cfg->dev_name)
2388 p2p->cfg->dev_name = os_strdup(cfg->dev_name);
2389 if (cfg->manufacturer)
2390 p2p->cfg->manufacturer = os_strdup(cfg->manufacturer);
2391 if (cfg->model_name)
2392 p2p->cfg->model_name = os_strdup(cfg->model_name);
2393 if (cfg->model_number)
2394 p2p->cfg->model_number = os_strdup(cfg->model_number);
2395 if (cfg->serial_number)
2396 p2p->cfg->serial_number = os_strdup(cfg->serial_number);
Dmitry Shmidt04949592012-07-19 12:16:46 -07002397 if (cfg->pref_chan) {
2398 p2p->cfg->pref_chan = os_malloc(cfg->num_pref_chan *
2399 sizeof(struct p2p_channel));
2400 if (p2p->cfg->pref_chan) {
2401 os_memcpy(p2p->cfg->pref_chan, cfg->pref_chan,
2402 cfg->num_pref_chan *
2403 sizeof(struct p2p_channel));
2404 } else
2405 p2p->cfg->num_pref_chan = 0;
2406 }
2407
Irfan Sherifff44b9c42012-06-13 11:09:23 -07002408#ifdef ANDROID_P2P
2409 /* 100ms listen time is too less to receive the response frames in some scenarios
2410 * increasing min listen time to 200ms.
2411 */
2412 p2p->min_disc_int = 2;
2413 /* SD_FAIR_POLICY: Initializing the SD current serviced pointer to NULL */
2414 p2p->sd_dev_list = NULL;
2415#else
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07002416 p2p->min_disc_int = 1;
Irfan Sherifff44b9c42012-06-13 11:09:23 -07002417#endif
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07002418 p2p->max_disc_int = 3;
Dmitry Shmidtd5e49232012-12-03 15:08:10 -08002419 p2p->max_disc_tu = -1;
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07002420
2421 os_get_random(&p2p->next_tie_breaker, 1);
2422 p2p->next_tie_breaker &= 0x01;
2423 if (cfg->sd_request)
2424 p2p->dev_capab |= P2P_DEV_CAPAB_SERVICE_DISCOVERY;
2425 p2p->dev_capab |= P2P_DEV_CAPAB_INVITATION_PROCEDURE;
2426 if (cfg->concurrent_operations)
2427 p2p->dev_capab |= P2P_DEV_CAPAB_CONCURRENT_OPER;
2428 p2p->dev_capab |= P2P_DEV_CAPAB_CLIENT_DISCOVERABILITY;
2429
2430 dl_list_init(&p2p->devices);
2431
2432 eloop_register_timeout(P2P_PEER_EXPIRATION_INTERVAL, 0,
2433 p2p_expiration_timeout, p2p, NULL);
2434
Dmitry Shmidt61d9df32012-08-29 16:22:06 -07002435 p2p->go_timeout = 100;
2436 p2p->client_timeout = 20;
2437
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07002438 return p2p;
2439}
2440
2441
2442void p2p_deinit(struct p2p_data *p2p)
2443{
Dmitry Shmidt61d9df32012-08-29 16:22:06 -07002444#ifdef CONFIG_WIFI_DISPLAY
2445 wpabuf_free(p2p->wfd_ie_beacon);
2446 wpabuf_free(p2p->wfd_ie_probe_req);
2447 wpabuf_free(p2p->wfd_ie_probe_resp);
2448 wpabuf_free(p2p->wfd_ie_assoc_req);
2449 wpabuf_free(p2p->wfd_ie_invitation);
2450 wpabuf_free(p2p->wfd_ie_prov_disc_req);
2451 wpabuf_free(p2p->wfd_ie_prov_disc_resp);
2452 wpabuf_free(p2p->wfd_ie_go_neg);
2453 wpabuf_free(p2p->wfd_dev_info);
2454 wpabuf_free(p2p->wfd_assoc_bssid);
2455 wpabuf_free(p2p->wfd_coupled_sink_info);
2456#endif /* CONFIG_WIFI_DISPLAY */
2457
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07002458 eloop_cancel_timeout(p2p_expiration_timeout, p2p, NULL);
2459 eloop_cancel_timeout(p2p_ext_listen_timeout, p2p, NULL);
2460 eloop_cancel_timeout(p2p_scan_timeout, p2p, NULL);
2461 p2p_flush(p2p);
2462 p2p_free_req_dev_types(p2p);
2463 os_free(p2p->cfg->dev_name);
2464 os_free(p2p->cfg->manufacturer);
2465 os_free(p2p->cfg->model_name);
2466 os_free(p2p->cfg->model_number);
2467 os_free(p2p->cfg->serial_number);
Dmitry Shmidt04949592012-07-19 12:16:46 -07002468 os_free(p2p->cfg->pref_chan);
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07002469 os_free(p2p->groups);
2470 wpabuf_free(p2p->sd_resp);
2471 os_free(p2p->after_scan_tx);
2472 p2p_remove_wps_vendor_extensions(p2p);
2473 os_free(p2p);
2474}
2475
2476
2477void p2p_flush(struct p2p_data *p2p)
2478{
2479 struct p2p_device *dev, *prev;
Dmitry Shmidt04949592012-07-19 12:16:46 -07002480 p2p_stop_find(p2p);
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07002481 dl_list_for_each_safe(dev, prev, &p2p->devices, struct p2p_device,
2482 list) {
2483 dl_list_del(&dev->list);
2484 p2p_device_free(p2p, dev);
2485 }
Irfan Sherifff44b9c42012-06-13 11:09:23 -07002486#ifdef ANDROID_P2P
2487 /* SD_FAIR_POLICY: Initializing the SD current serviced pointer to NULL */
2488 p2p->sd_dev_list = NULL;
2489#endif
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07002490 p2p_free_sd_queries(p2p);
2491 os_free(p2p->after_scan_tx);
2492 p2p->after_scan_tx = NULL;
2493}
2494
2495
2496int p2p_unauthorize(struct p2p_data *p2p, const u8 *addr)
2497{
2498 struct p2p_device *dev;
2499
2500 dev = p2p_get_device(p2p, addr);
2501 if (dev == NULL)
2502 return -1;
2503
2504 wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG, "P2P: Unauthorizing " MACSTR,
2505 MAC2STR(addr));
2506
2507 if (p2p->go_neg_peer == dev)
2508 p2p->go_neg_peer = NULL;
2509
2510 dev->wps_method = WPS_NOT_READY;
2511 dev->flags &= ~P2P_DEV_WAIT_GO_NEG_RESPONSE;
2512 dev->flags &= ~P2P_DEV_WAIT_GO_NEG_CONFIRM;
2513
2514 /* Check if after_scan_tx is for this peer. If so free it */
2515 if (p2p->after_scan_tx &&
2516 os_memcmp(addr, p2p->after_scan_tx->dst, ETH_ALEN) == 0) {
2517 os_free(p2p->after_scan_tx);
2518 p2p->after_scan_tx = NULL;
2519 }
2520
2521 return 0;
2522}
2523
2524
2525int p2p_set_dev_name(struct p2p_data *p2p, const char *dev_name)
2526{
2527 os_free(p2p->cfg->dev_name);
2528 if (dev_name) {
2529 p2p->cfg->dev_name = os_strdup(dev_name);
2530 if (p2p->cfg->dev_name == NULL)
2531 return -1;
2532 } else
2533 p2p->cfg->dev_name = NULL;
2534 return 0;
2535}
2536
2537
2538int p2p_set_manufacturer(struct p2p_data *p2p, const char *manufacturer)
2539{
2540 os_free(p2p->cfg->manufacturer);
2541 p2p->cfg->manufacturer = NULL;
2542 if (manufacturer) {
2543 p2p->cfg->manufacturer = os_strdup(manufacturer);
2544 if (p2p->cfg->manufacturer == NULL)
2545 return -1;
2546 }
2547
2548 return 0;
2549}
2550
2551
2552int p2p_set_model_name(struct p2p_data *p2p, const char *model_name)
2553{
2554 os_free(p2p->cfg->model_name);
2555 p2p->cfg->model_name = NULL;
2556 if (model_name) {
2557 p2p->cfg->model_name = os_strdup(model_name);
2558 if (p2p->cfg->model_name == NULL)
2559 return -1;
2560 }
2561
2562 return 0;
2563}
2564
2565
2566int p2p_set_model_number(struct p2p_data *p2p, const char *model_number)
2567{
2568 os_free(p2p->cfg->model_number);
2569 p2p->cfg->model_number = NULL;
2570 if (model_number) {
2571 p2p->cfg->model_number = os_strdup(model_number);
2572 if (p2p->cfg->model_number == NULL)
2573 return -1;
2574 }
2575
2576 return 0;
2577}
2578
2579
2580int p2p_set_serial_number(struct p2p_data *p2p, const char *serial_number)
2581{
2582 os_free(p2p->cfg->serial_number);
2583 p2p->cfg->serial_number = NULL;
2584 if (serial_number) {
2585 p2p->cfg->serial_number = os_strdup(serial_number);
2586 if (p2p->cfg->serial_number == NULL)
2587 return -1;
2588 }
2589
2590 return 0;
2591}
2592
2593
2594void p2p_set_config_methods(struct p2p_data *p2p, u16 config_methods)
2595{
2596 p2p->cfg->config_methods = config_methods;
2597}
2598
2599
2600void p2p_set_uuid(struct p2p_data *p2p, const u8 *uuid)
2601{
2602 os_memcpy(p2p->cfg->uuid, uuid, 16);
2603}
2604
2605
2606int p2p_set_pri_dev_type(struct p2p_data *p2p, const u8 *pri_dev_type)
2607{
2608 os_memcpy(p2p->cfg->pri_dev_type, pri_dev_type, 8);
2609 return 0;
2610}
2611
2612
2613int p2p_set_sec_dev_types(struct p2p_data *p2p, const u8 dev_types[][8],
2614 size_t num_dev_types)
2615{
2616 if (num_dev_types > P2P_SEC_DEVICE_TYPES)
2617 num_dev_types = P2P_SEC_DEVICE_TYPES;
2618 p2p->cfg->num_sec_dev_types = num_dev_types;
2619 os_memcpy(p2p->cfg->sec_dev_type, dev_types, num_dev_types * 8);
2620 return 0;
2621}
2622
2623
2624void p2p_remove_wps_vendor_extensions(struct p2p_data *p2p)
2625{
2626 int i;
2627
2628 for (i = 0; i < P2P_MAX_WPS_VENDOR_EXT; i++) {
2629 wpabuf_free(p2p->wps_vendor_ext[i]);
2630 p2p->wps_vendor_ext[i] = NULL;
2631 }
2632}
2633
2634
2635int p2p_add_wps_vendor_extension(struct p2p_data *p2p,
2636 const struct wpabuf *vendor_ext)
2637{
2638 int i;
2639
2640 if (vendor_ext == NULL)
2641 return -1;
2642
2643 for (i = 0; i < P2P_MAX_WPS_VENDOR_EXT; i++) {
2644 if (p2p->wps_vendor_ext[i] == NULL)
2645 break;
2646 }
2647 if (i >= P2P_MAX_WPS_VENDOR_EXT)
2648 return -1;
2649
2650 p2p->wps_vendor_ext[i] = wpabuf_dup(vendor_ext);
2651 if (p2p->wps_vendor_ext[i] == NULL)
2652 return -1;
2653
2654 return 0;
2655}
2656
2657
2658int p2p_set_country(struct p2p_data *p2p, const char *country)
2659{
2660 os_memcpy(p2p->cfg->country, country, 3);
2661 return 0;
2662}
2663
2664
2665void p2p_continue_find(struct p2p_data *p2p)
2666{
2667 struct p2p_device *dev;
Irfan Sherifff44b9c42012-06-13 11:09:23 -07002668#ifdef ANDROID_P2P
2669 int skip=1;
2670#endif
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07002671 p2p_set_state(p2p, P2P_SEARCH);
2672 dl_list_for_each(dev, &p2p->devices, struct p2p_device, list) {
Irfan Sherifff44b9c42012-06-13 11:09:23 -07002673#ifdef ANDROID_P2P
2674 /* SD_FAIR_POLICY: We need to give chance to all devices in the device list
2675 * There may be a scenario, where a particular peer device have
2676 * not registered any query response. When we send a SD request to such device,
2677 * no response will be received. And if we continue to get probe responses from that device,
2678 * and if that device happens to be on top in our device list,
2679 * we will always continue to send SD requests always to that peer only.
2680 * We will not be able to send SD requests to other devices in that case.
2681 * This implementation keeps track of last serviced peer device.
2682 * And then takes the next one from the device list, in the next iteration.
2683 */
2684 if (p2p->sd_dev_list && p2p->sd_dev_list != &p2p->devices) {
2685 if(skip) {
2686 if ((&dev->list == p2p->sd_dev_list) ) {
2687 skip = 0;
2688 if (dev->list.next == &p2p->devices)
2689 p2p->sd_dev_list = NULL;
2690 }
2691 continue;
2692 }
2693 }
2694 p2p->sd_dev_list = &dev->list;
2695 wpa_printf(MSG_DEBUG, "P2P: ### Servicing %p dev->flags 0x%x SD schedule %s devaddr " MACSTR,
2696 p2p->sd_dev_list, dev->flags, dev->flags & P2P_DEV_SD_SCHEDULE ? "TRUE": "FALSE",
2697 MAC2STR(dev->info.p2p_device_addr));
2698#endif
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07002699 if (dev->flags & P2P_DEV_SD_SCHEDULE) {
2700 if (p2p_start_sd(p2p, dev) == 0)
2701 return;
2702 else
2703 break;
2704 } else if (dev->req_config_methods &&
2705 !(dev->flags & P2P_DEV_PD_FOR_JOIN)) {
2706 wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG, "P2P: Send "
Dmitry Shmidt1f69aa52012-01-24 16:10:04 -08002707 "pending Provision Discovery Request to "
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07002708 MACSTR " (config methods 0x%x)",
2709 MAC2STR(dev->info.p2p_device_addr),
2710 dev->req_config_methods);
Dmitry Shmidt1f69aa52012-01-24 16:10:04 -08002711 if (p2p_send_prov_disc_req(p2p, dev, 0, 0) == 0)
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07002712 return;
2713 }
2714 }
2715
Dmitry Shmidtd5e49232012-12-03 15:08:10 -08002716 p2p_listen_in_find(p2p, 1);
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07002717}
2718
2719
2720static void p2p_sd_cb(struct p2p_data *p2p, int success)
2721{
2722 wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG,
2723 "P2P: Service Discovery Query TX callback: success=%d",
2724 success);
2725 p2p->pending_action_state = P2P_NO_PENDING_ACTION;
2726
2727 if (!success) {
2728 if (p2p->sd_peer) {
2729 p2p->sd_peer->flags &= ~P2P_DEV_SD_SCHEDULE;
2730 p2p->sd_peer = NULL;
2731 }
2732 p2p_continue_find(p2p);
2733 return;
2734 }
2735
2736 if (p2p->sd_peer == NULL) {
2737 wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG,
2738 "P2P: No SD peer entry known");
2739 p2p_continue_find(p2p);
2740 return;
2741 }
2742
2743 /* Wait for response from the peer */
2744 p2p_set_state(p2p, P2P_SD_DURING_FIND);
2745 p2p_set_timeout(p2p, 0, 200000);
2746}
2747
Jouni Malinen75ecf522011-06-27 15:19:46 -07002748
2749/**
2750 * p2p_retry_pd - Retry any pending provision disc requests in IDLE state
2751 * @p2p: P2P module context from p2p_init()
2752 */
Dmitry Shmidt1f69aa52012-01-24 16:10:04 -08002753static void p2p_retry_pd(struct p2p_data *p2p)
Jouni Malinen75ecf522011-06-27 15:19:46 -07002754{
2755 struct p2p_device *dev;
2756
2757 if (p2p->state != P2P_IDLE)
2758 return;
2759
2760 /*
2761 * Retry the prov disc req attempt only for the peer that the user had
Dmitry Shmidtd5e49232012-12-03 15:08:10 -08002762 * requested.
Jouni Malinen75ecf522011-06-27 15:19:46 -07002763 */
2764
2765 dl_list_for_each(dev, &p2p->devices, struct p2p_device, list) {
2766 if (os_memcmp(p2p->pending_pd_devaddr,
2767 dev->info.p2p_device_addr, ETH_ALEN) != 0)
2768 continue;
2769 if (!dev->req_config_methods)
2770 continue;
Jouni Malinen75ecf522011-06-27 15:19:46 -07002771
2772 wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG, "P2P: Send "
Dmitry Shmidt1f69aa52012-01-24 16:10:04 -08002773 "pending Provision Discovery Request to "
Jouni Malinen75ecf522011-06-27 15:19:46 -07002774 MACSTR " (config methods 0x%x)",
2775 MAC2STR(dev->info.p2p_device_addr),
2776 dev->req_config_methods);
Dmitry Shmidtd5e49232012-12-03 15:08:10 -08002777 p2p_send_prov_disc_req(p2p, dev,
2778 dev->flags & P2P_DEV_PD_FOR_JOIN, 0);
Jouni Malinen75ecf522011-06-27 15:19:46 -07002779 return;
2780 }
2781}
2782
2783
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07002784static void p2p_prov_disc_cb(struct p2p_data *p2p, int success)
2785{
2786 wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG,
2787 "P2P: Provision Discovery Request TX callback: success=%d",
2788 success);
Jouni Malinen75ecf522011-06-27 15:19:46 -07002789
2790 /*
2791 * Postpone resetting the pending action state till after we actually
2792 * time out. This allows us to take some action like notifying any
2793 * interested parties about no response to the request.
2794 *
2795 * When the timer (below) goes off we check in IDLE, SEARCH, or
2796 * LISTEN_ONLY state, which are the only allowed states to issue a PD
2797 * requests in, if this was still pending and then raise notification.
2798 */
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07002799
2800 if (!success) {
Jouni Malinen75ecf522011-06-27 15:19:46 -07002801 p2p->pending_action_state = P2P_NO_PENDING_ACTION;
2802
Dmitry Shmidt61d9df32012-08-29 16:22:06 -07002803 if (p2p->user_initiated_pd &&
2804 (p2p->state == P2P_SEARCH || p2p->state == P2P_LISTEN_ONLY))
2805 {
2806 /* Retry request from timeout to avoid busy loops */
2807 p2p->pending_action_state = P2P_PENDING_PD;
2808 p2p_set_timeout(p2p, 0, 50000);
2809 } else if (p2p->state != P2P_IDLE)
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07002810 p2p_continue_find(p2p);
Jouni Malinen75ecf522011-06-27 15:19:46 -07002811 else if (p2p->user_initiated_pd) {
2812 p2p->pending_action_state = P2P_PENDING_PD;
Irfan Sheriff1a2ce112012-10-30 22:22:52 -07002813#ifdef ANDROID_P2P
2814 p2p_set_timeout(p2p, 0, 350000);
2815#else
Jouni Malinen75ecf522011-06-27 15:19:46 -07002816 p2p_set_timeout(p2p, 0, 300000);
Irfan Sheriff1a2ce112012-10-30 22:22:52 -07002817#endif
Jouni Malinen75ecf522011-06-27 15:19:46 -07002818 }
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07002819 return;
2820 }
2821
Jouni Malinen75ecf522011-06-27 15:19:46 -07002822 /*
2823 * This postponing, of resetting pending_action_state, needs to be
2824 * done only for user initiated PD requests and not internal ones.
2825 */
2826 if (p2p->user_initiated_pd)
2827 p2p->pending_action_state = P2P_PENDING_PD;
2828 else
2829 p2p->pending_action_state = P2P_NO_PENDING_ACTION;
2830
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07002831 /* Wait for response from the peer */
2832 if (p2p->state == P2P_SEARCH)
2833 p2p_set_state(p2p, P2P_PD_DURING_FIND);
Irfan Sheriff1a2ce112012-10-30 22:22:52 -07002834#ifdef ANDROID_P2P
2835 p2p_set_timeout(p2p, 0, 350000);
2836#else
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07002837 p2p_set_timeout(p2p, 0, 200000);
Irfan Sheriff1a2ce112012-10-30 22:22:52 -07002838#endif
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07002839}
2840
2841
2842int p2p_scan_res_handler(struct p2p_data *p2p, const u8 *bssid, int freq,
2843 int level, const u8 *ies, size_t ies_len)
2844{
Dmitry Shmidt04949592012-07-19 12:16:46 -07002845 p2p_add_device(p2p, bssid, freq, level, ies, ies_len, 1);
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07002846
2847 return 0;
2848}
2849
2850
2851void p2p_scan_res_handled(struct p2p_data *p2p)
2852{
2853 if (!p2p->p2p_scan_running) {
2854 wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG, "P2P: p2p_scan was not "
2855 "running, but scan results received");
2856 }
2857 p2p->p2p_scan_running = 0;
2858 eloop_cancel_timeout(p2p_scan_timeout, p2p, NULL);
2859
2860 if (p2p_run_after_scan(p2p))
2861 return;
2862 if (p2p->state == P2P_SEARCH)
2863 p2p_continue_find(p2p);
2864}
2865
2866
Dmitry Shmidtc5ec7f52012-03-06 16:33:24 -08002867void p2p_scan_ie(struct p2p_data *p2p, struct wpabuf *ies, const u8 *dev_id)
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07002868{
Dmitry Shmidt61d9df32012-08-29 16:22:06 -07002869 u8 *len;
2870
2871#ifdef CONFIG_WIFI_DISPLAY
2872 if (p2p->wfd_ie_probe_req)
2873 wpabuf_put_buf(ies, p2p->wfd_ie_probe_req);
2874#endif /* CONFIG_WIFI_DISPLAY */
2875
2876 len = p2p_buf_add_ie_hdr(ies);
Dmitry Shmidt04949592012-07-19 12:16:46 -07002877 p2p_buf_add_capability(ies, p2p->dev_capab &
2878 ~P2P_DEV_CAPAB_CLIENT_DISCOVERABILITY, 0);
Dmitry Shmidtc5ec7f52012-03-06 16:33:24 -08002879 if (dev_id)
2880 p2p_buf_add_device_id(ies, dev_id);
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07002881 if (p2p->cfg->reg_class && p2p->cfg->channel)
2882 p2p_buf_add_listen_channel(ies, p2p->cfg->country,
2883 p2p->cfg->reg_class,
2884 p2p->cfg->channel);
2885 if (p2p->ext_listen_interval)
2886 p2p_buf_add_ext_listen_timing(ies, p2p->ext_listen_period,
2887 p2p->ext_listen_interval);
2888 /* TODO: p2p_buf_add_operating_channel() if GO */
2889 p2p_buf_update_ie_hdr(ies, len);
2890}
2891
2892
Dmitry Shmidt1f69aa52012-01-24 16:10:04 -08002893size_t p2p_scan_ie_buf_len(struct p2p_data *p2p)
2894{
Dmitry Shmidt61d9df32012-08-29 16:22:06 -07002895 size_t len = 100;
2896
2897#ifdef CONFIG_WIFI_DISPLAY
2898 if (p2p && p2p->wfd_ie_probe_req)
2899 len += wpabuf_len(p2p->wfd_ie_probe_req);
2900#endif /* CONFIG_WIFI_DISPLAY */
2901
2902 return len;
Dmitry Shmidt1f69aa52012-01-24 16:10:04 -08002903}
2904
2905
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07002906int p2p_ie_text(struct wpabuf *p2p_ie, char *buf, char *end)
2907{
2908 return p2p_attr_text(p2p_ie, buf, end);
2909}
2910
2911
2912static void p2p_go_neg_req_cb(struct p2p_data *p2p, int success)
2913{
2914 struct p2p_device *dev = p2p->go_neg_peer;
2915
2916 wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG,
2917 "P2P: GO Negotiation Request TX callback: success=%d",
2918 success);
2919
2920 if (dev == NULL) {
2921 wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG,
2922 "P2P: No pending GO Negotiation");
2923 return;
2924 }
2925
2926 if (success) {
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07002927 if (dev->flags & P2P_DEV_USER_REJECTED) {
2928 p2p_set_state(p2p, P2P_IDLE);
2929 return;
2930 }
Dmitry Shmidt04949592012-07-19 12:16:46 -07002931 } else if (dev->go_neg_req_sent) {
2932 /* Cancel the increment from p2p_connect_send() on failure */
Dmitry Shmidt98f9e762012-05-30 11:18:46 -07002933 dev->go_neg_req_sent--;
2934 }
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07002935
2936 if (!success &&
2937 (dev->info.dev_capab & P2P_DEV_CAPAB_CLIENT_DISCOVERABILITY) &&
2938 !is_zero_ether_addr(dev->member_in_go_dev)) {
2939 wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG,
2940 "P2P: Peer " MACSTR " did not acknowledge request - "
2941 "try to use device discoverability through its GO",
2942 MAC2STR(dev->info.p2p_device_addr));
2943 p2p->cfg->send_action_done(p2p->cfg->cb_ctx);
2944 p2p_send_dev_disc_req(p2p, dev);
2945 return;
2946 }
2947
2948 /*
2949 * Use P2P find, if needed, to find the other device from its listen
2950 * channel.
2951 */
2952 p2p_set_state(p2p, P2P_CONNECT);
Irfan Sheriff1a2ce112012-10-30 22:22:52 -07002953#ifdef ANDROID_P2P
2954 p2p_set_timeout(p2p, 0, 350000);
2955#else
Dmitry Shmidt61d9df32012-08-29 16:22:06 -07002956 p2p_set_timeout(p2p, 0, success ? 200000 : 100000);
Irfan Sheriff1a2ce112012-10-30 22:22:52 -07002957#endif
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07002958}
2959
2960
2961static void p2p_go_neg_resp_cb(struct p2p_data *p2p, int success)
2962{
2963 wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG,
2964 "P2P: GO Negotiation Response TX callback: success=%d",
2965 success);
2966 if (!p2p->go_neg_peer && p2p->state == P2P_PROVISIONING) {
2967 wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG,
2968 "P2P: Ignore TX callback event - GO Negotiation is "
2969 "not running anymore");
2970 return;
2971 }
2972 p2p_set_state(p2p, P2P_CONNECT);
Irfan Sheriff1a2ce112012-10-30 22:22:52 -07002973#ifdef ANDROID_P2P
2974 p2p_set_timeout(p2p, 0, 350000);
2975#else
Dmitry Shmidt61d9df32012-08-29 16:22:06 -07002976 p2p_set_timeout(p2p, 0, 250000);
Irfan Sheriff1a2ce112012-10-30 22:22:52 -07002977#endif
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07002978}
2979
2980
2981static void p2p_go_neg_resp_failure_cb(struct p2p_data *p2p, int success)
2982{
2983 wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG,
2984 "P2P: GO Negotiation Response (failure) TX callback: "
2985 "success=%d", success);
2986 if (p2p->go_neg_peer && p2p->go_neg_peer->status != P2P_SC_SUCCESS) {
2987 p2p_go_neg_failed(p2p, p2p->go_neg_peer,
2988 p2p->go_neg_peer->status);
2989 }
2990}
2991
2992
2993static void p2p_go_neg_conf_cb(struct p2p_data *p2p,
2994 enum p2p_send_action_result result)
2995{
2996 struct p2p_device *dev;
2997
2998 wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG,
2999 "P2P: GO Negotiation Confirm TX callback: result=%d",
3000 result);
3001 p2p->cfg->send_action_done(p2p->cfg->cb_ctx);
3002 if (result == P2P_SEND_ACTION_FAILED) {
3003 p2p_go_neg_failed(p2p, p2p->go_neg_peer, -1);
3004 return;
3005 }
3006 if (result == P2P_SEND_ACTION_NO_ACK) {
3007 /*
3008 * It looks like the TX status for GO Negotiation Confirm is
3009 * often showing failure even when the peer has actually
3010 * received the frame. Since the peer may change channels
3011 * immediately after having received the frame, we may not see
3012 * an Ack for retries, so just dropping a single frame may
3013 * trigger this. To allow the group formation to succeed if the
3014 * peer did indeed receive the frame, continue regardless of
3015 * the TX status.
3016 */
3017 wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG,
3018 "P2P: Assume GO Negotiation Confirm TX was actually "
3019 "received by the peer even though Ack was not "
3020 "reported");
3021 }
3022
3023 dev = p2p->go_neg_peer;
3024 if (dev == NULL)
3025 return;
3026
3027 p2p_go_complete(p2p, dev);
3028}
3029
3030
3031void p2p_send_action_cb(struct p2p_data *p2p, unsigned int freq, const u8 *dst,
3032 const u8 *src, const u8 *bssid,
3033 enum p2p_send_action_result result)
3034{
3035 enum p2p_pending_action_state state;
3036 int success;
3037
3038 wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG,
3039 "P2P: Action frame TX callback (state=%d freq=%u dst=" MACSTR
3040 " src=" MACSTR " bssid=" MACSTR " result=%d",
3041 p2p->pending_action_state, freq, MAC2STR(dst), MAC2STR(src),
3042 MAC2STR(bssid), result);
3043 success = result == P2P_SEND_ACTION_SUCCESS;
3044 state = p2p->pending_action_state;
3045 p2p->pending_action_state = P2P_NO_PENDING_ACTION;
3046 switch (state) {
3047 case P2P_NO_PENDING_ACTION:
3048 break;
3049 case P2P_PENDING_GO_NEG_REQUEST:
3050 p2p_go_neg_req_cb(p2p, success);
3051 break;
3052 case P2P_PENDING_GO_NEG_RESPONSE:
3053 p2p_go_neg_resp_cb(p2p, success);
3054 break;
3055 case P2P_PENDING_GO_NEG_RESPONSE_FAILURE:
3056 p2p_go_neg_resp_failure_cb(p2p, success);
3057 break;
3058 case P2P_PENDING_GO_NEG_CONFIRM:
3059 p2p_go_neg_conf_cb(p2p, result);
3060 break;
3061 case P2P_PENDING_SD:
3062 p2p_sd_cb(p2p, success);
3063 break;
3064 case P2P_PENDING_PD:
3065 p2p_prov_disc_cb(p2p, success);
3066 break;
3067 case P2P_PENDING_INVITATION_REQUEST:
3068 p2p_invitation_req_cb(p2p, success);
3069 break;
3070 case P2P_PENDING_INVITATION_RESPONSE:
3071 p2p_invitation_resp_cb(p2p, success);
3072 break;
3073 case P2P_PENDING_DEV_DISC_REQUEST:
3074 p2p_dev_disc_req_cb(p2p, success);
3075 break;
3076 case P2P_PENDING_DEV_DISC_RESPONSE:
3077 p2p_dev_disc_resp_cb(p2p, success);
3078 break;
3079 case P2P_PENDING_GO_DISC_REQ:
3080 p2p_go_disc_req_cb(p2p, success);
3081 break;
3082 }
3083}
3084
3085
3086void p2p_listen_cb(struct p2p_data *p2p, unsigned int freq,
3087 unsigned int duration)
3088{
3089 if (freq == p2p->pending_client_disc_freq) {
3090 wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG,
3091 "P2P: Client discoverability remain-awake completed");
3092 p2p->pending_client_disc_freq = 0;
3093 return;
3094 }
3095
3096 if (freq != p2p->pending_listen_freq) {
3097 wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG,
3098 "P2P: Unexpected listen callback for freq=%u "
3099 "duration=%u (pending_listen_freq=%u)",
3100 freq, duration, p2p->pending_listen_freq);
3101 return;
3102 }
3103
3104 wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG,
3105 "P2P: Starting Listen timeout(%u,%u) on freq=%u based on "
3106 "callback",
3107 p2p->pending_listen_sec, p2p->pending_listen_usec,
3108 p2p->pending_listen_freq);
3109 p2p->in_listen = 1;
3110 p2p->drv_in_listen = freq;
3111 if (p2p->pending_listen_sec || p2p->pending_listen_usec) {
3112 /*
3113 * Add 20 msec extra wait to avoid race condition with driver
3114 * remain-on-channel end event, i.e., give driver more time to
3115 * complete the operation before our timeout expires.
3116 */
3117 p2p_set_timeout(p2p, p2p->pending_listen_sec,
3118 p2p->pending_listen_usec + 20000);
3119 }
3120
3121 p2p->pending_listen_freq = 0;
3122}
3123
3124
3125int p2p_listen_end(struct p2p_data *p2p, unsigned int freq)
3126{
3127 wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG, "P2P: Driver ended Listen "
3128 "state (freq=%u)", freq);
3129 p2p->drv_in_listen = 0;
3130 if (p2p->in_listen)
3131 return 0; /* Internal timeout will trigger the next step */
3132
3133 if (p2p->state == P2P_CONNECT_LISTEN && p2p->go_neg_peer) {
3134 if (p2p->go_neg_peer->connect_reqs >= 120) {
3135 wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG,
3136 "P2P: Timeout on sending GO Negotiation "
3137 "Request without getting response");
3138 p2p_go_neg_failed(p2p, p2p->go_neg_peer, -1);
3139 return 0;
3140 }
3141
3142 p2p_set_state(p2p, P2P_CONNECT);
3143 p2p_connect_send(p2p, p2p->go_neg_peer);
3144 return 1;
3145 } else if (p2p->state == P2P_SEARCH) {
Dmitry Shmidtc5ec7f52012-03-06 16:33:24 -08003146 if (p2p->p2p_scan_running) {
3147 /*
3148 * Search is already in progress. This can happen if
3149 * an Action frame RX is reported immediately after
3150 * the end of a remain-on-channel operation and the
3151 * response frame to that is sent using an offchannel
3152 * operation while in p2p_find. Avoid an attempt to
3153 * restart a scan here.
3154 */
3155 wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG, "P2P: p2p_scan "
3156 "already in progress - do not try to start a "
3157 "new one");
3158 return 1;
3159 }
Dmitry Shmidt04949592012-07-19 12:16:46 -07003160 if (p2p->pending_listen_freq) {
3161 /*
3162 * Better wait a bit if the driver is unable to start
3163 * offchannel operation for some reason. p2p_search()
3164 * will be started from internal timeout.
3165 */
3166 wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG, "P2P: Listen "
3167 "operation did not seem to start - delay "
3168 "search phase to avoid busy loop");
3169 p2p_set_timeout(p2p, 0, 100000);
3170 return 1;
3171 }
Dmitry Shmidt61d9df32012-08-29 16:22:06 -07003172 if (p2p->search_delay) {
3173 wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG, "P2P: Delay "
3174 "search operation by %u ms",
3175 p2p->search_delay);
3176 p2p_set_timeout(p2p, p2p->search_delay / 1000,
3177 (p2p->search_delay % 1000) * 1000);
3178 return 1;
3179 }
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07003180 p2p_search(p2p);
3181 return 1;
3182 }
3183
3184 return 0;
3185}
3186
3187
3188static void p2p_timeout_connect(struct p2p_data *p2p)
3189{
3190 p2p->cfg->send_action_done(p2p->cfg->cb_ctx);
Dmitry Shmidt04949592012-07-19 12:16:46 -07003191 if (p2p->go_neg_peer &&
3192 (p2p->go_neg_peer->flags & P2P_DEV_WAIT_GO_NEG_CONFIRM)) {
3193 wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG, "P2P: Wait for GO "
3194 "Negotiation Confirm timed out - assume GO "
3195 "Negotiation failed");
3196 p2p_go_neg_failed(p2p, p2p->go_neg_peer, -1);
3197 return;
3198 }
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07003199 p2p_set_state(p2p, P2P_CONNECT_LISTEN);
Dmitry Shmidtd5e49232012-12-03 15:08:10 -08003200 p2p_listen_in_find(p2p, 0);
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07003201}
3202
3203
3204static void p2p_timeout_connect_listen(struct p2p_data *p2p)
3205{
3206 if (p2p->go_neg_peer) {
3207 if (p2p->drv_in_listen) {
3208 wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG, "P2P: Driver is "
3209 "still in Listen state; wait for it to "
3210 "complete");
3211 return;
3212 }
3213
3214 if (p2p->go_neg_peer->connect_reqs >= 120) {
3215 wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG,
3216 "P2P: Timeout on sending GO Negotiation "
3217 "Request without getting response");
3218 p2p_go_neg_failed(p2p, p2p->go_neg_peer, -1);
3219 return;
3220 }
3221
3222 p2p_set_state(p2p, P2P_CONNECT);
3223 p2p_connect_send(p2p, p2p->go_neg_peer);
3224 } else
3225 p2p_set_state(p2p, P2P_IDLE);
3226}
3227
3228
3229static void p2p_timeout_wait_peer_connect(struct p2p_data *p2p)
3230{
3231 /*
3232 * TODO: could remain constantly in Listen state for some time if there
3233 * are no other concurrent uses for the radio. For now, go to listen
3234 * state once per second to give other uses a chance to use the radio.
3235 */
3236 p2p_set_state(p2p, P2P_WAIT_PEER_IDLE);
Dmitry Shmidt1f69aa52012-01-24 16:10:04 -08003237 p2p_set_timeout(p2p, 0, 500000);
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07003238}
3239
3240
3241static void p2p_timeout_wait_peer_idle(struct p2p_data *p2p)
3242{
3243 struct p2p_device *dev = p2p->go_neg_peer;
3244
3245 if (dev == NULL) {
3246 wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG,
3247 "P2P: Unknown GO Neg peer - stop GO Neg wait");
3248 return;
3249 }
3250
3251 dev->wait_count++;
3252 if (dev->wait_count >= 120) {
3253 wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG,
3254 "P2P: Timeout on waiting peer to become ready for GO "
3255 "Negotiation");
3256 p2p_go_neg_failed(p2p, dev, -1);
3257 return;
3258 }
3259
3260 wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG,
3261 "P2P: Go to Listen state while waiting for the peer to become "
3262 "ready for GO Negotiation");
3263 p2p_set_state(p2p, P2P_WAIT_PEER_CONNECT);
Dmitry Shmidtd5e49232012-12-03 15:08:10 -08003264 p2p_listen_in_find(p2p, 0);
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07003265}
3266
3267
3268static void p2p_timeout_sd_during_find(struct p2p_data *p2p)
3269{
3270 wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG,
3271 "P2P: Service Discovery Query timeout");
3272 if (p2p->sd_peer) {
3273 p2p->cfg->send_action_done(p2p->cfg->cb_ctx);
3274 p2p->sd_peer->flags &= ~P2P_DEV_SD_SCHEDULE;
3275 p2p->sd_peer = NULL;
3276 }
3277 p2p_continue_find(p2p);
3278}
3279
3280
3281static void p2p_timeout_prov_disc_during_find(struct p2p_data *p2p)
3282{
3283 wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG,
3284 "P2P: Provision Discovery Request timeout");
3285 p2p->cfg->send_action_done(p2p->cfg->cb_ctx);
3286 p2p_continue_find(p2p);
3287}
3288
3289
Jouni Malinen75ecf522011-06-27 15:19:46 -07003290static void p2p_timeout_prov_disc_req(struct p2p_data *p2p)
3291{
3292 p2p->pending_action_state = P2P_NO_PENDING_ACTION;
3293
3294 /*
3295 * For user initiated PD requests that we have not gotten any responses
3296 * for while in IDLE state, we retry them a couple of times before
3297 * giving up.
3298 */
3299 if (!p2p->user_initiated_pd)
3300 return;
3301
3302 wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG,
3303 "P2P: User initiated Provision Discovery Request timeout");
3304
3305 if (p2p->pd_retries) {
3306 p2p->pd_retries--;
3307 p2p_retry_pd(p2p);
3308 } else {
Dmitry Shmidtd5e49232012-12-03 15:08:10 -08003309 struct p2p_device *dev;
3310 int for_join = 0;
3311
3312 dl_list_for_each(dev, &p2p->devices, struct p2p_device, list) {
3313 if (os_memcmp(p2p->pending_pd_devaddr,
3314 dev->info.p2p_device_addr, ETH_ALEN) != 0)
3315 continue;
3316 if (dev->req_config_methods &&
3317 (dev->flags & P2P_DEV_PD_FOR_JOIN))
3318 for_join = 1;
3319 }
3320
Jouni Malinen75ecf522011-06-27 15:19:46 -07003321 if (p2p->cfg->prov_disc_fail)
3322 p2p->cfg->prov_disc_fail(p2p->cfg->cb_ctx,
3323 p2p->pending_pd_devaddr,
Dmitry Shmidtd5e49232012-12-03 15:08:10 -08003324 for_join ?
3325 P2P_PROV_DISC_TIMEOUT_JOIN :
Jouni Malinen75ecf522011-06-27 15:19:46 -07003326 P2P_PROV_DISC_TIMEOUT);
3327 p2p_reset_pending_pd(p2p);
3328 }
3329}
3330
3331
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07003332static void p2p_timeout_invite(struct p2p_data *p2p)
3333{
3334 p2p->cfg->send_action_done(p2p->cfg->cb_ctx);
3335 p2p_set_state(p2p, P2P_INVITE_LISTEN);
3336 if (p2p->inv_role == P2P_INVITE_ROLE_ACTIVE_GO) {
3337 /*
3338 * Better remain on operating channel instead of listen channel
3339 * when running a group.
3340 */
3341 wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG, "P2P: Inviting in "
3342 "active GO role - wait on operating channel");
3343 p2p_set_timeout(p2p, 0, 100000);
3344 return;
3345 }
Dmitry Shmidtd5e49232012-12-03 15:08:10 -08003346 p2p_listen_in_find(p2p, 0);
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07003347}
3348
3349
3350static void p2p_timeout_invite_listen(struct p2p_data *p2p)
3351{
3352 if (p2p->invite_peer && p2p->invite_peer->invitation_reqs < 100) {
3353 p2p_set_state(p2p, P2P_INVITE);
3354 p2p_invite_send(p2p, p2p->invite_peer,
3355 p2p->invite_go_dev_addr);
3356 } else {
3357 if (p2p->invite_peer) {
3358 wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG,
3359 "P2P: Invitation Request retry limit reached");
3360 if (p2p->cfg->invitation_result)
3361 p2p->cfg->invitation_result(
3362 p2p->cfg->cb_ctx, -1, NULL);
3363 }
3364 p2p_set_state(p2p, P2P_IDLE);
3365 }
3366}
3367
3368
3369static void p2p_state_timeout(void *eloop_ctx, void *timeout_ctx)
3370{
3371 struct p2p_data *p2p = eloop_ctx;
3372
3373 wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG, "P2P: Timeout (state=%s)",
3374 p2p_state_txt(p2p->state));
3375
3376 p2p->in_listen = 0;
3377
3378 switch (p2p->state) {
3379 case P2P_IDLE:
Jouni Malinen75ecf522011-06-27 15:19:46 -07003380 /* Check if we timed out waiting for PD req */
3381 if (p2p->pending_action_state == P2P_PENDING_PD)
3382 p2p_timeout_prov_disc_req(p2p);
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07003383 break;
3384 case P2P_SEARCH:
Jouni Malinen75ecf522011-06-27 15:19:46 -07003385 /* Check if we timed out waiting for PD req */
3386 if (p2p->pending_action_state == P2P_PENDING_PD)
3387 p2p_timeout_prov_disc_req(p2p);
Dmitry Shmidt61d9df32012-08-29 16:22:06 -07003388 if (p2p->search_delay && !p2p->in_search_delay) {
3389 wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG, "P2P: Delay "
3390 "search operation by %u ms",
3391 p2p->search_delay);
3392 p2p->in_search_delay = 1;
3393 p2p_set_timeout(p2p, p2p->search_delay / 1000,
3394 (p2p->search_delay % 1000) * 1000);
3395 break;
3396 }
3397 p2p->in_search_delay = 0;
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07003398 p2p_search(p2p);
3399 break;
3400 case P2P_CONNECT:
3401 p2p_timeout_connect(p2p);
3402 break;
3403 case P2P_CONNECT_LISTEN:
3404 p2p_timeout_connect_listen(p2p);
3405 break;
3406 case P2P_GO_NEG:
3407 break;
3408 case P2P_LISTEN_ONLY:
Jouni Malinen75ecf522011-06-27 15:19:46 -07003409 /* Check if we timed out waiting for PD req */
3410 if (p2p->pending_action_state == P2P_PENDING_PD)
3411 p2p_timeout_prov_disc_req(p2p);
3412
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07003413 if (p2p->ext_listen_only) {
3414 wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG,
3415 "P2P: Extended Listen Timing - Listen State "
3416 "completed");
3417 p2p->ext_listen_only = 0;
3418 p2p_set_state(p2p, P2P_IDLE);
3419 }
3420 break;
3421 case P2P_WAIT_PEER_CONNECT:
3422 p2p_timeout_wait_peer_connect(p2p);
3423 break;
3424 case P2P_WAIT_PEER_IDLE:
3425 p2p_timeout_wait_peer_idle(p2p);
3426 break;
3427 case P2P_SD_DURING_FIND:
3428 p2p_timeout_sd_during_find(p2p);
3429 break;
3430 case P2P_PROVISIONING:
3431 break;
3432 case P2P_PD_DURING_FIND:
3433 p2p_timeout_prov_disc_during_find(p2p);
3434 break;
3435 case P2P_INVITE:
3436 p2p_timeout_invite(p2p);
3437 break;
3438 case P2P_INVITE_LISTEN:
3439 p2p_timeout_invite_listen(p2p);
3440 break;
Dmitry Shmidt1f69aa52012-01-24 16:10:04 -08003441 case P2P_SEARCH_WHEN_READY:
3442 break;
Dmitry Shmidt61d9df32012-08-29 16:22:06 -07003443 case P2P_CONTINUE_SEARCH_WHEN_READY:
3444 break;
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07003445 }
3446}
3447
3448
3449int p2p_reject(struct p2p_data *p2p, const u8 *peer_addr)
3450{
3451 struct p2p_device *dev;
3452
3453 dev = p2p_get_device(p2p, peer_addr);
3454 wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG, "P2P: Local request to reject "
3455 "connection attempts by peer " MACSTR, MAC2STR(peer_addr));
3456 if (dev == NULL) {
3457 wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG, "P2P: Peer " MACSTR
3458 " unknown", MAC2STR(peer_addr));
3459 return -1;
3460 }
3461 dev->status = P2P_SC_FAIL_REJECTED_BY_USER;
3462 dev->flags |= P2P_DEV_USER_REJECTED;
3463 return 0;
3464}
3465
3466
Dmitry Shmidt1f69aa52012-01-24 16:10:04 -08003467const char * p2p_wps_method_text(enum p2p_wps_method method)
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07003468{
3469 switch (method) {
3470 case WPS_NOT_READY:
3471 return "not-ready";
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07003472 case WPS_PIN_DISPLAY:
3473 return "Display";
3474 case WPS_PIN_KEYPAD:
3475 return "Keypad";
3476 case WPS_PBC:
3477 return "PBC";
3478 }
3479
3480 return "??";
3481}
3482
3483
3484static const char * p2p_go_state_text(enum p2p_go_state go_state)
3485{
3486 switch (go_state) {
3487 case UNKNOWN_GO:
3488 return "unknown";
3489 case LOCAL_GO:
3490 return "local";
3491 case REMOTE_GO:
3492 return "remote";
3493 }
3494
3495 return "??";
3496}
3497
3498
Dmitry Shmidt1f69aa52012-01-24 16:10:04 -08003499const struct p2p_peer_info * p2p_get_peer_info(struct p2p_data *p2p,
3500 const u8 *addr, int next)
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07003501{
3502 struct p2p_device *dev;
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07003503
3504 if (addr)
3505 dev = p2p_get_device(p2p, addr);
3506 else
3507 dev = dl_list_first(&p2p->devices, struct p2p_device, list);
3508
3509 if (dev && next) {
3510 dev = dl_list_first(&dev->list, struct p2p_device, list);
3511 if (&dev->list == &p2p->devices)
3512 dev = NULL;
3513 }
3514
3515 if (dev == NULL)
Dmitry Shmidt1f69aa52012-01-24 16:10:04 -08003516 return NULL;
3517
3518 return &dev->info;
3519}
3520
3521
3522int p2p_get_peer_info_txt(const struct p2p_peer_info *info,
3523 char *buf, size_t buflen)
3524{
3525 struct p2p_device *dev;
3526 int res;
3527 char *pos, *end;
3528 struct os_time now;
3529
3530 if (info == NULL)
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07003531 return -1;
3532
Dmitry Shmidt1f69aa52012-01-24 16:10:04 -08003533 dev = (struct p2p_device *) (((u8 *) info) -
3534 offsetof(struct p2p_device, info));
3535
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07003536 pos = buf;
3537 end = buf + buflen;
3538
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07003539 os_get_time(&now);
3540 res = os_snprintf(pos, end - pos,
3541 "age=%d\n"
3542 "listen_freq=%d\n"
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07003543 "wps_method=%s\n"
3544 "interface_addr=" MACSTR "\n"
3545 "member_in_go_dev=" MACSTR "\n"
3546 "member_in_go_iface=" MACSTR "\n"
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07003547 "go_neg_req_sent=%d\n"
3548 "go_state=%s\n"
3549 "dialog_token=%u\n"
3550 "intended_addr=" MACSTR "\n"
3551 "country=%c%c\n"
3552 "oper_freq=%d\n"
3553 "req_config_methods=0x%x\n"
3554 "flags=%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s\n"
3555 "status=%d\n"
3556 "wait_count=%u\n"
3557 "invitation_reqs=%u\n",
3558 (int) (now.sec - dev->last_seen.sec),
3559 dev->listen_freq,
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07003560 p2p_wps_method_text(dev->wps_method),
3561 MAC2STR(dev->interface_addr),
3562 MAC2STR(dev->member_in_go_dev),
3563 MAC2STR(dev->member_in_go_iface),
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07003564 dev->go_neg_req_sent,
3565 p2p_go_state_text(dev->go_state),
3566 dev->dialog_token,
3567 MAC2STR(dev->intended_addr),
3568 dev->country[0] ? dev->country[0] : '_',
3569 dev->country[1] ? dev->country[1] : '_',
3570 dev->oper_freq,
3571 dev->req_config_methods,
3572 dev->flags & P2P_DEV_PROBE_REQ_ONLY ?
3573 "[PROBE_REQ_ONLY]" : "",
3574 dev->flags & P2P_DEV_REPORTED ? "[REPORTED]" : "",
3575 dev->flags & P2P_DEV_NOT_YET_READY ?
3576 "[NOT_YET_READY]" : "",
3577 dev->flags & P2P_DEV_SD_INFO ? "[SD_INFO]" : "",
3578 dev->flags & P2P_DEV_SD_SCHEDULE ? "[SD_SCHEDULE]" :
3579 "",
3580 dev->flags & P2P_DEV_PD_PEER_DISPLAY ?
3581 "[PD_PEER_DISPLAY]" : "",
3582 dev->flags & P2P_DEV_PD_PEER_KEYPAD ?
3583 "[PD_PEER_KEYPAD]" : "",
3584 dev->flags & P2P_DEV_USER_REJECTED ?
3585 "[USER_REJECTED]" : "",
3586 dev->flags & P2P_DEV_PEER_WAITING_RESPONSE ?
3587 "[PEER_WAITING_RESPONSE]" : "",
3588 dev->flags & P2P_DEV_PREFER_PERSISTENT_GROUP ?
3589 "[PREFER_PERSISTENT_GROUP]" : "",
3590 dev->flags & P2P_DEV_WAIT_GO_NEG_RESPONSE ?
3591 "[WAIT_GO_NEG_RESPONSE]" : "",
3592 dev->flags & P2P_DEV_WAIT_GO_NEG_CONFIRM ?
3593 "[WAIT_GO_NEG_CONFIRM]" : "",
3594 dev->flags & P2P_DEV_GROUP_CLIENT_ONLY ?
3595 "[GROUP_CLIENT_ONLY]" : "",
3596 dev->flags & P2P_DEV_FORCE_FREQ ?
3597 "[FORCE_FREQ]" : "",
3598 dev->flags & P2P_DEV_PD_FOR_JOIN ?
3599 "[PD_FOR_JOIN]" : "",
3600 dev->status,
3601 dev->wait_count,
3602 dev->invitation_reqs);
3603 if (res < 0 || res >= end - pos)
3604 return pos - buf;
3605 pos += res;
3606
3607 if (dev->ext_listen_period) {
3608 res = os_snprintf(pos, end - pos,
3609 "ext_listen_period=%u\n"
3610 "ext_listen_interval=%u\n",
3611 dev->ext_listen_period,
3612 dev->ext_listen_interval);
3613 if (res < 0 || res >= end - pos)
3614 return pos - buf;
3615 pos += res;
3616 }
3617
3618 if (dev->oper_ssid_len) {
3619 res = os_snprintf(pos, end - pos,
3620 "oper_ssid=%s\n",
3621 wpa_ssid_txt(dev->oper_ssid,
3622 dev->oper_ssid_len));
3623 if (res < 0 || res >= end - pos)
3624 return pos - buf;
3625 pos += res;
3626 }
3627
Dmitry Shmidt61d9df32012-08-29 16:22:06 -07003628#ifdef CONFIG_WIFI_DISPLAY
3629 if (dev->info.wfd_subelems) {
3630 res = os_snprintf(pos, end - pos, "wfd_subelems=");
3631 if (res < 0 || res >= end - pos)
3632 return pos - buf;
3633 pos += res;
3634
3635 pos += wpa_snprintf_hex(pos, end - pos,
3636 wpabuf_head(dev->info.wfd_subelems),
3637 wpabuf_len(dev->info.wfd_subelems));
3638
3639 res = os_snprintf(pos, end - pos, "\n");
3640 if (res < 0 || res >= end - pos)
3641 return pos - buf;
3642 pos += res;
3643 }
3644#endif /* CONFIG_WIFI_DISPLAY */
3645
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07003646 return pos - buf;
3647}
3648
3649
Dmitry Shmidt1f69aa52012-01-24 16:10:04 -08003650int p2p_peer_known(struct p2p_data *p2p, const u8 *addr)
3651{
3652 return p2p_get_device(p2p, addr) != NULL;
3653}
3654
3655
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07003656void p2p_set_client_discoverability(struct p2p_data *p2p, int enabled)
3657{
3658 if (enabled) {
3659 wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG, "P2P: Client "
3660 "discoverability enabled");
3661 p2p->dev_capab |= P2P_DEV_CAPAB_CLIENT_DISCOVERABILITY;
3662 } else {
3663 wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG, "P2P: Client "
3664 "discoverability disabled");
3665 p2p->dev_capab &= ~P2P_DEV_CAPAB_CLIENT_DISCOVERABILITY;
3666 }
3667}
3668
3669
3670static struct wpabuf * p2p_build_presence_req(u32 duration1, u32 interval1,
3671 u32 duration2, u32 interval2)
3672{
3673 struct wpabuf *req;
3674 struct p2p_noa_desc desc1, desc2, *ptr1 = NULL, *ptr2 = NULL;
3675 u8 *len;
3676
3677 req = wpabuf_alloc(100);
3678 if (req == NULL)
3679 return NULL;
3680
3681 if (duration1 || interval1) {
3682 os_memset(&desc1, 0, sizeof(desc1));
3683 desc1.count_type = 1;
3684 desc1.duration = duration1;
3685 desc1.interval = interval1;
3686 ptr1 = &desc1;
3687
3688 if (duration2 || interval2) {
3689 os_memset(&desc2, 0, sizeof(desc2));
3690 desc2.count_type = 2;
3691 desc2.duration = duration2;
3692 desc2.interval = interval2;
3693 ptr2 = &desc2;
3694 }
3695 }
3696
3697 p2p_buf_add_action_hdr(req, P2P_PRESENCE_REQ, 1);
3698 len = p2p_buf_add_ie_hdr(req);
3699 p2p_buf_add_noa(req, 0, 0, 0, ptr1, ptr2);
3700 p2p_buf_update_ie_hdr(req, len);
3701
3702 return req;
3703}
3704
3705
3706int p2p_presence_req(struct p2p_data *p2p, const u8 *go_interface_addr,
3707 const u8 *own_interface_addr, unsigned int freq,
3708 u32 duration1, u32 interval1, u32 duration2,
3709 u32 interval2)
3710{
3711 struct wpabuf *req;
3712
3713 wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG, "P2P: Send Presence Request to "
3714 "GO " MACSTR " (own interface " MACSTR ") freq=%u dur1=%u "
3715 "int1=%u dur2=%u int2=%u",
3716 MAC2STR(go_interface_addr), MAC2STR(own_interface_addr),
3717 freq, duration1, interval1, duration2, interval2);
3718
3719 req = p2p_build_presence_req(duration1, interval1, duration2,
3720 interval2);
3721 if (req == NULL)
3722 return -1;
3723
3724 p2p->pending_action_state = P2P_NO_PENDING_ACTION;
3725 if (p2p_send_action(p2p, freq, go_interface_addr, own_interface_addr,
3726 go_interface_addr,
3727 wpabuf_head(req), wpabuf_len(req), 200) < 0) {
3728 wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG,
3729 "P2P: Failed to send Action frame");
3730 }
3731 wpabuf_free(req);
3732
3733 return 0;
3734}
3735
3736
3737static struct wpabuf * p2p_build_presence_resp(u8 status, const u8 *noa,
3738 size_t noa_len, u8 dialog_token)
3739{
3740 struct wpabuf *resp;
3741 u8 *len;
3742
3743 resp = wpabuf_alloc(100 + noa_len);
3744 if (resp == NULL)
3745 return NULL;
3746
3747 p2p_buf_add_action_hdr(resp, P2P_PRESENCE_RESP, dialog_token);
3748 len = p2p_buf_add_ie_hdr(resp);
3749 p2p_buf_add_status(resp, status);
3750 if (noa) {
3751 wpabuf_put_u8(resp, P2P_ATTR_NOTICE_OF_ABSENCE);
3752 wpabuf_put_le16(resp, noa_len);
3753 wpabuf_put_data(resp, noa, noa_len);
3754 } else
3755 p2p_buf_add_noa(resp, 0, 0, 0, NULL, NULL);
3756 p2p_buf_update_ie_hdr(resp, len);
3757
3758 return resp;
3759}
3760
3761
3762static void p2p_process_presence_req(struct p2p_data *p2p, const u8 *da,
3763 const u8 *sa, const u8 *data, size_t len,
3764 int rx_freq)
3765{
3766 struct p2p_message msg;
3767 u8 status;
3768 struct wpabuf *resp;
3769 size_t g;
3770 struct p2p_group *group = NULL;
3771 int parsed = 0;
3772 u8 noa[50];
3773 int noa_len;
3774
3775 wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG,
3776 "P2P: Received P2P Action - P2P Presence Request");
3777
3778 for (g = 0; g < p2p->num_groups; g++) {
3779 if (os_memcmp(da, p2p_group_get_interface_addr(p2p->groups[g]),
3780 ETH_ALEN) == 0) {
3781 group = p2p->groups[g];
3782 break;
3783 }
3784 }
3785 if (group == NULL) {
3786 wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG,
3787 "P2P: Ignore P2P Presence Request for unknown group "
3788 MACSTR, MAC2STR(da));
3789 return;
3790 }
3791
3792 if (p2p_parse(data, len, &msg) < 0) {
3793 wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG,
3794 "P2P: Failed to parse P2P Presence Request");
3795 status = P2P_SC_FAIL_INVALID_PARAMS;
3796 goto fail;
3797 }
3798 parsed = 1;
3799
3800 if (msg.noa == NULL) {
3801 wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG,
3802 "P2P: No NoA attribute in P2P Presence Request");
3803 status = P2P_SC_FAIL_INVALID_PARAMS;
3804 goto fail;
3805 }
3806
3807 status = p2p_group_presence_req(group, sa, msg.noa, msg.noa_len);
3808
3809fail:
3810 if (p2p->cfg->get_noa)
3811 noa_len = p2p->cfg->get_noa(p2p->cfg->cb_ctx, da, noa,
3812 sizeof(noa));
3813 else
3814 noa_len = -1;
3815 resp = p2p_build_presence_resp(status, noa_len > 0 ? noa : NULL,
3816 noa_len > 0 ? noa_len : 0,
3817 msg.dialog_token);
3818 if (parsed)
3819 p2p_parse_free(&msg);
3820 if (resp == NULL)
3821 return;
3822
3823 p2p->pending_action_state = P2P_NO_PENDING_ACTION;
3824 if (p2p_send_action(p2p, rx_freq, sa, da, da,
3825 wpabuf_head(resp), wpabuf_len(resp), 200) < 0) {
3826 wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG,
3827 "P2P: Failed to send Action frame");
3828 }
3829 wpabuf_free(resp);
3830}
3831
3832
3833static void p2p_process_presence_resp(struct p2p_data *p2p, const u8 *da,
3834 const u8 *sa, const u8 *data, size_t len)
3835{
3836 struct p2p_message msg;
3837
3838 wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG,
3839 "P2P: Received P2P Action - P2P Presence Response");
3840
3841 if (p2p_parse(data, len, &msg) < 0) {
3842 wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG,
3843 "P2P: Failed to parse P2P Presence Response");
3844 return;
3845 }
3846
3847 if (msg.status == NULL || msg.noa == NULL) {
3848 wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG,
3849 "P2P: No Status or NoA attribute in P2P Presence "
3850 "Response");
3851 p2p_parse_free(&msg);
3852 return;
3853 }
3854
3855 if (*msg.status) {
3856 wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG,
3857 "P2P: P2P Presence Request was rejected: status %u",
3858 *msg.status);
3859 p2p_parse_free(&msg);
3860 return;
3861 }
3862
3863 wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG,
3864 "P2P: P2P Presence Request was accepted");
3865 wpa_hexdump(MSG_DEBUG, "P2P: P2P Presence Response - NoA",
3866 msg.noa, msg.noa_len);
3867 /* TODO: process NoA */
3868 p2p_parse_free(&msg);
3869}
3870
3871
3872static void p2p_ext_listen_timeout(void *eloop_ctx, void *timeout_ctx)
3873{
3874 struct p2p_data *p2p = eloop_ctx;
3875
3876 if (p2p->ext_listen_interval) {
3877 /* Schedule next extended listen timeout */
3878 eloop_register_timeout(p2p->ext_listen_interval_sec,
3879 p2p->ext_listen_interval_usec,
3880 p2p_ext_listen_timeout, p2p, NULL);
3881 }
3882
3883 if (p2p->state == P2P_LISTEN_ONLY && p2p->ext_listen_only) {
3884 /*
3885 * This should not really happen, but it looks like the Listen
3886 * command may fail is something else (e.g., a scan) was
3887 * running at an inconvenient time. As a workaround, allow new
3888 * Extended Listen operation to be started.
3889 */
3890 wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG, "P2P: Previous "
3891 "Extended Listen operation had not been completed - "
3892 "try again");
3893 p2p->ext_listen_only = 0;
3894 p2p_set_state(p2p, P2P_IDLE);
3895 }
3896
3897 if (p2p->state != P2P_IDLE) {
3898 wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG, "P2P: Skip Extended "
3899 "Listen timeout in active state (%s)",
3900 p2p_state_txt(p2p->state));
3901 return;
3902 }
3903
3904 wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG, "P2P: Extended Listen timeout");
3905 p2p->ext_listen_only = 1;
3906 if (p2p_listen(p2p, p2p->ext_listen_period) < 0) {
3907 wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG, "P2P: Failed to start "
3908 "Listen state for Extended Listen Timing");
3909 p2p->ext_listen_only = 0;
3910 }
3911}
3912
3913
3914int p2p_ext_listen(struct p2p_data *p2p, unsigned int period,
3915 unsigned int interval)
3916{
3917 if (period > 65535 || interval > 65535 || period > interval ||
3918 (period == 0 && interval > 0) || (period > 0 && interval == 0)) {
3919 wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG,
3920 "P2P: Invalid Extended Listen Timing request: "
3921 "period=%u interval=%u", period, interval);
3922 return -1;
3923 }
3924
3925 eloop_cancel_timeout(p2p_ext_listen_timeout, p2p, NULL);
3926
3927 if (interval == 0) {
3928 wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG,
3929 "P2P: Disabling Extended Listen Timing");
3930 p2p->ext_listen_period = 0;
3931 p2p->ext_listen_interval = 0;
3932 return 0;
3933 }
3934
3935 wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG,
3936 "P2P: Enabling Extended Listen Timing: period %u msec, "
3937 "interval %u msec", period, interval);
3938 p2p->ext_listen_period = period;
3939 p2p->ext_listen_interval = interval;
3940 p2p->ext_listen_interval_sec = interval / 1000;
3941 p2p->ext_listen_interval_usec = (interval % 1000) * 1000;
3942
3943 eloop_register_timeout(p2p->ext_listen_interval_sec,
3944 p2p->ext_listen_interval_usec,
3945 p2p_ext_listen_timeout, p2p, NULL);
3946
3947 return 0;
3948}
3949
3950
3951void p2p_deauth_notif(struct p2p_data *p2p, const u8 *bssid, u16 reason_code,
3952 const u8 *ie, size_t ie_len)
3953{
3954 struct p2p_message msg;
3955
3956 if (bssid == NULL || ie == NULL)
3957 return;
3958
3959 os_memset(&msg, 0, sizeof(msg));
3960 if (p2p_parse_ies(ie, ie_len, &msg))
3961 return;
3962 if (msg.minor_reason_code == NULL)
3963 return;
3964
3965 wpa_msg(p2p->cfg->msg_ctx, MSG_INFO,
3966 "P2P: Deauthentication notification BSSID " MACSTR
3967 " reason_code=%u minor_reason_code=%u",
3968 MAC2STR(bssid), reason_code, *msg.minor_reason_code);
3969
3970 p2p_parse_free(&msg);
3971}
3972
3973
3974void p2p_disassoc_notif(struct p2p_data *p2p, const u8 *bssid, u16 reason_code,
3975 const u8 *ie, size_t ie_len)
3976{
3977 struct p2p_message msg;
3978
3979 if (bssid == NULL || ie == NULL)
3980 return;
3981
3982 os_memset(&msg, 0, sizeof(msg));
3983 if (p2p_parse_ies(ie, ie_len, &msg))
3984 return;
3985 if (msg.minor_reason_code == NULL)
3986 return;
3987
3988 wpa_msg(p2p->cfg->msg_ctx, MSG_INFO,
3989 "P2P: Disassociation notification BSSID " MACSTR
3990 " reason_code=%u minor_reason_code=%u",
3991 MAC2STR(bssid), reason_code, *msg.minor_reason_code);
3992
3993 p2p_parse_free(&msg);
3994}
3995
3996
3997void p2p_set_managed_oper(struct p2p_data *p2p, int enabled)
3998{
3999 if (enabled) {
4000 wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG, "P2P: Managed P2P "
4001 "Device operations enabled");
4002 p2p->dev_capab |= P2P_DEV_CAPAB_INFRA_MANAGED;
4003 } else {
4004 wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG, "P2P: Managed P2P "
4005 "Device operations disabled");
4006 p2p->dev_capab &= ~P2P_DEV_CAPAB_INFRA_MANAGED;
4007 }
4008}
4009
4010
4011int p2p_set_listen_channel(struct p2p_data *p2p, u8 reg_class, u8 channel)
4012{
4013 if (p2p_channel_to_freq(p2p->cfg->country, reg_class, channel) < 0)
4014 return -1;
4015
4016 wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG, "P2P: Set Listen channel: "
4017 "reg_class %u channel %u", reg_class, channel);
4018 p2p->cfg->reg_class = reg_class;
4019 p2p->cfg->channel = channel;
4020
4021 return 0;
4022}
4023
4024
4025int p2p_set_ssid_postfix(struct p2p_data *p2p, const u8 *postfix, size_t len)
4026{
4027 wpa_hexdump_ascii(MSG_DEBUG, "P2P: New SSID postfix", postfix, len);
4028 if (postfix == NULL) {
4029 p2p->cfg->ssid_postfix_len = 0;
4030 return 0;
4031 }
4032 if (len > sizeof(p2p->cfg->ssid_postfix))
4033 return -1;
4034 os_memcpy(p2p->cfg->ssid_postfix, postfix, len);
4035 p2p->cfg->ssid_postfix_len = len;
4036 return 0;
4037}
4038
4039
Jouni Malinen75ecf522011-06-27 15:19:46 -07004040int p2p_set_oper_channel(struct p2p_data *p2p, u8 op_reg_class, u8 op_channel,
4041 int cfg_op_channel)
4042{
4043 if (p2p_channel_to_freq(p2p->cfg->country, op_reg_class, op_channel)
4044 < 0)
4045 return -1;
4046
4047 wpa_msg(p2p->cfg->msg_ctx, MSG_INFO, "P2P: Set Operating channel: "
4048 "reg_class %u channel %u", op_reg_class, op_channel);
4049 p2p->cfg->op_reg_class = op_reg_class;
4050 p2p->cfg->op_channel = op_channel;
4051 p2p->cfg->cfg_op_channel = cfg_op_channel;
4052 return 0;
4053}
4054
4055
Dmitry Shmidt04949592012-07-19 12:16:46 -07004056int p2p_set_pref_chan(struct p2p_data *p2p, unsigned int num_pref_chan,
4057 const struct p2p_channel *pref_chan)
4058{
4059 struct p2p_channel *n;
4060
4061 if (pref_chan) {
4062 n = os_malloc(num_pref_chan * sizeof(struct p2p_channel));
4063 if (n == NULL)
4064 return -1;
4065 os_memcpy(n, pref_chan,
4066 num_pref_chan * sizeof(struct p2p_channel));
4067 } else
4068 n = NULL;
4069
4070 os_free(p2p->cfg->pref_chan);
4071 p2p->cfg->pref_chan = n;
4072 p2p->cfg->num_pref_chan = num_pref_chan;
4073
4074 return 0;
4075}
4076
4077
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07004078int p2p_get_interface_addr(struct p2p_data *p2p, const u8 *dev_addr,
4079 u8 *iface_addr)
4080{
4081 struct p2p_device *dev = p2p_get_device(p2p, dev_addr);
4082 if (dev == NULL || is_zero_ether_addr(dev->interface_addr))
4083 return -1;
4084 os_memcpy(iface_addr, dev->interface_addr, ETH_ALEN);
4085 return 0;
4086}
4087
4088
4089int p2p_get_dev_addr(struct p2p_data *p2p, const u8 *iface_addr,
4090 u8 *dev_addr)
4091{
4092 struct p2p_device *dev = p2p_get_device_interface(p2p, iface_addr);
4093 if (dev == NULL)
4094 return -1;
4095 os_memcpy(dev_addr, dev->info.p2p_device_addr, ETH_ALEN);
4096 return 0;
4097}
4098
4099
4100void p2p_set_peer_filter(struct p2p_data *p2p, const u8 *addr)
4101{
4102 os_memcpy(p2p->peer_filter, addr, ETH_ALEN);
4103 if (is_zero_ether_addr(p2p->peer_filter))
4104 wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG, "P2P: Disable peer "
4105 "filter");
4106 else
4107 wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG, "P2P: Enable peer "
4108 "filter for " MACSTR, MAC2STR(p2p->peer_filter));
4109}
4110
4111
4112void p2p_set_cross_connect(struct p2p_data *p2p, int enabled)
4113{
4114 wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG, "P2P: Cross connection %s",
4115 enabled ? "enabled" : "disabled");
4116 if (p2p->cross_connect == enabled)
4117 return;
4118 p2p->cross_connect = enabled;
4119 /* TODO: may need to tear down any action group where we are GO(?) */
4120}
4121
4122
4123int p2p_get_oper_freq(struct p2p_data *p2p, const u8 *iface_addr)
4124{
4125 struct p2p_device *dev = p2p_get_device_interface(p2p, iface_addr);
4126 if (dev == NULL)
4127 return -1;
4128 if (dev->oper_freq <= 0)
4129 return -1;
4130 return dev->oper_freq;
4131}
4132
4133
4134void p2p_set_intra_bss_dist(struct p2p_data *p2p, int enabled)
4135{
4136 wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG, "P2P: Intra BSS distribution %s",
4137 enabled ? "enabled" : "disabled");
4138 p2p->cfg->p2p_intra_bss = enabled;
4139}
4140
4141
4142void p2p_update_channel_list(struct p2p_data *p2p, struct p2p_channels *chan)
4143{
4144 wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG, "P2P: Update channel list");
4145 os_memcpy(&p2p->cfg->channels, chan, sizeof(struct p2p_channels));
4146}
4147
4148
4149int p2p_send_action(struct p2p_data *p2p, unsigned int freq, const u8 *dst,
4150 const u8 *src, const u8 *bssid, const u8 *buf,
4151 size_t len, unsigned int wait_time)
4152{
4153 if (p2p->p2p_scan_running) {
4154 wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG, "P2P: Delay Action "
4155 "frame TX until p2p_scan completes");
4156 if (p2p->after_scan_tx) {
4157 wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG, "P2P: Dropped "
4158 "previous pending Action frame TX");
4159 os_free(p2p->after_scan_tx);
4160 }
4161 p2p->after_scan_tx = os_malloc(sizeof(*p2p->after_scan_tx) +
4162 len);
4163 if (p2p->after_scan_tx == NULL)
4164 return -1;
4165 p2p->after_scan_tx->freq = freq;
4166 os_memcpy(p2p->after_scan_tx->dst, dst, ETH_ALEN);
4167 os_memcpy(p2p->after_scan_tx->src, src, ETH_ALEN);
4168 os_memcpy(p2p->after_scan_tx->bssid, bssid, ETH_ALEN);
4169 p2p->after_scan_tx->len = len;
4170 p2p->after_scan_tx->wait_time = wait_time;
4171 os_memcpy(p2p->after_scan_tx + 1, buf, len);
4172 return 0;
4173 }
4174
4175 return p2p->cfg->send_action(p2p->cfg->cb_ctx, freq, dst, src, bssid,
4176 buf, len, wait_time);
4177}
4178
4179
4180void p2p_set_best_channels(struct p2p_data *p2p, int freq_24, int freq_5,
4181 int freq_overall)
4182{
4183 wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG, "P2P: Best channel: 2.4 GHz: %d,"
4184 " 5 GHz: %d, overall: %d", freq_24, freq_5, freq_overall);
4185 p2p->best_freq_24 = freq_24;
4186 p2p->best_freq_5 = freq_5;
4187 p2p->best_freq_overall = freq_overall;
4188}
4189
4190
4191const u8 * p2p_get_go_neg_peer(struct p2p_data *p2p)
4192{
4193 if (p2p == NULL || p2p->go_neg_peer == NULL)
4194 return NULL;
4195 return p2p->go_neg_peer->info.p2p_device_addr;
4196}
4197
4198
4199const struct p2p_peer_info *
4200p2p_get_peer_found(struct p2p_data *p2p, const u8 *addr, int next)
4201{
4202 struct p2p_device *dev;
4203
4204 if (addr) {
4205 dev = p2p_get_device(p2p, addr);
4206 if (!dev)
4207 return NULL;
4208
4209 if (!next) {
4210 if (dev->flags & P2P_DEV_PROBE_REQ_ONLY)
4211 return NULL;
4212
4213 return &dev->info;
4214 } else {
4215 do {
4216 dev = dl_list_first(&dev->list,
4217 struct p2p_device,
4218 list);
4219 if (&dev->list == &p2p->devices)
4220 return NULL;
4221 } while (dev->flags & P2P_DEV_PROBE_REQ_ONLY);
4222 }
4223 } else {
4224 dev = dl_list_first(&p2p->devices, struct p2p_device, list);
4225 if (!dev)
4226 return NULL;
4227 while (dev->flags & P2P_DEV_PROBE_REQ_ONLY) {
4228 dev = dl_list_first(&dev->list,
4229 struct p2p_device,
4230 list);
4231 if (&dev->list == &p2p->devices)
4232 return NULL;
4233 }
4234 }
4235
4236 return &dev->info;
4237}
Dmitry Shmidt1f69aa52012-01-24 16:10:04 -08004238
4239#ifdef ANDROID_P2P
4240int p2p_search_in_progress(struct p2p_data *p2p)
4241{
4242 if (p2p == NULL)
4243 return 0;
4244
4245 return p2p->state == P2P_SEARCH;
4246}
4247#endif
4248
4249int p2p_in_progress(struct p2p_data *p2p)
4250{
4251 if (p2p == NULL)
4252 return 0;
Dmitry Shmidt61d9df32012-08-29 16:22:06 -07004253 if (p2p->state == P2P_SEARCH || p2p->state == P2P_SEARCH_WHEN_READY ||
4254 p2p->state == P2P_CONTINUE_SEARCH_WHEN_READY)
4255 return 2;
Dmitry Shmidt1f69aa52012-01-24 16:10:04 -08004256 return p2p->state != P2P_IDLE && p2p->state != P2P_PROVISIONING;
4257}
Dmitry Shmidt61d9df32012-08-29 16:22:06 -07004258
4259
4260void p2p_set_config_timeout(struct p2p_data *p2p, u8 go_timeout,
4261 u8 client_timeout)
4262{
4263 if (p2p) {
4264 p2p->go_timeout = go_timeout;
4265 p2p->client_timeout = client_timeout;
4266 }
4267}
4268
4269
4270void p2p_increase_search_delay(struct p2p_data *p2p, unsigned int delay)
4271{
4272 if (p2p && p2p->search_delay < delay)
4273 p2p->search_delay = delay;
4274}
4275
4276
4277#ifdef CONFIG_WIFI_DISPLAY
4278
4279static void p2p_update_wfd_ie_groups(struct p2p_data *p2p)
4280{
4281 size_t g;
4282 struct p2p_group *group;
4283
4284 for (g = 0; g < p2p->num_groups; g++) {
4285 group = p2p->groups[g];
4286 p2p_group_update_ies(group);
4287 }
4288}
4289
4290
4291int p2p_set_wfd_ie_beacon(struct p2p_data *p2p, struct wpabuf *ie)
4292{
4293 wpabuf_free(p2p->wfd_ie_beacon);
4294 p2p->wfd_ie_beacon = ie;
4295 p2p_update_wfd_ie_groups(p2p);
4296 return 0;
4297}
4298
4299
4300int p2p_set_wfd_ie_probe_req(struct p2p_data *p2p, struct wpabuf *ie)
4301{
4302 wpabuf_free(p2p->wfd_ie_probe_req);
4303 p2p->wfd_ie_probe_req = ie;
4304 return 0;
4305}
4306
4307
4308int p2p_set_wfd_ie_probe_resp(struct p2p_data *p2p, struct wpabuf *ie)
4309{
4310 wpabuf_free(p2p->wfd_ie_probe_resp);
4311 p2p->wfd_ie_probe_resp = ie;
4312 p2p_update_wfd_ie_groups(p2p);
4313 return 0;
4314}
4315
4316
4317int p2p_set_wfd_ie_assoc_req(struct p2p_data *p2p, struct wpabuf *ie)
4318{
4319 wpabuf_free(p2p->wfd_ie_assoc_req);
4320 p2p->wfd_ie_assoc_req = ie;
4321 return 0;
4322}
4323
4324
4325int p2p_set_wfd_ie_invitation(struct p2p_data *p2p, struct wpabuf *ie)
4326{
4327 wpabuf_free(p2p->wfd_ie_invitation);
4328 p2p->wfd_ie_invitation = ie;
4329 return 0;
4330}
4331
4332
4333int p2p_set_wfd_ie_prov_disc_req(struct p2p_data *p2p, struct wpabuf *ie)
4334{
4335 wpabuf_free(p2p->wfd_ie_prov_disc_req);
4336 p2p->wfd_ie_prov_disc_req = ie;
4337 return 0;
4338}
4339
4340
4341int p2p_set_wfd_ie_prov_disc_resp(struct p2p_data *p2p, struct wpabuf *ie)
4342{
4343 wpabuf_free(p2p->wfd_ie_prov_disc_resp);
4344 p2p->wfd_ie_prov_disc_resp = ie;
4345 return 0;
4346}
4347
4348
4349int p2p_set_wfd_ie_go_neg(struct p2p_data *p2p, struct wpabuf *ie)
4350{
4351 wpabuf_free(p2p->wfd_ie_go_neg);
4352 p2p->wfd_ie_go_neg = ie;
4353 return 0;
4354}
4355
4356
4357int p2p_set_wfd_dev_info(struct p2p_data *p2p, const struct wpabuf *elem)
4358{
4359 wpabuf_free(p2p->wfd_dev_info);
4360 if (elem) {
4361 p2p->wfd_dev_info = wpabuf_dup(elem);
4362 if (p2p->wfd_dev_info == NULL)
4363 return -1;
4364 } else
4365 p2p->wfd_dev_info = NULL;
4366
4367 return 0;
4368}
4369
4370
4371int p2p_set_wfd_assoc_bssid(struct p2p_data *p2p, const struct wpabuf *elem)
4372{
4373 wpabuf_free(p2p->wfd_assoc_bssid);
4374 if (elem) {
4375 p2p->wfd_assoc_bssid = wpabuf_dup(elem);
4376 if (p2p->wfd_assoc_bssid == NULL)
4377 return -1;
4378 } else
4379 p2p->wfd_assoc_bssid = NULL;
4380
4381 return 0;
4382}
4383
4384
4385int p2p_set_wfd_coupled_sink_info(struct p2p_data *p2p,
4386 const struct wpabuf *elem)
4387{
4388 wpabuf_free(p2p->wfd_coupled_sink_info);
4389 if (elem) {
4390 p2p->wfd_coupled_sink_info = wpabuf_dup(elem);
4391 if (p2p->wfd_coupled_sink_info == NULL)
4392 return -1;
4393 } else
4394 p2p->wfd_coupled_sink_info = NULL;
4395
4396 return 0;
4397}
4398
4399#endif /* CONFIG_WIFI_DISPLAY */
Dmitry Shmidtd5e49232012-12-03 15:08:10 -08004400
4401
4402int p2p_set_disc_int(struct p2p_data *p2p, int min_disc_int, int max_disc_int,
4403 int max_disc_tu)
4404{
4405 if (min_disc_int > max_disc_int || min_disc_int < 0 || max_disc_int < 0)
4406 return -1;
4407
4408 p2p->min_disc_int = min_disc_int;
4409 p2p->max_disc_int = max_disc_int;
4410 p2p->max_disc_tu = max_disc_tu;
4411 wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG, "P2P: Set discoverable interval: "
4412 "min=%d max=%d max_tu=%d", min_disc_int, max_disc_int,
4413 max_disc_tu);
4414
4415 return 0;
4416}