p2p.c revision 8da800a193fb6f8832218715f82a7b4e2d2ad338
18d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt/* 28d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * Wi-Fi Direct - P2P module 38d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * Copyright (c) 2009-2010, Atheros Communications 48d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * 5c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt * This software may be distributed under the terms of the BSD license. 6c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt * See README for more details. 78d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */ 88d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 98d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include "includes.h" 108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include "common.h" 128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include "eloop.h" 138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include "common/ieee802_11_defs.h" 148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include "common/ieee802_11_common.h" 15c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt#include "common/wpa_ctrl.h" 168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include "wps/wps_i.h" 178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include "p2p_i.h" 188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include "p2p.h" 198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic void p2p_state_timeout(void *eloop_ctx, void *timeout_ctx); 228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic void p2p_device_free(struct p2p_data *p2p, struct p2p_device *dev); 238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic void p2p_process_presence_req(struct p2p_data *p2p, const u8 *da, 248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt const u8 *sa, const u8 *data, size_t len, 258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt int rx_freq); 268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic void p2p_process_presence_resp(struct p2p_data *p2p, const u8 *da, 278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt const u8 *sa, const u8 *data, 288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt size_t len); 298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic void p2p_ext_listen_timeout(void *eloop_ctx, void *timeout_ctx); 308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic void p2p_scan_timeout(void *eloop_ctx, void *timeout_ctx); 318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt/* 348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * p2p_scan recovery timeout 358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * 368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * Many drivers are using 30 second timeout on scan results. Allow a bit larger 378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * timeout for this to avoid hitting P2P timeout unnecessarily. 388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */ 398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#define P2P_SCAN_TIMEOUT 35 408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt/** 428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * P2P_PEER_EXPIRATION_AGE - Number of seconds after which inactive peer 438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * entries will be removed 448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */ 452fb777c379ad560c309c54b96c2c13291da23f54Dmitry Shmidt#ifdef ANDROID_P2P 462fb777c379ad560c309c54b96c2c13291da23f54Dmitry Shmidt#define P2P_PEER_EXPIRATION_AGE 30 472fb777c379ad560c309c54b96c2c13291da23f54Dmitry Shmidt#else 488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#define P2P_PEER_EXPIRATION_AGE 300 492fb777c379ad560c309c54b96c2c13291da23f54Dmitry Shmidt#endif 508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#define P2P_PEER_EXPIRATION_INTERVAL (P2P_PEER_EXPIRATION_AGE / 2) 528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 532fb777c379ad560c309c54b96c2c13291da23f54Dmitry Shmidt#ifdef ANDROID_P2P 542fb777c379ad560c309c54b96c2c13291da23f54Dmitry Shmidtint p2p_connection_in_progress(struct p2p_data *p2p) 552fb777c379ad560c309c54b96c2c13291da23f54Dmitry Shmidt{ 562fb777c379ad560c309c54b96c2c13291da23f54Dmitry Shmidt int ret = 0; 572fb777c379ad560c309c54b96c2c13291da23f54Dmitry Shmidt 582fb777c379ad560c309c54b96c2c13291da23f54Dmitry Shmidt switch (p2p->state) { 592fb777c379ad560c309c54b96c2c13291da23f54Dmitry Shmidt case P2P_CONNECT: 602fb777c379ad560c309c54b96c2c13291da23f54Dmitry Shmidt case P2P_CONNECT_LISTEN: 612fb777c379ad560c309c54b96c2c13291da23f54Dmitry Shmidt case P2P_GO_NEG: 622fb777c379ad560c309c54b96c2c13291da23f54Dmitry Shmidt case P2P_WAIT_PEER_CONNECT: 6398f9e76624da6bb96edc1982c423e4a119c5170aDmitry Shmidt case P2P_WAIT_PEER_IDLE: 642fb777c379ad560c309c54b96c2c13291da23f54Dmitry Shmidt case P2P_PROVISIONING: 652fb777c379ad560c309c54b96c2c13291da23f54Dmitry Shmidt case P2P_INVITE: 662fb777c379ad560c309c54b96c2c13291da23f54Dmitry Shmidt case P2P_INVITE_LISTEN: 672fb777c379ad560c309c54b96c2c13291da23f54Dmitry Shmidt ret = 1; 682fb777c379ad560c309c54b96c2c13291da23f54Dmitry Shmidt break; 692fb777c379ad560c309c54b96c2c13291da23f54Dmitry Shmidt 702fb777c379ad560c309c54b96c2c13291da23f54Dmitry Shmidt default: 7198f9e76624da6bb96edc1982c423e4a119c5170aDmitry Shmidt wpa_printf(MSG_DEBUG, "p2p_connection_in_progress state %d", p2p->state); 722fb777c379ad560c309c54b96c2c13291da23f54Dmitry Shmidt ret = 0; 732fb777c379ad560c309c54b96c2c13291da23f54Dmitry Shmidt } 742fb777c379ad560c309c54b96c2c13291da23f54Dmitry Shmidt 752fb777c379ad560c309c54b96c2c13291da23f54Dmitry Shmidt return ret; 762fb777c379ad560c309c54b96c2c13291da23f54Dmitry Shmidt} 772fb777c379ad560c309c54b96c2c13291da23f54Dmitry Shmidt#endif 782fb777c379ad560c309c54b96c2c13291da23f54Dmitry Shmidt 798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic void p2p_expire_peers(struct p2p_data *p2p) 808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct p2p_device *dev, *n; 828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct os_time now; 83c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt size_t i; 848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_get_time(&now); 868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt dl_list_for_each_safe(dev, n, &p2p->devices, struct p2p_device, list) { 878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (dev->last_seen.sec + P2P_PEER_EXPIRATION_AGE >= now.sec) 888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt continue; 89c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt 90c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt if (p2p->cfg->go_connected && 91c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt p2p->cfg->go_connected(p2p->cfg->cb_ctx, 92c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt dev->info.p2p_device_addr)) { 93c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt /* 94c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt * We are connected as a client to a group in which the 95c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt * peer is the GO, so do not expire the peer entry. 96c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt */ 97c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt os_get_time(&dev->last_seen); 98c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt continue; 99c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt } 100c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt 101c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt for (i = 0; i < p2p->num_groups; i++) { 102c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt if (p2p_group_is_client_connected( 103c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt p2p->groups[i], dev->info.p2p_device_addr)) 104c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt break; 105c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt } 106c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt if (i < p2p->num_groups) { 107c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt /* 108c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt * The peer is connected as a client in a group where 109c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt * we are the GO, so do not expire the peer entry. 110c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt */ 111c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt os_get_time(&dev->last_seen); 112c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt continue; 113c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt } 114c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt 1152fb777c379ad560c309c54b96c2c13291da23f54Dmitry Shmidt#ifdef ANDROID_P2P 1162fb777c379ad560c309c54b96c2c13291da23f54Dmitry Shmidt /* If Connection is in progress, don't expire the peer 1172fb777c379ad560c309c54b96c2c13291da23f54Dmitry Shmidt */ 1182fb777c379ad560c309c54b96c2c13291da23f54Dmitry Shmidt if (p2p_connection_in_progress(p2p)) 1192fb777c379ad560c309c54b96c2c13291da23f54Dmitry Shmidt continue; 1202fb777c379ad560c309c54b96c2c13291da23f54Dmitry Shmidt#endif 1212fb777c379ad560c309c54b96c2c13291da23f54Dmitry Shmidt 12204949598a23f501be6eec21697465fd46a28840aDmitry Shmidt wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG, "P2P: Expiring old peer " 1238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "entry " MACSTR, MAC2STR(dev->info.p2p_device_addr)); 124f44b9c4a18d17fbd39901f76a014c32006570fb8Irfan Sheriff#ifdef ANDROID_P2P 125f44b9c4a18d17fbd39901f76a014c32006570fb8Irfan Sheriff /* SD_FAIR_POLICY: Update the current sd_dev_list pointer to next device */ 126f44b9c4a18d17fbd39901f76a014c32006570fb8Irfan Sheriff if(&dev->list == p2p->sd_dev_list) 127f44b9c4a18d17fbd39901f76a014c32006570fb8Irfan Sheriff p2p->sd_dev_list = dev->list.next; 128f44b9c4a18d17fbd39901f76a014c32006570fb8Irfan Sheriff#endif 1298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt dl_list_del(&dev->list); 1308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_device_free(p2p, dev); 1318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 1328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 1338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic void p2p_expiration_timeout(void *eloop_ctx, void *timeout_ctx) 1368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 1378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct p2p_data *p2p = eloop_ctx; 1388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_expire_peers(p2p); 1398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt eloop_register_timeout(P2P_PEER_EXPIRATION_INTERVAL, 0, 1408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_expiration_timeout, p2p, NULL); 1418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 1428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic const char * p2p_state_txt(int state) 1458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 1468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt switch (state) { 1478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case P2P_IDLE: 1488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return "IDLE"; 1498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case P2P_SEARCH: 1508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return "SEARCH"; 1518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case P2P_CONNECT: 1528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return "CONNECT"; 1538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case P2P_CONNECT_LISTEN: 1548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return "CONNECT_LISTEN"; 1558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case P2P_GO_NEG: 1568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return "GO_NEG"; 1578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case P2P_LISTEN_ONLY: 1588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return "LISTEN_ONLY"; 1598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case P2P_WAIT_PEER_CONNECT: 1608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return "WAIT_PEER_CONNECT"; 1618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case P2P_WAIT_PEER_IDLE: 1628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return "WAIT_PEER_IDLE"; 1638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case P2P_SD_DURING_FIND: 1648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return "SD_DURING_FIND"; 1658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case P2P_PROVISIONING: 1668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return "PROVISIONING"; 1678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case P2P_PD_DURING_FIND: 1688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return "PD_DURING_FIND"; 1698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case P2P_INVITE: 1708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return "INVITE"; 1718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case P2P_INVITE_LISTEN: 1728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return "INVITE_LISTEN"; 1731f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt case P2P_SEARCH_WHEN_READY: 1741f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt return "SEARCH_WHEN_READY"; 17561d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt case P2P_CONTINUE_SEARCH_WHEN_READY: 17661d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt return "CONTINUE_SEARCH_WHEN_READY"; 1778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt default: 1788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return "?"; 1798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 1808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 1818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1831f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidtu16 p2p_get_provisioning_info(struct p2p_data *p2p, const u8 *addr) 1841f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt{ 1851f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt struct p2p_device *dev = NULL; 1861f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt 1871f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt if (!addr || !p2p) 1881f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt return 0; 1891f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt 1901f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt dev = p2p_get_device(p2p, addr); 1911f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt if (dev) 1921f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt return dev->wps_prov_info; 1931f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt else 1941f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt return 0; 1951f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt} 1961f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt 1971f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt 19804949598a23f501be6eec21697465fd46a28840aDmitry Shmidtvoid p2p_clear_provisioning_info(struct p2p_data *p2p, const u8 *addr) 1991f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt{ 2001f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt struct p2p_device *dev = NULL; 2011f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt 20204949598a23f501be6eec21697465fd46a28840aDmitry Shmidt if (!addr || !p2p) 2031f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt return; 2041f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt 20504949598a23f501be6eec21697465fd46a28840aDmitry Shmidt dev = p2p_get_device(p2p, addr); 2061f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt if (dev) 2071f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt dev->wps_prov_info = 0; 2081f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt} 2091f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt 2101f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt 2118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtvoid p2p_set_state(struct p2p_data *p2p, int new_state) 2128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 2138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG, "P2P: State %s -> %s", 2148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_state_txt(p2p->state), p2p_state_txt(new_state)); 2158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p->state = new_state; 2168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 2178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtvoid p2p_set_timeout(struct p2p_data *p2p, unsigned int sec, unsigned int usec) 2208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 2218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG, 2228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "P2P: Set timeout (state=%s): %u.%06u sec", 2238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_state_txt(p2p->state), sec, usec); 2248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt eloop_cancel_timeout(p2p_state_timeout, p2p, NULL); 2258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt eloop_register_timeout(sec, usec, p2p_state_timeout, p2p, NULL); 2268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 2278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtvoid p2p_clear_timeout(struct p2p_data *p2p) 2308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 2318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG, "P2P: Clear timeout (state=%s)", 2328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_state_txt(p2p->state)); 2338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt eloop_cancel_timeout(p2p_state_timeout, p2p, NULL); 2348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 2358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtvoid p2p_go_neg_failed(struct p2p_data *p2p, struct p2p_device *peer, 2388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt int status) 2398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 2408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct p2p_go_neg_results res; 2418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_clear_timeout(p2p); 2428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_set_state(p2p, P2P_IDLE); 2438c65289885e84727226d81b3d32856f79c31ee5fDmitry Shmidt if (p2p->go_neg_peer) { 2448c65289885e84727226d81b3d32856f79c31ee5fDmitry Shmidt p2p->go_neg_peer->flags &= ~P2P_DEV_PEER_WAITING_RESPONSE; 2451f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt p2p->go_neg_peer->wps_method = WPS_NOT_READY; 2468c65289885e84727226d81b3d32856f79c31ee5fDmitry Shmidt } 2478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p->go_neg_peer = NULL; 2488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memset(&res, 0, sizeof(res)); 2508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt res.status = status; 2518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (peer) { 2528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memcpy(res.peer_device_addr, peer->info.p2p_device_addr, 2538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ETH_ALEN); 2548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memcpy(res.peer_interface_addr, peer->intended_addr, 2558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ETH_ALEN); 2568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 2578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p->cfg->go_neg_completed(p2p->cfg->cb_ctx, &res); 2588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 2598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 261d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidtstatic void p2p_listen_in_find(struct p2p_data *p2p, int dev_disc) 2628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 2638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt unsigned int r, tu; 2648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt int freq; 2658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct wpabuf *ies; 2668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG, 2688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "P2P: Starting short listen state (state=%s)", 2698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_state_txt(p2p->state)); 2708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt freq = p2p_channel_to_freq(p2p->cfg->country, p2p->cfg->reg_class, 2728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p->cfg->channel); 2738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (freq < 0) { 2748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG, 2758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "P2P: Unknown regulatory class/channel"); 2768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; 2778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 2788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_get_random((u8 *) &r, sizeof(r)); 2808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt tu = (r % ((p2p->max_disc_int - p2p->min_disc_int) + 1) + 2818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p->min_disc_int) * 100; 282d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt if (p2p->max_disc_tu >= 0 && tu > (unsigned int) p2p->max_disc_tu) 283d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt tu = p2p->max_disc_tu; 284d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt if (!dev_disc && tu < 100) 285d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt tu = 100; /* Need to wait in non-device discovery use cases */ 286d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt if (p2p->cfg->max_listen && 1024 * tu / 1000 > p2p->cfg->max_listen) 287d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt tu = p2p->cfg->max_listen * 1000 / 1024; 288d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt 289d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt if (tu == 0) { 290d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG, "P2P: Skip listen state " 291d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt "since duration was 0 TU"); 292d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt p2p_set_timeout(p2p, 0, 0); 293d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt return; 294d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt } 2958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p->pending_listen_freq = freq; 2978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p->pending_listen_sec = 0; 2988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p->pending_listen_usec = 1024 * tu; 2998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 3008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ies = p2p_build_probe_resp_ies(p2p); 3018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (ies == NULL) 3028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; 3038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 3048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (p2p->cfg->start_listen(p2p->cfg->cb_ctx, freq, 1024 * tu / 1000, 3058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ies) < 0) { 3068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG, 3078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "P2P: Failed to start listen mode"); 3088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p->pending_listen_freq = 0; 3098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 3108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpabuf_free(ies); 3118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 3128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 3138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 3148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtint p2p_listen(struct p2p_data *p2p, unsigned int timeout) 3158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 3168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt int freq; 3178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct wpabuf *ies; 3188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 3198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG, 3208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "P2P: Going to listen(only) state"); 3218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 3228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt freq = p2p_channel_to_freq(p2p->cfg->country, p2p->cfg->reg_class, 3238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p->cfg->channel); 3248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (freq < 0) { 3258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG, 3268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "P2P: Unknown regulatory class/channel"); 3278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 3288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 3298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 3308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p->pending_listen_freq = freq; 3318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p->pending_listen_sec = timeout / 1000; 3328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p->pending_listen_usec = (timeout % 1000) * 1000; 3338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 3348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (p2p->p2p_scan_running) { 33504949598a23f501be6eec21697465fd46a28840aDmitry Shmidt if (p2p->start_after_scan == P2P_AFTER_SCAN_CONNECT) { 3361f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG, 3371f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt "P2P: p2p_scan running - connect is already " 3381f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt "pending - skip listen"); 3391f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt return 0; 3401f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt } 3418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG, 3428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "P2P: p2p_scan running - delay start of listen state"); 3438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p->start_after_scan = P2P_AFTER_SCAN_LISTEN; 3448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 3458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 3468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 3478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ies = p2p_build_probe_resp_ies(p2p); 3488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (ies == NULL) 3498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 3508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 3518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (p2p->cfg->start_listen(p2p->cfg->cb_ctx, freq, timeout, ies) < 0) { 3528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG, 3538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "P2P: Failed to start listen mode"); 3548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p->pending_listen_freq = 0; 3558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpabuf_free(ies); 3568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 3578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 3588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpabuf_free(ies); 3598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 3608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_set_state(p2p, P2P_LISTEN_ONLY); 3618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 3628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 3638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 3648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 3658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 3668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic void p2p_device_clear_reported(struct p2p_data *p2p) 3678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 3688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct p2p_device *dev; 3698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt dl_list_for_each(dev, &p2p->devices, struct p2p_device, list) 3708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt dev->flags &= ~P2P_DEV_REPORTED; 3718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 3728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 3738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 3748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt/** 3758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * p2p_get_device - Fetch a peer entry 3768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @p2p: P2P module context from p2p_init() 3778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @addr: P2P Device Address of the peer 3788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * Returns: Pointer to the device entry or %NULL if not found 3798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */ 3808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstruct p2p_device * p2p_get_device(struct p2p_data *p2p, const u8 *addr) 3818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 3828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct p2p_device *dev; 3838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt dl_list_for_each(dev, &p2p->devices, struct p2p_device, list) { 3848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (os_memcmp(dev->info.p2p_device_addr, addr, ETH_ALEN) == 0) 3858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return dev; 3868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 3878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return NULL; 3888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 3898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 3908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 3918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt/** 3928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * p2p_get_device_interface - Fetch a peer entry based on P2P Interface Address 3938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @p2p: P2P module context from p2p_init() 3948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @addr: P2P Interface Address of the peer 3958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * Returns: Pointer to the device entry or %NULL if not found 3968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */ 3978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstruct p2p_device * p2p_get_device_interface(struct p2p_data *p2p, 3988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt const u8 *addr) 3998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 4008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct p2p_device *dev; 4018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt dl_list_for_each(dev, &p2p->devices, struct p2p_device, list) { 4028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (os_memcmp(dev->interface_addr, addr, ETH_ALEN) == 0) 4038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return dev; 4048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 4058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return NULL; 4068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 4078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 4088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 4098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt/** 4108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * p2p_create_device - Create a peer entry 4118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @p2p: P2P module context from p2p_init() 4128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @addr: P2P Device Address of the peer 4138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * Returns: Pointer to the device entry or %NULL on failure 4148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * 4158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * If there is already an entry for the peer, it will be returned instead of 4168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * creating a new one. 4178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */ 4188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic struct p2p_device * p2p_create_device(struct p2p_data *p2p, 4198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt const u8 *addr) 4208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 4218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct p2p_device *dev, *oldest = NULL; 4228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt size_t count = 0; 4238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 4248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt dev = p2p_get_device(p2p, addr); 4258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (dev) 4268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return dev; 4278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 4288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt dl_list_for_each(dev, &p2p->devices, struct p2p_device, list) { 4298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt count++; 4308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (oldest == NULL || 4318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_time_before(&dev->last_seen, &oldest->last_seen)) 4328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt oldest = dev; 4338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 4348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (count + 1 > p2p->cfg->max_peers && oldest) { 4358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG, 4368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "P2P: Remove oldest peer entry to make room for a new " 4378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "peer"); 438f44b9c4a18d17fbd39901f76a014c32006570fb8Irfan Sheriff#ifdef ANDROID_P2P 439f44b9c4a18d17fbd39901f76a014c32006570fb8Irfan Sheriff /* SD_FAIR_POLICY: Update the current sd_dev_list pointer to next device */ 440f44b9c4a18d17fbd39901f76a014c32006570fb8Irfan Sheriff if(&oldest->list == p2p->sd_dev_list) 441f44b9c4a18d17fbd39901f76a014c32006570fb8Irfan Sheriff p2p->sd_dev_list = oldest->list.next; 442f44b9c4a18d17fbd39901f76a014c32006570fb8Irfan Sheriff#endif 4438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt dl_list_del(&oldest->list); 4448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_device_free(p2p, oldest); 4458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 4468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 4478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt dev = os_zalloc(sizeof(*dev)); 4488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (dev == NULL) 4498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return NULL; 4508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt dl_list_add(&p2p->devices, &dev->list); 4518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memcpy(dev->info.p2p_device_addr, addr, ETH_ALEN); 4528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 4538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return dev; 4548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 4558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 4568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 4578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic void p2p_copy_client_info(struct p2p_device *dev, 4588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct p2p_client_info *cli) 4598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 4608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memcpy(dev->info.device_name, cli->dev_name, cli->dev_name_len); 4618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt dev->info.device_name[cli->dev_name_len] = '\0'; 4628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt dev->info.dev_capab = cli->dev_capab; 4638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt dev->info.config_methods = cli->config_methods; 4648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memcpy(dev->info.pri_dev_type, cli->pri_dev_type, 8); 4658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt dev->info.wps_sec_dev_type_list_len = 8 * cli->num_sec_dev_types; 4668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memcpy(dev->info.wps_sec_dev_type_list, cli->sec_dev_types, 4678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt dev->info.wps_sec_dev_type_list_len); 4688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 4698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 4708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 4718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic int p2p_add_group_clients(struct p2p_data *p2p, const u8 *go_dev_addr, 4728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt const u8 *go_interface_addr, int freq, 4738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt const u8 *gi, size_t gi_len) 4748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 4758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct p2p_group_info info; 4768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt size_t c; 4778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct p2p_device *dev; 4788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 4798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (gi == NULL) 4808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 4818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 4828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (p2p_group_info_parse(gi, gi_len, &info) < 0) 4838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 4848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 4858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* 4868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * Clear old data for this group; if the devices are still in the 4878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * group, the information will be restored in the loop following this. 4888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */ 4898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt dl_list_for_each(dev, &p2p->devices, struct p2p_device, list) { 4901f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt if (os_memcmp(dev->member_in_go_iface, go_interface_addr, 4918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ETH_ALEN) == 0) { 4928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memset(dev->member_in_go_iface, 0, ETH_ALEN); 4938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memset(dev->member_in_go_dev, 0, ETH_ALEN); 4948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 4958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 4968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 4978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt for (c = 0; c < info.num_clients; c++) { 4988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct p2p_client_info *cli = &info.client[c]; 4991f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt if (os_memcmp(cli->p2p_device_addr, p2p->cfg->dev_addr, 5001f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt ETH_ALEN) == 0) 5011f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt continue; /* ignore our own entry */ 5028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt dev = p2p_get_device(p2p, cli->p2p_device_addr); 5038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (dev) { 5048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (dev->flags & (P2P_DEV_GROUP_CLIENT_ONLY | 50504949598a23f501be6eec21697465fd46a28840aDmitry Shmidt P2P_DEV_PROBE_REQ_ONLY)) { 50604949598a23f501be6eec21697465fd46a28840aDmitry Shmidt /* 50704949598a23f501be6eec21697465fd46a28840aDmitry Shmidt * Update information since we have not 50804949598a23f501be6eec21697465fd46a28840aDmitry Shmidt * received this directly from the client. 50904949598a23f501be6eec21697465fd46a28840aDmitry Shmidt */ 5108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_copy_client_info(dev, cli); 51104949598a23f501be6eec21697465fd46a28840aDmitry Shmidt } else { 51204949598a23f501be6eec21697465fd46a28840aDmitry Shmidt /* 51304949598a23f501be6eec21697465fd46a28840aDmitry Shmidt * Need to update P2P Client Discoverability 51404949598a23f501be6eec21697465fd46a28840aDmitry Shmidt * flag since it is valid only in P2P Group 51504949598a23f501be6eec21697465fd46a28840aDmitry Shmidt * Info attribute. 51604949598a23f501be6eec21697465fd46a28840aDmitry Shmidt */ 51704949598a23f501be6eec21697465fd46a28840aDmitry Shmidt dev->info.dev_capab &= 51804949598a23f501be6eec21697465fd46a28840aDmitry Shmidt ~P2P_DEV_CAPAB_CLIENT_DISCOVERABILITY; 51904949598a23f501be6eec21697465fd46a28840aDmitry Shmidt dev->info.dev_capab |= 52004949598a23f501be6eec21697465fd46a28840aDmitry Shmidt cli->dev_capab & 52104949598a23f501be6eec21697465fd46a28840aDmitry Shmidt P2P_DEV_CAPAB_CLIENT_DISCOVERABILITY; 52204949598a23f501be6eec21697465fd46a28840aDmitry Shmidt } 5238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (dev->flags & P2P_DEV_PROBE_REQ_ONLY) { 5248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt dev->flags &= ~P2P_DEV_PROBE_REQ_ONLY; 5258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 5268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } else { 5278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt dev = p2p_create_device(p2p, cli->p2p_device_addr); 5288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (dev == NULL) 5298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt continue; 5308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt dev->flags |= P2P_DEV_GROUP_CLIENT_ONLY; 5318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_copy_client_info(dev, cli); 5328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt dev->oper_freq = freq; 5338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p->cfg->dev_found(p2p->cfg->cb_ctx, 5348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt dev->info.p2p_device_addr, 5358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt &dev->info, 1); 5368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt dev->flags |= P2P_DEV_REPORTED | P2P_DEV_REPORTED_ONCE; 5378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 5388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 5398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memcpy(dev->interface_addr, cli->p2p_interface_addr, 5408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ETH_ALEN); 5418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_get_time(&dev->last_seen); 5428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memcpy(dev->member_in_go_dev, go_dev_addr, ETH_ALEN); 5438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memcpy(dev->member_in_go_iface, go_interface_addr, 5448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ETH_ALEN); 5458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 5468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 5478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 5488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 5498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 5508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 5518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic void p2p_copy_wps_info(struct p2p_device *dev, int probe_req, 5528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt const struct p2p_message *msg) 5538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 5548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memcpy(dev->info.device_name, msg->device_name, 5558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sizeof(dev->info.device_name)); 5568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 5578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (msg->manufacturer && 5588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt msg->manufacturer_len < sizeof(dev->info.manufacturer)) { 5598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memset(dev->info.manufacturer, 0, 5608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sizeof(dev->info.manufacturer)); 5618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memcpy(dev->info.manufacturer, msg->manufacturer, 5628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt msg->manufacturer_len); 5638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 5648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 5658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (msg->model_name && 5668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt msg->model_name_len < sizeof(dev->info.model_name)) { 5678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memset(dev->info.model_name, 0, 5688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sizeof(dev->info.model_name)); 5698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memcpy(dev->info.model_name, msg->model_name, 5708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt msg->model_name_len); 5718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 5728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 5738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (msg->model_number && 5748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt msg->model_number_len < sizeof(dev->info.model_number)) { 5758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memset(dev->info.model_number, 0, 5768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sizeof(dev->info.model_number)); 5778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memcpy(dev->info.model_number, msg->model_number, 5788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt msg->model_number_len); 5798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 5808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 5818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (msg->serial_number && 5828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt msg->serial_number_len < sizeof(dev->info.serial_number)) { 5838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memset(dev->info.serial_number, 0, 5848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sizeof(dev->info.serial_number)); 5858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memcpy(dev->info.serial_number, msg->serial_number, 5868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt msg->serial_number_len); 5878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 5888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 5898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (msg->pri_dev_type) 5908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memcpy(dev->info.pri_dev_type, msg->pri_dev_type, 5918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sizeof(dev->info.pri_dev_type)); 5928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt else if (msg->wps_pri_dev_type) 5938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memcpy(dev->info.pri_dev_type, msg->wps_pri_dev_type, 5948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sizeof(dev->info.pri_dev_type)); 5958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 5968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (msg->wps_sec_dev_type_list) { 5978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memcpy(dev->info.wps_sec_dev_type_list, 5988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt msg->wps_sec_dev_type_list, 5998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt msg->wps_sec_dev_type_list_len); 6008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt dev->info.wps_sec_dev_type_list_len = 6018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt msg->wps_sec_dev_type_list_len; 6028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 6038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 6048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (msg->capability) { 60504949598a23f501be6eec21697465fd46a28840aDmitry Shmidt /* 60604949598a23f501be6eec21697465fd46a28840aDmitry Shmidt * P2P Client Discoverability bit is reserved in all frames 60704949598a23f501be6eec21697465fd46a28840aDmitry Shmidt * that use this function, so do not change its value here. 60804949598a23f501be6eec21697465fd46a28840aDmitry Shmidt */ 60904949598a23f501be6eec21697465fd46a28840aDmitry Shmidt dev->info.dev_capab &= P2P_DEV_CAPAB_CLIENT_DISCOVERABILITY; 61004949598a23f501be6eec21697465fd46a28840aDmitry Shmidt dev->info.dev_capab |= msg->capability[0] & 61104949598a23f501be6eec21697465fd46a28840aDmitry Shmidt ~P2P_DEV_CAPAB_CLIENT_DISCOVERABILITY; 6128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt dev->info.group_capab = msg->capability[1]; 6138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 6148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 6158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (msg->ext_listen_timing) { 6168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt dev->ext_listen_period = WPA_GET_LE16(msg->ext_listen_timing); 6178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt dev->ext_listen_interval = 6188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt WPA_GET_LE16(msg->ext_listen_timing + 2); 6198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 62004949598a23f501be6eec21697465fd46a28840aDmitry Shmidt 6218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (!probe_req) { 622f86232838cf712377867cb42417c1613ab5dc425Dmitry Shmidt u16 new_config_methods; 623f86232838cf712377867cb42417c1613ab5dc425Dmitry Shmidt new_config_methods = msg->config_methods ? 6248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt msg->config_methods : msg->wps_config_methods; 625f86232838cf712377867cb42417c1613ab5dc425Dmitry Shmidt if (new_config_methods && 626f86232838cf712377867cb42417c1613ab5dc425Dmitry Shmidt dev->info.config_methods != new_config_methods) { 627f86232838cf712377867cb42417c1613ab5dc425Dmitry Shmidt wpa_printf(MSG_DEBUG, "P2P: Update peer " MACSTR 628f86232838cf712377867cb42417c1613ab5dc425Dmitry Shmidt " config_methods 0x%x -> 0x%x", 629f86232838cf712377867cb42417c1613ab5dc425Dmitry Shmidt MAC2STR(dev->info.p2p_device_addr), 630f86232838cf712377867cb42417c1613ab5dc425Dmitry Shmidt dev->info.config_methods, 631f86232838cf712377867cb42417c1613ab5dc425Dmitry Shmidt new_config_methods); 632f86232838cf712377867cb42417c1613ab5dc425Dmitry Shmidt dev->info.config_methods = new_config_methods; 633f86232838cf712377867cb42417c1613ab5dc425Dmitry Shmidt } 6348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 6358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 6368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 6378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 6388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt/** 63904949598a23f501be6eec21697465fd46a28840aDmitry Shmidt * p2p_add_device - Add peer entries based on scan results or P2P frames 6408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @p2p: P2P module context from p2p_init() 6418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @addr: Source address of Beacon or Probe Response frame (may be either 6428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * P2P Device Address or P2P Interface Address) 6438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @level: Signal level (signal strength of the received frame from the peer) 6448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @freq: Frequency on which the Beacon or Probe Response frame was received 645f86232838cf712377867cb42417c1613ab5dc425Dmitry Shmidt * @rx_time: Time when the result was received 6468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @ies: IEs from the Beacon or Probe Response frame 6478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @ies_len: Length of ies buffer in octets 64804949598a23f501be6eec21697465fd46a28840aDmitry Shmidt * @scan_res: Whether this was based on scan results 6498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * Returns: 0 on success, -1 on failure 6508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * 6518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * If the scan result is for a GO, the clients in the group will also be added 6528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * to the peer table. This function can also be used with some other frames 6538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * like Provision Discovery Request that contains P2P Capability and P2P Device 6548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * Info attributes. 6558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */ 656a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidtint p2p_add_device(struct p2p_data *p2p, const u8 *addr, int freq, 657f86232838cf712377867cb42417c1613ab5dc425Dmitry Shmidt struct os_time *rx_time, int level, const u8 *ies, 658a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt size_t ies_len, int scan_res) 6598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 6608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct p2p_device *dev; 6618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct p2p_message msg; 6628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt const u8 *p2p_dev_addr; 6638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt int i; 664f86232838cf712377867cb42417c1613ab5dc425Dmitry Shmidt struct os_time time_now; 6658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 6668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memset(&msg, 0, sizeof(msg)); 6678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (p2p_parse_ies(ies, ies_len, &msg)) { 6688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG, 6698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "P2P: Failed to parse P2P IE for a device entry"); 6708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_parse_free(&msg); 6718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 6728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 6738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 6748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (msg.p2p_device_addr) 6758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_dev_addr = msg.p2p_device_addr; 6768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt else if (msg.device_id) 6778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_dev_addr = msg.device_id; 6788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt else { 6798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG, 6808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "P2P: Ignore scan data without P2P Device Info or " 6818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "P2P Device Id"); 6828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_parse_free(&msg); 6838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 6848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 6858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 6868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (!is_zero_ether_addr(p2p->peer_filter) && 6878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memcmp(p2p_dev_addr, p2p->peer_filter, ETH_ALEN) != 0) { 6888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG, "P2P: Do not add peer " 6898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "filter for " MACSTR " due to peer filter", 6908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt MAC2STR(p2p_dev_addr)); 691a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt p2p_parse_free(&msg); 6928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 6938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 6948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 6958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt dev = p2p_create_device(p2p, p2p_dev_addr); 6968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (dev == NULL) { 6978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_parse_free(&msg); 6988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 6998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 700a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt 701f86232838cf712377867cb42417c1613ab5dc425Dmitry Shmidt if (rx_time == NULL) { 702f86232838cf712377867cb42417c1613ab5dc425Dmitry Shmidt os_get_time(&time_now); 703f86232838cf712377867cb42417c1613ab5dc425Dmitry Shmidt rx_time = &time_now; 704f86232838cf712377867cb42417c1613ab5dc425Dmitry Shmidt } 705a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt 706a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt /* 707a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt * Update the device entry only if the new peer 708a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt * entry is newer than the one previously stored. 709a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt */ 710f86232838cf712377867cb42417c1613ab5dc425Dmitry Shmidt if (dev->last_seen.sec > 0 && 711f86232838cf712377867cb42417c1613ab5dc425Dmitry Shmidt os_time_before(rx_time, &dev->last_seen)) { 712f86232838cf712377867cb42417c1613ab5dc425Dmitry Shmidt wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG, "P2P: Do not update peer " 713f86232838cf712377867cb42417c1613ab5dc425Dmitry Shmidt "entry based on old frame (rx_time=%u.%06u " 714f86232838cf712377867cb42417c1613ab5dc425Dmitry Shmidt "last_seen=%u.%06u)", 715f86232838cf712377867cb42417c1613ab5dc425Dmitry Shmidt (unsigned int) rx_time->sec, 716f86232838cf712377867cb42417c1613ab5dc425Dmitry Shmidt (unsigned int) rx_time->usec, 717f86232838cf712377867cb42417c1613ab5dc425Dmitry Shmidt (unsigned int) dev->last_seen.sec, 718f86232838cf712377867cb42417c1613ab5dc425Dmitry Shmidt (unsigned int) dev->last_seen.usec); 719a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt p2p_parse_free(&msg); 720a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt return -1; 721a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt } 722a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt 723f86232838cf712377867cb42417c1613ab5dc425Dmitry Shmidt os_memcpy(&dev->last_seen, rx_time, sizeof(struct os_time)); 724a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt 7258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt dev->flags &= ~(P2P_DEV_PROBE_REQ_ONLY | P2P_DEV_GROUP_CLIENT_ONLY); 7268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 7278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (os_memcmp(addr, p2p_dev_addr, ETH_ALEN) != 0) 7288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memcpy(dev->interface_addr, addr, ETH_ALEN); 7298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (msg.ssid && 7308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt (msg.ssid[1] != P2P_WILDCARD_SSID_LEN || 7318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memcmp(msg.ssid + 2, P2P_WILDCARD_SSID, P2P_WILDCARD_SSID_LEN) 7328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt != 0)) { 7338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memcpy(dev->oper_ssid, msg.ssid + 2, msg.ssid[1]); 7348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt dev->oper_ssid_len = msg.ssid[1]; 7358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 7368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 7378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (freq >= 2412 && freq <= 2484 && msg.ds_params && 7388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt *msg.ds_params >= 1 && *msg.ds_params <= 14) { 7398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt int ds_freq; 7408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (*msg.ds_params == 14) 7418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ds_freq = 2484; 7428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt else 7438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ds_freq = 2407 + *msg.ds_params * 5; 7448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (freq != ds_freq) { 7458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG, 7468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "P2P: Update Listen frequency based on DS " 7478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "Parameter Set IE: %d -> %d MHz", 7488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt freq, ds_freq); 7498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt freq = ds_freq; 7508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 7518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 7528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 75304949598a23f501be6eec21697465fd46a28840aDmitry Shmidt if (dev->listen_freq && dev->listen_freq != freq && scan_res) { 7548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG, 7558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "P2P: Update Listen frequency based on scan " 7568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "results (" MACSTR " %d -> %d MHz (DS param %d)", 7578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt MAC2STR(dev->info.p2p_device_addr), dev->listen_freq, 7588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt freq, msg.ds_params ? *msg.ds_params : -1); 7598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 76004949598a23f501be6eec21697465fd46a28840aDmitry Shmidt if (scan_res) { 76104949598a23f501be6eec21697465fd46a28840aDmitry Shmidt dev->listen_freq = freq; 76204949598a23f501be6eec21697465fd46a28840aDmitry Shmidt if (msg.group_info) 76304949598a23f501be6eec21697465fd46a28840aDmitry Shmidt dev->oper_freq = freq; 76404949598a23f501be6eec21697465fd46a28840aDmitry Shmidt } 76575ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen dev->info.level = level; 7668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 7678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_copy_wps_info(dev, 0, &msg); 7688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 7698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt for (i = 0; i < P2P_MAX_WPS_VENDOR_EXT; i++) { 7708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpabuf_free(dev->info.wps_vendor_ext[i]); 7718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt dev->info.wps_vendor_ext[i] = NULL; 7728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 7738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 7748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt for (i = 0; i < P2P_MAX_WPS_VENDOR_EXT; i++) { 7758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (msg.wps_vendor_ext[i] == NULL) 7768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 7778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt dev->info.wps_vendor_ext[i] = wpabuf_alloc_copy( 7788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt msg.wps_vendor_ext[i], msg.wps_vendor_ext_len[i]); 7798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (dev->info.wps_vendor_ext[i] == NULL) 7808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 7818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 7828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 78361d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt if (msg.wfd_subelems) { 78461d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt wpabuf_free(dev->info.wfd_subelems); 78561d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt dev->info.wfd_subelems = wpabuf_dup(msg.wfd_subelems); 78661d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt } 78761d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt 78804949598a23f501be6eec21697465fd46a28840aDmitry Shmidt if (scan_res) { 78904949598a23f501be6eec21697465fd46a28840aDmitry Shmidt p2p_add_group_clients(p2p, p2p_dev_addr, addr, freq, 79004949598a23f501be6eec21697465fd46a28840aDmitry Shmidt msg.group_info, msg.group_info_len); 79104949598a23f501be6eec21697465fd46a28840aDmitry Shmidt } 7928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 7938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_parse_free(&msg); 7948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 7958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (p2p_pending_sd_req(p2p, dev)) 7968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt dev->flags |= P2P_DEV_SD_SCHEDULE; 7978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 7988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (dev->flags & P2P_DEV_REPORTED) 7998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 8008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 8018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG, 802f86232838cf712377867cb42417c1613ab5dc425Dmitry Shmidt "P2P: Peer found with Listen frequency %d MHz " 803f86232838cf712377867cb42417c1613ab5dc425Dmitry Shmidt "(rx_time=%u.%06u)", freq, (unsigned int) rx_time->sec, 804f86232838cf712377867cb42417c1613ab5dc425Dmitry Shmidt (unsigned int) rx_time->usec); 8058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (dev->flags & P2P_DEV_USER_REJECTED) { 8068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG, 8078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "P2P: Do not report rejected device"); 8088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 8098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 8108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 811f86232838cf712377867cb42417c1613ab5dc425Dmitry Shmidt if (dev->info.config_methods == 0 && 812f86232838cf712377867cb42417c1613ab5dc425Dmitry Shmidt (freq == 2412 || freq == 2437 || freq == 2462)) { 813f86232838cf712377867cb42417c1613ab5dc425Dmitry Shmidt /* 814f86232838cf712377867cb42417c1613ab5dc425Dmitry Shmidt * If we have only seen a Beacon frame from a GO, we do not yet 815f86232838cf712377867cb42417c1613ab5dc425Dmitry Shmidt * know what WPS config methods it supports. Since some 816f86232838cf712377867cb42417c1613ab5dc425Dmitry Shmidt * applications use config_methods value from P2P-DEVICE-FOUND 817f86232838cf712377867cb42417c1613ab5dc425Dmitry Shmidt * events, postpone reporting this peer until we've fully 818f86232838cf712377867cb42417c1613ab5dc425Dmitry Shmidt * discovered its capabilities. 819f86232838cf712377867cb42417c1613ab5dc425Dmitry Shmidt * 820f86232838cf712377867cb42417c1613ab5dc425Dmitry Shmidt * At least for now, do this only if the peer was detected on 821f86232838cf712377867cb42417c1613ab5dc425Dmitry Shmidt * one of the social channels since that peer can be easily be 822f86232838cf712377867cb42417c1613ab5dc425Dmitry Shmidt * found again and there are no limitations of having to use 823f86232838cf712377867cb42417c1613ab5dc425Dmitry Shmidt * passive scan on this channels, so this can be done through 824f86232838cf712377867cb42417c1613ab5dc425Dmitry Shmidt * Probe Response frame that includes the config_methods 825f86232838cf712377867cb42417c1613ab5dc425Dmitry Shmidt * information. 826f86232838cf712377867cb42417c1613ab5dc425Dmitry Shmidt */ 827f86232838cf712377867cb42417c1613ab5dc425Dmitry Shmidt wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG, 828f86232838cf712377867cb42417c1613ab5dc425Dmitry Shmidt "P2P: Do not report peer " MACSTR " with unknown " 829f86232838cf712377867cb42417c1613ab5dc425Dmitry Shmidt "config methods", MAC2STR(addr)); 830f86232838cf712377867cb42417c1613ab5dc425Dmitry Shmidt return 0; 831f86232838cf712377867cb42417c1613ab5dc425Dmitry Shmidt } 832f86232838cf712377867cb42417c1613ab5dc425Dmitry Shmidt 8338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p->cfg->dev_found(p2p->cfg->cb_ctx, addr, &dev->info, 8348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt !(dev->flags & P2P_DEV_REPORTED_ONCE)); 8358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt dev->flags |= P2P_DEV_REPORTED | P2P_DEV_REPORTED_ONCE; 8368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 8378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 8388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 8398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 8408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 8418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic void p2p_device_free(struct p2p_data *p2p, struct p2p_device *dev) 8428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 8438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt int i; 8448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 845497c1d5e50162d6b3c1cce5dbd9c5fd9da69aaefDmitry Shmidt if (p2p->go_neg_peer == dev) { 8461f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt /* 8471f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt * If GO Negotiation is in progress, report that it has failed. 8481f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt */ 849497c1d5e50162d6b3c1cce5dbd9c5fd9da69aaefDmitry Shmidt p2p_go_neg_failed(p2p, dev, -1); 8508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p->go_neg_peer = NULL; 851497c1d5e50162d6b3c1cce5dbd9c5fd9da69aaefDmitry Shmidt } 8528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (p2p->invite_peer == dev) 8538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p->invite_peer = NULL; 8548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (p2p->sd_peer == dev) 8558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p->sd_peer = NULL; 8568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (p2p->pending_client_disc_go == dev) 8578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p->pending_client_disc_go = NULL; 8588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 859c55524ad84d13014e8019491c2b17e5dcf13545aDmitry Shmidt /* dev_lost() device, but only if it was previously dev_found() */ 860c55524ad84d13014e8019491c2b17e5dcf13545aDmitry Shmidt if (dev->flags & P2P_DEV_REPORTED_ONCE) 861c55524ad84d13014e8019491c2b17e5dcf13545aDmitry Shmidt p2p->cfg->dev_lost(p2p->cfg->cb_ctx, 862c55524ad84d13014e8019491c2b17e5dcf13545aDmitry Shmidt dev->info.p2p_device_addr); 8638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 8648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt for (i = 0; i < P2P_MAX_WPS_VENDOR_EXT; i++) { 8658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpabuf_free(dev->info.wps_vendor_ext[i]); 8668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt dev->info.wps_vendor_ext[i] = NULL; 8678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 8688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 86961d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt wpabuf_free(dev->info.wfd_subelems); 87061d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt 8718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_free(dev); 8728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 8738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 8748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 8758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic int p2p_get_next_prog_freq(struct p2p_data *p2p) 8768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 8778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct p2p_channels *c; 8788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct p2p_reg_class *cla; 8798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt size_t cl, ch; 8808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt int found = 0; 8818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt u8 reg_class; 8828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt u8 channel; 8838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt int freq; 8848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 8858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt c = &p2p->cfg->channels; 8868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt for (cl = 0; cl < c->reg_classes; cl++) { 8878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt cla = &c->reg_class[cl]; 8888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (cla->reg_class != p2p->last_prog_scan_class) 8898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt continue; 8908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt for (ch = 0; ch < cla->channels; ch++) { 8918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (cla->channel[ch] == p2p->last_prog_scan_chan) { 8928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt found = 1; 8938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 8948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 8958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 8968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (found) 8978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 8988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 8998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 9008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (!found) { 9018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* Start from beginning */ 9028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt reg_class = c->reg_class[0].reg_class; 9038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt channel = c->reg_class[0].channel[0]; 9048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } else { 9058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* Pick the next channel */ 9068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ch++; 9078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (ch == cla->channels) { 9088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt cl++; 9098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (cl == c->reg_classes) 9108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt cl = 0; 9118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ch = 0; 9128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 9138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt reg_class = c->reg_class[cl].reg_class; 9148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt channel = c->reg_class[cl].channel[ch]; 9158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 9168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 9178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt freq = p2p_channel_to_freq(p2p->cfg->country, reg_class, channel); 9188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG, "P2P: Next progressive search " 9198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "channel: reg_class %u channel %u -> %d MHz", 9208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt reg_class, channel, freq); 9218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p->last_prog_scan_class = reg_class; 9228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p->last_prog_scan_chan = channel; 9238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 9248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (freq == 2412 || freq == 2437 || freq == 2462) 9258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; /* No need to add social channels */ 9268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return freq; 9278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 9288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 9298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 9308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic void p2p_search(struct p2p_data *p2p) 9318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 9328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt int freq = 0; 9338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt enum p2p_scan_type type; 93404949598a23f501be6eec21697465fd46a28840aDmitry Shmidt u16 pw_id = DEV_PW_DEFAULT; 93561d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt int res; 9368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 9378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (p2p->drv_in_listen) { 9388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG, "P2P: Driver is still " 9398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "in Listen state - wait for it to end before " 9408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "continuing"); 9418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; 9428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 9438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p->cfg->stop_listen(p2p->cfg->cb_ctx); 9448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 94504949598a23f501be6eec21697465fd46a28840aDmitry Shmidt if (p2p->find_type == P2P_FIND_PROGRESSIVE && 94604949598a23f501be6eec21697465fd46a28840aDmitry Shmidt (freq = p2p_get_next_prog_freq(p2p)) > 0) { 9478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt type = P2P_SCAN_SOCIAL_PLUS_ONE; 9488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG, "P2P: Starting search " 9498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "(+ freq %u)", freq); 9508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } else { 9518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt type = P2P_SCAN_SOCIAL; 9528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG, "P2P: Starting search"); 9538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 9548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 95561d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt res = p2p->cfg->p2p_scan(p2p->cfg->cb_ctx, type, freq, 95661d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt p2p->num_req_dev_types, p2p->req_dev_types, 95761d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt p2p->find_dev_id, pw_id); 95861d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt if (res < 0) { 9598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG, 9608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "P2P: Scan request failed"); 9618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_continue_find(p2p); 96261d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt } else if (res == 1) { 96361d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG, "P2P: Could not start " 96461d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt "p2p_scan at this point - will try again after " 96561d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt "previous scan completes"); 96661d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt p2p_set_state(p2p, P2P_CONTINUE_SEARCH_WHEN_READY); 9678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } else { 9688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG, "P2P: Running p2p_scan"); 9698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p->p2p_scan_running = 1; 9708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt eloop_cancel_timeout(p2p_scan_timeout, p2p, NULL); 9718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt eloop_register_timeout(P2P_SCAN_TIMEOUT, 0, p2p_scan_timeout, 9728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p, NULL); 9738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 9748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 9758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 9768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 9778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic void p2p_find_timeout(void *eloop_ctx, void *timeout_ctx) 9788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 9798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct p2p_data *p2p = eloop_ctx; 9808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG, "P2P: Find timeout -> stop"); 9818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_stop_find(p2p); 9828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 9838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 9848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 9858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic int p2p_run_after_scan(struct p2p_data *p2p) 9868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 9878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct p2p_device *dev; 9888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt enum p2p_after_scan op; 9898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 9908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (p2p->after_scan_tx) { 9918da800a193fb6f8832218715f82a7b4e2d2ad338Dmitry Shmidt p2p->after_scan_tx_in_progress = 1; 9928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG, "P2P: Send pending " 9938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "Action frame at p2p_scan completion"); 9941f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt p2p->cfg->send_action(p2p->cfg->cb_ctx, 9951f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt p2p->after_scan_tx->freq, 9961f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt p2p->after_scan_tx->dst, 9971f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt p2p->after_scan_tx->src, 9981f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt p2p->after_scan_tx->bssid, 9991f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt (u8 *) (p2p->after_scan_tx + 1), 10001f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt p2p->after_scan_tx->len, 10011f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt p2p->after_scan_tx->wait_time); 10028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_free(p2p->after_scan_tx); 10038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p->after_scan_tx = NULL; 1004f44b9c4a18d17fbd39901f76a014c32006570fb8Irfan Sheriff#ifdef ANDROID_P2P 1005f44b9c4a18d17fbd39901f76a014c32006570fb8Irfan Sheriff /* For SD frames, there is a scenario, where we can receive a SD request frame during p2p_scan. 1006f44b9c4a18d17fbd39901f76a014c32006570fb8Irfan Sheriff * At that moment, we will send the SD response from this context. After sending the SD response, 1007f44b9c4a18d17fbd39901f76a014c32006570fb8Irfan Sheriff * we need to continue p2p_find. But if we return 1 from here, p2p_find is going to be stopped. 1008f44b9c4a18d17fbd39901f76a014c32006570fb8Irfan Sheriff */ 1009f44b9c4a18d17fbd39901f76a014c32006570fb8Irfan Sheriff return 0; 1010f44b9c4a18d17fbd39901f76a014c32006570fb8Irfan Sheriff#else 10118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 1; 1012f44b9c4a18d17fbd39901f76a014c32006570fb8Irfan Sheriff#endif 10138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 10148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 10158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt op = p2p->start_after_scan; 10168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p->start_after_scan = P2P_AFTER_SCAN_NOTHING; 10178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt switch (op) { 10188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case P2P_AFTER_SCAN_NOTHING: 10198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 10208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case P2P_AFTER_SCAN_LISTEN: 10218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG, "P2P: Start previously " 10228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "requested Listen state"); 10238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_listen(p2p, p2p->pending_listen_sec * 1000 + 10248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p->pending_listen_usec / 1000); 10258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 1; 10268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case P2P_AFTER_SCAN_CONNECT: 10278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG, "P2P: Start previously " 10288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "requested connect with " MACSTR, 10298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt MAC2STR(p2p->after_scan_peer)); 10308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt dev = p2p_get_device(p2p, p2p->after_scan_peer); 10318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (dev == NULL) { 10328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG, "P2P: Peer not " 10338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "known anymore"); 10348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 10358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 10368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_connect_send(p2p, dev); 10378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 1; 10388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 10398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 10408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 10418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 10428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 10438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 10448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic void p2p_scan_timeout(void *eloop_ctx, void *timeout_ctx) 10458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 10468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct p2p_data *p2p = eloop_ctx; 10478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt int running; 10488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG, "P2P: p2p_scan timeout " 10498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "(running=%d)", p2p->p2p_scan_running); 10508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt running = p2p->p2p_scan_running; 10518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* Make sure we recover from missed scan results callback */ 10528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p->p2p_scan_running = 0; 10538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 10548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (running) 10558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_run_after_scan(p2p); 10568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 10578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 10588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 10598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic void p2p_free_req_dev_types(struct p2p_data *p2p) 10608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 10618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p->num_req_dev_types = 0; 10628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_free(p2p->req_dev_types); 10638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p->req_dev_types = NULL; 10648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 10658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 10668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 10678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtint p2p_find(struct p2p_data *p2p, unsigned int timeout, 10688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt enum p2p_discovery_type type, 1069c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt unsigned int num_req_dev_types, const u8 *req_dev_types, 107061d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt const u8 *dev_id, unsigned int search_delay) 10718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 10728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt int res; 10738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 10748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG, "P2P: Starting find (type=%d)", 10758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt type); 1076f86232838cf712377867cb42417c1613ab5dc425Dmitry Shmidt os_get_time(&p2p->find_start); 10778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (p2p->p2p_scan_running) { 10788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG, "P2P: p2p_scan is " 10798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "already running"); 10808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 10818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 10828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_free_req_dev_types(p2p); 10838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (req_dev_types && num_req_dev_types) { 10848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p->req_dev_types = os_malloc(num_req_dev_types * 10858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt WPS_DEV_TYPE_LEN); 10868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (p2p->req_dev_types == NULL) 10878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 10888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memcpy(p2p->req_dev_types, req_dev_types, 10898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt num_req_dev_types * WPS_DEV_TYPE_LEN); 10908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p->num_req_dev_types = num_req_dev_types; 10918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 10928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1093c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt if (dev_id) { 1094c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt os_memcpy(p2p->find_dev_id_buf, dev_id, ETH_ALEN); 1095c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt p2p->find_dev_id = p2p->find_dev_id_buf; 1096c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt } else 1097c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt p2p->find_dev_id = NULL; 1098c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt 10998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p->start_after_scan = P2P_AFTER_SCAN_NOTHING; 11008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_clear_timeout(p2p); 11018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p->cfg->stop_listen(p2p->cfg->cb_ctx); 11028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p->find_type = type; 11038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_device_clear_reported(p2p); 11048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_set_state(p2p, P2P_SEARCH); 110561d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt p2p->search_delay = search_delay; 110661d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt p2p->in_search_delay = 0; 11078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt eloop_cancel_timeout(p2p_find_timeout, p2p, NULL); 11081f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt p2p->last_p2p_find_timeout = timeout; 11098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (timeout) 11108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt eloop_register_timeout(timeout, 0, p2p_find_timeout, 11118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p, NULL); 11128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt switch (type) { 11138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case P2P_FIND_START_WITH_FULL: 11148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case P2P_FIND_PROGRESSIVE: 11158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt res = p2p->cfg->p2p_scan(p2p->cfg->cb_ctx, P2P_SCAN_FULL, 0, 11168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p->num_req_dev_types, 111704949598a23f501be6eec21697465fd46a28840aDmitry Shmidt p2p->req_dev_types, dev_id, 111804949598a23f501be6eec21697465fd46a28840aDmitry Shmidt DEV_PW_DEFAULT); 11198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 11208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case P2P_FIND_ONLY_SOCIAL: 11218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt res = p2p->cfg->p2p_scan(p2p->cfg->cb_ctx, P2P_SCAN_SOCIAL, 0, 11228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p->num_req_dev_types, 112304949598a23f501be6eec21697465fd46a28840aDmitry Shmidt p2p->req_dev_types, dev_id, 112404949598a23f501be6eec21697465fd46a28840aDmitry Shmidt DEV_PW_DEFAULT); 11258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 11268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt default: 11278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 11288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 11298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 11308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (res == 0) { 11318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG, "P2P: Running p2p_scan"); 11328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p->p2p_scan_running = 1; 11338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt eloop_cancel_timeout(p2p_scan_timeout, p2p, NULL); 11348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt eloop_register_timeout(P2P_SCAN_TIMEOUT, 0, p2p_scan_timeout, 11358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p, NULL); 11361f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt } else if (res == 1) { 11371f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG, "P2P: Could not start " 11381f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt "p2p_scan at this point - will try again after " 11391f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt "previous scan completes"); 11401f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt res = 0; 11411f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt p2p_set_state(p2p, P2P_SEARCH_WHEN_READY); 11421f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt eloop_cancel_timeout(p2p_find_timeout, p2p, NULL); 11438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } else { 11448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG, "P2P: Failed to start " 11458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "p2p_scan"); 11461f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt p2p_set_state(p2p, P2P_IDLE); 11471f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt eloop_cancel_timeout(p2p_find_timeout, p2p, NULL); 11488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 11498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 11508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return res; 11518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 11528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 11532fb777c379ad560c309c54b96c2c13291da23f54Dmitry Shmidt#ifdef ANDROID_P2P 11542fb777c379ad560c309c54b96c2c13291da23f54Dmitry Shmidtint p2p_search_pending(struct p2p_data *p2p) 11552fb777c379ad560c309c54b96c2c13291da23f54Dmitry Shmidt{ 11562fb777c379ad560c309c54b96c2c13291da23f54Dmitry Shmidt if(p2p == NULL) 11572fb777c379ad560c309c54b96c2c13291da23f54Dmitry Shmidt return 0; 11582fb777c379ad560c309c54b96c2c13291da23f54Dmitry Shmidt 11592fb777c379ad560c309c54b96c2c13291da23f54Dmitry Shmidt if(p2p->state == P2P_SEARCH_WHEN_READY) 11602fb777c379ad560c309c54b96c2c13291da23f54Dmitry Shmidt return 1; 11612fb777c379ad560c309c54b96c2c13291da23f54Dmitry Shmidt 11622fb777c379ad560c309c54b96c2c13291da23f54Dmitry Shmidt return 0; 11632fb777c379ad560c309c54b96c2c13291da23f54Dmitry Shmidt} 11642fb777c379ad560c309c54b96c2c13291da23f54Dmitry Shmidt#endif 11658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 11661f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidtint p2p_other_scan_completed(struct p2p_data *p2p) 11671f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt{ 116861d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt if (p2p->state == P2P_CONTINUE_SEARCH_WHEN_READY) { 116961d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt p2p_set_state(p2p, P2P_SEARCH); 117061d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt p2p_search(p2p); 117161d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt return 1; 117261d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt } 11731f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt if (p2p->state != P2P_SEARCH_WHEN_READY) 11741f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt return 0; 11751f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG, "P2P: Starting pending P2P find " 11761f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt "now that previous scan was completed"); 11771f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt if (p2p_find(p2p, p2p->last_p2p_find_timeout, p2p->find_type, 1178c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt p2p->num_req_dev_types, p2p->req_dev_types, 1179f86232838cf712377867cb42417c1613ab5dc425Dmitry Shmidt p2p->find_dev_id, p2p->search_delay) < 0) { 1180f86232838cf712377867cb42417c1613ab5dc425Dmitry Shmidt wpa_msg(p2p->cfg->msg_ctx, MSG_INFO, P2P_EVENT_FIND_STOPPED); 11811f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt return 0; 1182f86232838cf712377867cb42417c1613ab5dc425Dmitry Shmidt } 11831f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt return 1; 11841f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt} 11851f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt 11861f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt 11878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtvoid p2p_stop_find_for_freq(struct p2p_data *p2p, int freq) 11888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 11898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG, "P2P: Stopping find"); 11908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt eloop_cancel_timeout(p2p_find_timeout, p2p, NULL); 11918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_clear_timeout(p2p); 1192a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt if (p2p->state == P2P_SEARCH || 1193a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt p2p->state == P2P_CONTINUE_SEARCH_WHEN_READY || 1194a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt p2p->state == P2P_SEARCH_WHEN_READY) 1195c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt wpa_msg(p2p->cfg->msg_ctx, MSG_INFO, P2P_EVENT_FIND_STOPPED); 11968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_set_state(p2p, P2P_IDLE); 11978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_free_req_dev_types(p2p); 11988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p->start_after_scan = P2P_AFTER_SCAN_NOTHING; 11998c65289885e84727226d81b3d32856f79c31ee5fDmitry Shmidt if (p2p->go_neg_peer) 12008c65289885e84727226d81b3d32856f79c31ee5fDmitry Shmidt p2p->go_neg_peer->flags &= ~P2P_DEV_PEER_WAITING_RESPONSE; 12018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p->go_neg_peer = NULL; 12028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p->sd_peer = NULL; 12038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p->invite_peer = NULL; 120404949598a23f501be6eec21697465fd46a28840aDmitry Shmidt p2p_stop_listen_for_freq(p2p, freq); 120504949598a23f501be6eec21697465fd46a28840aDmitry Shmidt} 120604949598a23f501be6eec21697465fd46a28840aDmitry Shmidt 120704949598a23f501be6eec21697465fd46a28840aDmitry Shmidt 120804949598a23f501be6eec21697465fd46a28840aDmitry Shmidtvoid p2p_stop_listen_for_freq(struct p2p_data *p2p, int freq) 120904949598a23f501be6eec21697465fd46a28840aDmitry Shmidt{ 12108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (freq > 0 && p2p->drv_in_listen == freq && p2p->in_listen) { 12118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG, "P2P: Skip stop_listen " 12128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "since we are on correct channel for response"); 12138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; 12148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 121504949598a23f501be6eec21697465fd46a28840aDmitry Shmidt if (p2p->in_listen) { 121604949598a23f501be6eec21697465fd46a28840aDmitry Shmidt p2p->in_listen = 0; 121704949598a23f501be6eec21697465fd46a28840aDmitry Shmidt p2p_clear_timeout(p2p); 121804949598a23f501be6eec21697465fd46a28840aDmitry Shmidt } 12191f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt if (p2p->drv_in_listen) { 12201f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt /* 12211f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt * The driver may not deliver callback to p2p_listen_end() 12221f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt * when the operation gets canceled, so clear the internal 12231f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt * variable that is tracking driver state. 12241f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt */ 12251f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG, "P2P: Clear " 12261f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt "drv_in_listen (%d)", p2p->drv_in_listen); 12271f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt p2p->drv_in_listen = 0; 12281f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt } 12298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p->cfg->stop_listen(p2p->cfg->cb_ctx); 12308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 12318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 12328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 12338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtvoid p2p_stop_find(struct p2p_data *p2p) 12348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 12358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_stop_find_for_freq(p2p, 0); 12368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 12378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 12388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1239a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidtstatic int p2p_prepare_channel_pref(struct p2p_data *p2p, 1240a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt unsigned int force_freq, 1241a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt unsigned int pref_freq) 12428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 1243a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt u8 op_class, op_channel; 1244a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt unsigned int freq = force_freq ? force_freq : pref_freq; 12458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1246a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt if (p2p_freq_to_channel(p2p->cfg->country, freq, 1247a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt &op_class, &op_channel) < 0) { 1248a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG, 1249a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt "P2P: Unsupported frequency %u MHz", freq); 1250a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt return -1; 1251a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt } 1252a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt 1253a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt if (!p2p_channels_includes(&p2p->cfg->channels, op_class, op_channel)) { 1254a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG, 1255a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt "P2P: Frequency %u MHz (oper_class %u channel %u) not " 1256a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt "allowed for P2P", freq, op_class, op_channel); 1257a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt return -1; 1258a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt } 1259a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt 1260a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt p2p->op_reg_class = op_class; 1261a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt p2p->op_channel = op_channel; 12628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1263a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt if (force_freq) { 1264a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt p2p->channels.reg_classes = 1; 1265a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt p2p->channels.reg_class[0].channels = 1; 1266a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt p2p->channels.reg_class[0].reg_class = p2p->op_reg_class; 1267a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt p2p->channels.reg_class[0].channel[0] = p2p->op_channel; 1268a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt } else { 12698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memcpy(&p2p->channels, &p2p->cfg->channels, 12708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sizeof(struct p2p_channels)); 12718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 1272a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt 1273a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt return 0; 1274a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt} 1275a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt 1276a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt 1277a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidtstatic void p2p_prepare_channel_best(struct p2p_data *p2p) 1278a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt{ 1279a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt u8 op_class, op_channel; 1280a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt 1281a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt if (!p2p->cfg->cfg_op_channel && p2p->best_freq_overall > 0 && 1282a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt p2p_supported_freq(p2p, p2p->best_freq_overall) && 1283a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt p2p_freq_to_channel(p2p->cfg->country, p2p->best_freq_overall, 1284a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt &op_class, &op_channel) == 0) { 1285a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG, "P2P: Select best " 1286a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt "overall channel as operating channel preference"); 1287a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt p2p->op_reg_class = op_class; 1288a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt p2p->op_channel = op_channel; 1289a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt } else if (!p2p->cfg->cfg_op_channel && p2p->best_freq_5 > 0 && 1290a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt p2p_supported_freq(p2p, p2p->best_freq_5) && 1291a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt p2p_freq_to_channel(p2p->cfg->country, p2p->best_freq_5, 1292a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt &op_class, &op_channel) == 0) { 1293a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG, "P2P: Select best 5 GHz " 1294a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt "channel as operating channel preference"); 1295a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt p2p->op_reg_class = op_class; 1296a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt p2p->op_channel = op_channel; 1297a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt } else if (!p2p->cfg->cfg_op_channel && p2p->best_freq_24 > 0 && 1298a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt p2p_supported_freq(p2p, p2p->best_freq_24) && 1299a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt p2p_freq_to_channel(p2p->cfg->country, p2p->best_freq_24, 1300a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt &op_class, &op_channel) == 0) { 1301a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG, "P2P: Select best 2.4 " 1302a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt "GHz channel as operating channel preference"); 1303a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt p2p->op_reg_class = op_class; 1304a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt p2p->op_channel = op_channel; 1305a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt } else { 1306a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt p2p->op_reg_class = p2p->cfg->op_reg_class; 1307a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt p2p->op_channel = p2p->cfg->op_channel; 1308a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt } 1309a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt 1310a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt os_memcpy(&p2p->channels, &p2p->cfg->channels, 1311a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt sizeof(struct p2p_channels)); 1312a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt} 1313a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt 1314a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt 1315a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt/** 1316a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt * p2p_prepare_channel - Select operating channel for GO Negotiation 1317a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt * @p2p: P2P module context from p2p_init() 1318a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt * @dev: Selected peer device 1319a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt * @force_freq: Forced frequency in MHz or 0 if not forced 1320a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt * @pref_freq: Preferred frequency in MHz or 0 if no preference 1321a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt * Returns: 0 on success, -1 on failure (channel not supported for P2P) 1322a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt * 1323a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt * This function is used to do initial operating channel selection for GO 1324a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt * Negotiation prior to having received peer information. The selected channel 1325a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt * may be further optimized in p2p_reselect_channel() once the peer information 1326a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt * is available. 1327a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt */ 13287a5e50a0554bee77a9da492ea3d86f46147f1671Dmitry Shmidtint p2p_prepare_channel(struct p2p_data *p2p, struct p2p_device *dev, 13297a5e50a0554bee77a9da492ea3d86f46147f1671Dmitry Shmidt unsigned int force_freq, unsigned int pref_freq) 1330a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt{ 1331a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt if (force_freq || pref_freq) { 1332a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt if (p2p_prepare_channel_pref(p2p, force_freq, pref_freq) < 0) 1333a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt return -1; 1334a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt } else { 1335a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt p2p_prepare_channel_best(p2p); 1336a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt } 13378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG, 13388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "P2P: Own preference for operation channel: " 13398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "Operating Class %u Channel %u%s", 13408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p->op_reg_class, p2p->op_channel, 13418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt force_freq ? " (forced)" : ""); 13428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1343a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt if (force_freq) 1344a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt dev->flags |= P2P_DEV_FORCE_FREQ; 1345a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt else 1346a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt dev->flags &= ~P2P_DEV_FORCE_FREQ; 1347a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt 13488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 13498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 13508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 13518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 13521f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidtstatic void p2p_set_dev_persistent(struct p2p_device *dev, 13531f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt int persistent_group) 13541f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt{ 13551f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt switch (persistent_group) { 13561f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt case 0: 13571f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt dev->flags &= ~(P2P_DEV_PREFER_PERSISTENT_GROUP | 13581f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt P2P_DEV_PREFER_PERSISTENT_RECONN); 13591f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt break; 13601f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt case 1: 13611f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt dev->flags |= P2P_DEV_PREFER_PERSISTENT_GROUP; 13621f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt dev->flags &= ~P2P_DEV_PREFER_PERSISTENT_RECONN; 13631f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt break; 13641f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt case 2: 13651f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt dev->flags |= P2P_DEV_PREFER_PERSISTENT_GROUP | 13661f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt P2P_DEV_PREFER_PERSISTENT_RECONN; 13671f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt break; 13681f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt } 13691f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt} 13701f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt 13711f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt 13728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtint p2p_connect(struct p2p_data *p2p, const u8 *peer_addr, 13738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt enum p2p_wps_method wps_method, 13748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt int go_intent, const u8 *own_interface_addr, 137504949598a23f501be6eec21697465fd46a28840aDmitry Shmidt unsigned int force_freq, int persistent_group, 137604949598a23f501be6eec21697465fd46a28840aDmitry Shmidt const u8 *force_ssid, size_t force_ssid_len, 1377d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt int pd_before_go_neg, unsigned int pref_freq) 13788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 13798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct p2p_device *dev; 13808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 13818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG, 13828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "P2P: Request to start group negotiation - peer=" MACSTR 13838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt " GO Intent=%d Intended Interface Address=" MACSTR 1384d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt " wps_method=%d persistent_group=%d pd_before_go_neg=%d", 13858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt MAC2STR(peer_addr), go_intent, MAC2STR(own_interface_addr), 1386d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt wps_method, persistent_group, pd_before_go_neg); 13878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 13888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt dev = p2p_get_device(p2p, peer_addr); 13898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (dev == NULL || (dev->flags & P2P_DEV_PROBE_REQ_ONLY)) { 13908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG, 13918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "P2P: Cannot connect to unknown P2P Device " MACSTR, 13928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt MAC2STR(peer_addr)); 13938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 13948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 13958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1396a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt if (p2p_prepare_channel(p2p, dev, force_freq, pref_freq) < 0) 1397a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt return -1; 1398a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt 13998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (dev->flags & P2P_DEV_GROUP_CLIENT_ONLY) { 14008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (!(dev->info.dev_capab & 14018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt P2P_DEV_CAPAB_CLIENT_DISCOVERABILITY)) { 14028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG, 14038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "P2P: Cannot connect to P2P Device " MACSTR 14048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt " that is in a group and is not discoverable", 14058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt MAC2STR(peer_addr)); 14068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 14078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 14088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (dev->oper_freq <= 0) { 14098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG, 14108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "P2P: Cannot connect to P2P Device " MACSTR 14118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt " with incomplete information", 14128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt MAC2STR(peer_addr)); 14138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 14148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 14158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 14168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* 14178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * First, try to connect directly. If the peer does not 14188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * acknowledge frames, assume it is sleeping and use device 14198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * discoverability via the GO at that point. 14208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */ 14218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 14228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 142304949598a23f501be6eec21697465fd46a28840aDmitry Shmidt p2p->ssid_set = 0; 142404949598a23f501be6eec21697465fd46a28840aDmitry Shmidt if (force_ssid) { 142504949598a23f501be6eec21697465fd46a28840aDmitry Shmidt wpa_hexdump_ascii(MSG_DEBUG, "P2P: Forced SSID", 142604949598a23f501be6eec21697465fd46a28840aDmitry Shmidt force_ssid, force_ssid_len); 142704949598a23f501be6eec21697465fd46a28840aDmitry Shmidt os_memcpy(p2p->ssid, force_ssid, force_ssid_len); 142804949598a23f501be6eec21697465fd46a28840aDmitry Shmidt p2p->ssid_len = force_ssid_len; 142904949598a23f501be6eec21697465fd46a28840aDmitry Shmidt p2p->ssid_set = 1; 143004949598a23f501be6eec21697465fd46a28840aDmitry Shmidt } 143104949598a23f501be6eec21697465fd46a28840aDmitry Shmidt 14328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt dev->flags &= ~P2P_DEV_NOT_YET_READY; 14338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt dev->flags &= ~P2P_DEV_USER_REJECTED; 14348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt dev->flags &= ~P2P_DEV_WAIT_GO_NEG_RESPONSE; 14358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt dev->flags &= ~P2P_DEV_WAIT_GO_NEG_CONFIRM; 143604949598a23f501be6eec21697465fd46a28840aDmitry Shmidt if (pd_before_go_neg) 143704949598a23f501be6eec21697465fd46a28840aDmitry Shmidt dev->flags |= P2P_DEV_PD_BEFORE_GO_NEG; 1438a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt else { 143904949598a23f501be6eec21697465fd46a28840aDmitry Shmidt dev->flags &= ~P2P_DEV_PD_BEFORE_GO_NEG; 1440a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt /* 14419cdf1b905fae57dea42506a1af67f6ece544b261Dmitry Shmidt * Assign dialog token and tie breaker here to use the same 14429cdf1b905fae57dea42506a1af67f6ece544b261Dmitry Shmidt * values in each retry within the same GO Negotiation exchange. 1443a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt */ 1444a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt dev->dialog_token++; 1445a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt if (dev->dialog_token == 0) 1446a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt dev->dialog_token = 1; 14479cdf1b905fae57dea42506a1af67f6ece544b261Dmitry Shmidt dev->tie_breaker = p2p->next_tie_breaker; 14489cdf1b905fae57dea42506a1af67f6ece544b261Dmitry Shmidt p2p->next_tie_breaker = !p2p->next_tie_breaker; 1449a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt } 14508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt dev->connect_reqs = 0; 14518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt dev->go_neg_req_sent = 0; 14528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt dev->go_state = UNKNOWN_GO; 14531f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt p2p_set_dev_persistent(dev, persistent_group); 14548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p->go_intent = go_intent; 14558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memcpy(p2p->intended_addr, own_interface_addr, ETH_ALEN); 14568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 14578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (p2p->state != P2P_IDLE) 14588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_stop_find(p2p); 14598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 14608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (p2p->after_scan_tx) { 14618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* 14628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * We need to drop the pending frame to avoid issues with the 14638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * new GO Negotiation, e.g., when the pending frame was from a 14648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * previous attempt at starting a GO Negotiation. 14658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */ 14668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG, "P2P: Dropped " 14678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "previous pending Action frame TX that was waiting " 14688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "for p2p_scan completion"); 14698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_free(p2p->after_scan_tx); 14708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p->after_scan_tx = NULL; 14718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 14728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 14738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt dev->wps_method = wps_method; 14748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt dev->status = P2P_SC_SUCCESS; 14758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 14768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (p2p->p2p_scan_running) { 14778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG, 14788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "P2P: p2p_scan running - delay connect send"); 14798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p->start_after_scan = P2P_AFTER_SCAN_CONNECT; 14808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memcpy(p2p->after_scan_peer, peer_addr, ETH_ALEN); 14818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 14828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 14838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p->start_after_scan = P2P_AFTER_SCAN_NOTHING; 14848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 14858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return p2p_connect_send(p2p, dev); 14868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 14878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 14888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 14898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtint p2p_authorize(struct p2p_data *p2p, const u8 *peer_addr, 14908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt enum p2p_wps_method wps_method, 14918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt int go_intent, const u8 *own_interface_addr, 149204949598a23f501be6eec21697465fd46a28840aDmitry Shmidt unsigned int force_freq, int persistent_group, 1493d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt const u8 *force_ssid, size_t force_ssid_len, 1494d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt unsigned int pref_freq) 14958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 14968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct p2p_device *dev; 14978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 14988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG, 14998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "P2P: Request to authorize group negotiation - peer=" MACSTR 15008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt " GO Intent=%d Intended Interface Address=" MACSTR 15018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt " wps_method=%d persistent_group=%d", 15028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt MAC2STR(peer_addr), go_intent, MAC2STR(own_interface_addr), 15038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wps_method, persistent_group); 15048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 15058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt dev = p2p_get_device(p2p, peer_addr); 15068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (dev == NULL) { 15078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG, 15088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "P2P: Cannot authorize unknown P2P Device " MACSTR, 15098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt MAC2STR(peer_addr)); 15108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 15118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 15128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1513a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt if (p2p_prepare_channel(p2p, dev, force_freq, pref_freq) < 0) 1514a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt return -1; 1515a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt 151604949598a23f501be6eec21697465fd46a28840aDmitry Shmidt p2p->ssid_set = 0; 151704949598a23f501be6eec21697465fd46a28840aDmitry Shmidt if (force_ssid) { 151804949598a23f501be6eec21697465fd46a28840aDmitry Shmidt wpa_hexdump_ascii(MSG_DEBUG, "P2P: Forced SSID", 151904949598a23f501be6eec21697465fd46a28840aDmitry Shmidt force_ssid, force_ssid_len); 152004949598a23f501be6eec21697465fd46a28840aDmitry Shmidt os_memcpy(p2p->ssid, force_ssid, force_ssid_len); 152104949598a23f501be6eec21697465fd46a28840aDmitry Shmidt p2p->ssid_len = force_ssid_len; 152204949598a23f501be6eec21697465fd46a28840aDmitry Shmidt p2p->ssid_set = 1; 152304949598a23f501be6eec21697465fd46a28840aDmitry Shmidt } 152404949598a23f501be6eec21697465fd46a28840aDmitry Shmidt 15258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt dev->flags &= ~P2P_DEV_NOT_YET_READY; 15268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt dev->flags &= ~P2P_DEV_USER_REJECTED; 15278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt dev->go_neg_req_sent = 0; 15288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt dev->go_state = UNKNOWN_GO; 15291f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt p2p_set_dev_persistent(dev, persistent_group); 15308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p->go_intent = go_intent; 15318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memcpy(p2p->intended_addr, own_interface_addr, ETH_ALEN); 15328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 15338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt dev->wps_method = wps_method; 15348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt dev->status = P2P_SC_SUCCESS; 15358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 15368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 15378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 15388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 15398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 15408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtvoid p2p_add_dev_info(struct p2p_data *p2p, const u8 *addr, 15418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct p2p_device *dev, struct p2p_message *msg) 15428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 15438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_get_time(&dev->last_seen); 15448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 15458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_copy_wps_info(dev, 0, msg); 15468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 15478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (msg->listen_channel) { 15488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt int freq; 15498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt freq = p2p_channel_to_freq((char *) msg->listen_channel, 15508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt msg->listen_channel[3], 15518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt msg->listen_channel[4]); 15528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (freq < 0) { 15538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG, 15548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "P2P: Unknown peer Listen channel: " 15558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "country=%c%c(0x%02x) reg_class=%u channel=%u", 15568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt msg->listen_channel[0], 15578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt msg->listen_channel[1], 15588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt msg->listen_channel[2], 15598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt msg->listen_channel[3], 15608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt msg->listen_channel[4]); 15618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } else { 15628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG, "P2P: Update " 15638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "peer " MACSTR " Listen channel: %u -> %u MHz", 15648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt MAC2STR(dev->info.p2p_device_addr), 15658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt dev->listen_freq, freq); 15668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt dev->listen_freq = freq; 15678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 15688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 15698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 157061d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt if (msg->wfd_subelems) { 157161d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt wpabuf_free(dev->info.wfd_subelems); 157261d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt dev->info.wfd_subelems = wpabuf_dup(msg->wfd_subelems); 157361d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt } 157461d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt 15758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (dev->flags & P2P_DEV_PROBE_REQ_ONLY) { 15768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt dev->flags &= ~P2P_DEV_PROBE_REQ_ONLY; 15778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG, 15788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "P2P: Completed device entry based on data from " 15798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "GO Negotiation Request"); 15808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } else { 15818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG, 15828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "P2P: Created device entry based on GO Neg Req: " 15838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt MACSTR " dev_capab=0x%x group_capab=0x%x name='%s' " 15848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "listen_freq=%d", 15858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt MAC2STR(dev->info.p2p_device_addr), 15868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt dev->info.dev_capab, dev->info.group_capab, 15878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt dev->info.device_name, dev->listen_freq); 15888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 15898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 15908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt dev->flags &= ~P2P_DEV_GROUP_CLIENT_ONLY; 15918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 15928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (dev->flags & P2P_DEV_USER_REJECTED) { 15938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG, 15948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "P2P: Do not report rejected device"); 15958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; 15968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 15978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 15988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p->cfg->dev_found(p2p->cfg->cb_ctx, addr, &dev->info, 15998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt !(dev->flags & P2P_DEV_REPORTED_ONCE)); 16008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt dev->flags |= P2P_DEV_REPORTED | P2P_DEV_REPORTED_ONCE; 16018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 16028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 16038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 16048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtvoid p2p_build_ssid(struct p2p_data *p2p, u8 *ssid, size_t *ssid_len) 16058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 16068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memcpy(ssid, P2P_WILDCARD_SSID, P2P_WILDCARD_SSID_LEN); 16078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_random((char *) &ssid[P2P_WILDCARD_SSID_LEN], 2); 16088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memcpy(&ssid[P2P_WILDCARD_SSID_LEN + 2], 16098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p->cfg->ssid_postfix, p2p->cfg->ssid_postfix_len); 16108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt *ssid_len = P2P_WILDCARD_SSID_LEN + 2 + p2p->cfg->ssid_postfix_len; 16118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 16128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 16138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 16148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtint p2p_go_params(struct p2p_data *p2p, struct p2p_go_neg_results *params) 16158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 16168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_build_ssid(p2p, params->ssid, ¶ms->ssid_len); 16178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_random(params->passphrase, 8); 16188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 16198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 16208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 16218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 16228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtvoid p2p_go_complete(struct p2p_data *p2p, struct p2p_device *peer) 16238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 16248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct p2p_go_neg_results res; 16258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt int go = peer->go_state == LOCAL_GO; 16268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct p2p_channels intersection; 16278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt int freqs; 16288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt size_t i, j; 16298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 16308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG, 16318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "P2P: GO Negotiation with " MACSTR " completed (%s will be " 16328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "GO)", MAC2STR(peer->info.p2p_device_addr), 16338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt go ? "local end" : "peer"); 16348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 16358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memset(&res, 0, sizeof(res)); 16368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt res.role_go = go; 16378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memcpy(res.peer_device_addr, peer->info.p2p_device_addr, ETH_ALEN); 16388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memcpy(res.peer_interface_addr, peer->intended_addr, ETH_ALEN); 16398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt res.wps_method = peer->wps_method; 16401f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt if (peer->flags & P2P_DEV_PREFER_PERSISTENT_GROUP) { 16411f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt if (peer->flags & P2P_DEV_PREFER_PERSISTENT_RECONN) 16421f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt res.persistent_group = 2; 16431f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt else 16441f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt res.persistent_group = 1; 16451f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt } 16468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 16478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (go) { 16488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* Setup AP mode for WPS provisioning */ 16498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt res.freq = p2p_channel_to_freq(p2p->cfg->country, 16508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p->op_reg_class, 16518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p->op_channel); 16528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memcpy(res.ssid, p2p->ssid, p2p->ssid_len); 16538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt res.ssid_len = p2p->ssid_len; 16548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_random(res.passphrase, 8); 16558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } else { 16568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt res.freq = peer->oper_freq; 16578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (p2p->ssid_len) { 16588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memcpy(res.ssid, p2p->ssid, p2p->ssid_len); 16598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt res.ssid_len = p2p->ssid_len; 16608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 16618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 16628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 16638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_channels_intersect(&p2p->channels, &peer->channels, 16648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt &intersection); 16658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt freqs = 0; 16668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt for (i = 0; i < intersection.reg_classes; i++) { 16678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct p2p_reg_class *c = &intersection.reg_class[i]; 16688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (freqs + 1 == P2P_MAX_CHANNELS) 16698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 16708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt for (j = 0; j < c->channels; j++) { 16718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt int freq; 16728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (freqs + 1 == P2P_MAX_CHANNELS) 16738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 16748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt freq = p2p_channel_to_freq(peer->country, c->reg_class, 16758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt c->channel[j]); 16768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (freq < 0) 16778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt continue; 16788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt res.freq_list[freqs++] = freq; 16798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 16808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 16818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 16828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt res.peer_config_timeout = go ? peer->client_timeout : peer->go_timeout; 16838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 16848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_clear_timeout(p2p); 16851f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt p2p->ssid_set = 0; 16868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt peer->go_neg_req_sent = 0; 16878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt peer->wps_method = WPS_NOT_READY; 16888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 16898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_set_state(p2p, P2P_PROVISIONING); 16908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p->cfg->go_neg_completed(p2p->cfg->cb_ctx, &res); 16918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 16928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 16938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 16948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic void p2p_rx_p2p_action(struct p2p_data *p2p, const u8 *sa, 16958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt const u8 *data, size_t len, int rx_freq) 16968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 16978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG, 16988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "P2P: RX P2P Public Action from " MACSTR, MAC2STR(sa)); 16998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_hexdump(MSG_MSGDUMP, "P2P: P2P Public Action contents", data, len); 17008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 17018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (len < 1) 17028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; 17038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 17048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt switch (data[0]) { 17058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case P2P_GO_NEG_REQ: 17068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_process_go_neg_req(p2p, sa, data + 1, len - 1, rx_freq); 17078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 17088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case P2P_GO_NEG_RESP: 17098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_process_go_neg_resp(p2p, sa, data + 1, len - 1, rx_freq); 17108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 17118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case P2P_GO_NEG_CONF: 17128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_process_go_neg_conf(p2p, sa, data + 1, len - 1); 17138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 17148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case P2P_INVITATION_REQ: 17158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_process_invitation_req(p2p, sa, data + 1, len - 1, 17168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt rx_freq); 17178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 17188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case P2P_INVITATION_RESP: 17198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_process_invitation_resp(p2p, sa, data + 1, len - 1); 17208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 17218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case P2P_PROV_DISC_REQ: 17228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_process_prov_disc_req(p2p, sa, data + 1, len - 1, rx_freq); 17238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 17248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case P2P_PROV_DISC_RESP: 17258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_process_prov_disc_resp(p2p, sa, data + 1, len - 1); 17268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 17278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case P2P_DEV_DISC_REQ: 17288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_process_dev_disc_req(p2p, sa, data + 1, len - 1, rx_freq); 17298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 17308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case P2P_DEV_DISC_RESP: 17318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_process_dev_disc_resp(p2p, sa, data + 1, len - 1); 17328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 17338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt default: 17348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG, 17358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "P2P: Unsupported P2P Public Action frame type %d", 17368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt data[0]); 17378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 17388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 17398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 17408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 17418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 17421f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidtstatic void p2p_rx_action_public(struct p2p_data *p2p, const u8 *da, 17431f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt const u8 *sa, const u8 *bssid, const u8 *data, 17441f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt size_t len, int freq) 17458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 17468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (len < 1) 17478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; 17488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 17498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt switch (data[0]) { 17508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case WLAN_PA_VENDOR_SPECIFIC: 17518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt data++; 17528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt len--; 17538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (len < 3) 17548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; 17558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (WPA_GET_BE24(data) != OUI_WFA) 17568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; 17578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 17588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt data += 3; 17598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt len -= 3; 17608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (len < 1) 17618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; 17628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 17638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (*data != P2P_OUI_TYPE) 17648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; 17658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 17668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_rx_p2p_action(p2p, sa, data + 1, len - 1, freq); 17678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 17688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case WLAN_PA_GAS_INITIAL_REQ: 17698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_rx_gas_initial_req(p2p, sa, data + 1, len - 1, freq); 17708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 17718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case WLAN_PA_GAS_INITIAL_RESP: 17728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_rx_gas_initial_resp(p2p, sa, data + 1, len - 1, freq); 17738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 17748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case WLAN_PA_GAS_COMEBACK_REQ: 17758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_rx_gas_comeback_req(p2p, sa, data + 1, len - 1, freq); 17768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 17778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case WLAN_PA_GAS_COMEBACK_RESP: 17788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_rx_gas_comeback_resp(p2p, sa, data + 1, len - 1, freq); 17798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 17808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 17818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 17828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 17838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 17848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtvoid p2p_rx_action(struct p2p_data *p2p, const u8 *da, const u8 *sa, 17858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt const u8 *bssid, u8 category, 17868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt const u8 *data, size_t len, int freq) 17878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 17888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (category == WLAN_ACTION_PUBLIC) { 17898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_rx_action_public(p2p, da, sa, bssid, data, len, freq); 17908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; 17918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 17928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 17938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (category != WLAN_ACTION_VENDOR_SPECIFIC) 17948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; 17958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 17968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (len < 4) 17978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; 17988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 17998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (WPA_GET_BE24(data) != OUI_WFA) 18008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; 18018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt data += 3; 18028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt len -= 3; 18038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 18048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (*data != P2P_OUI_TYPE) 18058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; 18068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt data++; 18078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt len--; 18088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 18098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* P2P action frame */ 18108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG, 18118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "P2P: RX P2P Action from " MACSTR, MAC2STR(sa)); 18128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_hexdump(MSG_MSGDUMP, "P2P: P2P Action contents", data, len); 18138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 18148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (len < 1) 18158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; 18168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt switch (data[0]) { 18178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case P2P_NOA: 18188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG, 18198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "P2P: Received P2P Action - Notice of Absence"); 18208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* TODO */ 18218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 18228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case P2P_PRESENCE_REQ: 18238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_process_presence_req(p2p, da, sa, data + 1, len - 1, freq); 18248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 18258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case P2P_PRESENCE_RESP: 18268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_process_presence_resp(p2p, da, sa, data + 1, len - 1); 18278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 18288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case P2P_GO_DISC_REQ: 18298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_process_go_disc_req(p2p, da, sa, data + 1, len - 1, freq); 18308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 18318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt default: 18328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG, 18338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "P2P: Received P2P Action - unknown type %u", data[0]); 18348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 18358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 18368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 18378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 18388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 18398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic void p2p_go_neg_start(void *eloop_ctx, void *timeout_ctx) 18408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 18418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct p2p_data *p2p = eloop_ctx; 18428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (p2p->go_neg_peer == NULL) 18438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; 18448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p->cfg->stop_listen(p2p->cfg->cb_ctx); 18458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p->go_neg_peer->status = P2P_SC_SUCCESS; 18468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_connect_send(p2p, p2p->go_neg_peer); 18478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 18488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 18498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 18508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic void p2p_invite_start(void *eloop_ctx, void *timeout_ctx) 18518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 18528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct p2p_data *p2p = eloop_ctx; 18538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (p2p->invite_peer == NULL) 18548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; 18558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p->cfg->stop_listen(p2p->cfg->cb_ctx); 18568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_invite_send(p2p, p2p->invite_peer, p2p->invite_go_dev_addr); 18578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 18588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 18598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 18608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic void p2p_add_dev_from_probe_req(struct p2p_data *p2p, const u8 *addr, 18618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt const u8 *ie, size_t ie_len) 18628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 18638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct p2p_message msg; 18648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct p2p_device *dev; 18658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 18668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memset(&msg, 0, sizeof(msg)); 18678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (p2p_parse_ies(ie, ie_len, &msg) < 0 || msg.p2p_attributes == NULL) 18688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt { 18698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_parse_free(&msg); 18708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; /* not a P2P probe */ 18718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 18728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 18738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (msg.ssid == NULL || msg.ssid[1] != P2P_WILDCARD_SSID_LEN || 18748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memcmp(msg.ssid + 2, P2P_WILDCARD_SSID, P2P_WILDCARD_SSID_LEN) 18758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt != 0) { 18768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* The Probe Request is not part of P2P Device Discovery. It is 18778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * not known whether the source address of the frame is the P2P 18788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * Device Address or P2P Interface Address. Do not add a new 18798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * peer entry based on this frames. 18808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */ 18818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_parse_free(&msg); 18828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; 18838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 18848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 18858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt dev = p2p_get_device(p2p, addr); 18868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (dev) { 18878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (dev->country[0] == 0 && msg.listen_channel) 18888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memcpy(dev->country, msg.listen_channel, 3); 18891f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt os_get_time(&dev->last_seen); 18908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_parse_free(&msg); 18918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; /* already known */ 18928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 18938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 18948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt dev = p2p_create_device(p2p, addr); 18958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (dev == NULL) { 18968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_parse_free(&msg); 18978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; 18988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 18998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 19008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_get_time(&dev->last_seen); 19018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt dev->flags |= P2P_DEV_PROBE_REQ_ONLY; 19028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 19038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (msg.listen_channel) { 19048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memcpy(dev->country, msg.listen_channel, 3); 19058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt dev->listen_freq = p2p_channel_to_freq(dev->country, 19068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt msg.listen_channel[3], 19078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt msg.listen_channel[4]); 19088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 19098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 19108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_copy_wps_info(dev, 1, &msg); 19118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 191261d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt if (msg.wfd_subelems) { 191361d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt wpabuf_free(dev->info.wfd_subelems); 191461d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt dev->info.wfd_subelems = wpabuf_dup(msg.wfd_subelems); 191561d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt } 191661d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt 19178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_parse_free(&msg); 19188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 19198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG, 19208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "P2P: Created device entry based on Probe Req: " MACSTR 19218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt " dev_capab=0x%x group_capab=0x%x name='%s' listen_freq=%d", 19228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt MAC2STR(dev->info.p2p_device_addr), dev->info.dev_capab, 19238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt dev->info.group_capab, dev->info.device_name, 19248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt dev->listen_freq); 19258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 19268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 19278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 19288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstruct p2p_device * p2p_add_dev_from_go_neg_req(struct p2p_data *p2p, 19298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt const u8 *addr, 19308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct p2p_message *msg) 19318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 19328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct p2p_device *dev; 19338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 19348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt dev = p2p_get_device(p2p, addr); 19358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (dev) { 19368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_get_time(&dev->last_seen); 19378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return dev; /* already known */ 19388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 19398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 19408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt dev = p2p_create_device(p2p, addr); 19418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (dev == NULL) 19428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return NULL; 19438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 19448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_add_dev_info(p2p, addr, dev, msg); 19458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 19468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return dev; 19478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 19488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 19498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 19508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic int dev_type_match(const u8 *dev_type, const u8 *req_dev_type) 19518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 19528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (os_memcmp(dev_type, req_dev_type, WPS_DEV_TYPE_LEN) == 0) 19538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 1; 19548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (os_memcmp(dev_type, req_dev_type, 2) == 0 && 19558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt WPA_GET_BE32(&req_dev_type[2]) == 0 && 19568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt WPA_GET_BE16(&req_dev_type[6]) == 0) 19578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 1; /* Category match with wildcard OUI/sub-category */ 19588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 19598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 19608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 19618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 19628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtint dev_type_list_match(const u8 *dev_type, const u8 *req_dev_type[], 19638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt size_t num_req_dev_type) 19648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 19658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt size_t i; 19668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt for (i = 0; i < num_req_dev_type; i++) { 19678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (dev_type_match(dev_type, req_dev_type[i])) 19688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 1; 19698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 19708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 19718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 19728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 19738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 19748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt/** 19758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * p2p_match_dev_type - Match local device type with requested type 19768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @p2p: P2P module context from p2p_init() 19778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @wps: WPS TLVs from Probe Request frame (concatenated WPS IEs) 19788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * Returns: 1 on match, 0 on mismatch 19798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * 19808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * This function can be used to match the Requested Device Type attribute in 19818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * WPS IE with the local device types for deciding whether to reply to a Probe 19828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * Request frame. 19838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */ 19848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtint p2p_match_dev_type(struct p2p_data *p2p, struct wpabuf *wps) 19858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 19868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct wps_parse_attr attr; 19878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt size_t i; 19888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 19898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (wps_parse_msg(wps, &attr)) 19908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 1; /* assume no Requested Device Type attributes */ 19918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 19928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (attr.num_req_dev_type == 0) 19938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 1; /* no Requested Device Type attributes -> match */ 19948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 19958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (dev_type_list_match(p2p->cfg->pri_dev_type, attr.req_dev_type, 19968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt attr.num_req_dev_type)) 19978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 1; /* Own Primary Device Type matches */ 19988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 19998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt for (i = 0; i < p2p->cfg->num_sec_dev_types; i++) 20008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (dev_type_list_match(p2p->cfg->sec_dev_type[i], 20018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt attr.req_dev_type, 20028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt attr.num_req_dev_type)) 20038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 1; /* Own Secondary Device Type matches */ 20048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 20058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* No matching device type found */ 20068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 20078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 20088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 20098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 20108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstruct wpabuf * p2p_build_probe_resp_ies(struct p2p_data *p2p) 20118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 20128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct wpabuf *buf; 20138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt u8 *len; 201404949598a23f501be6eec21697465fd46a28840aDmitry Shmidt int pw_id = -1; 201561d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt size_t extra = 0; 201661d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt 201761d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt#ifdef CONFIG_WIFI_DISPLAY 201861d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt if (p2p->wfd_ie_probe_resp) 201961d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt extra = wpabuf_len(p2p->wfd_ie_probe_resp); 202061d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt#endif /* CONFIG_WIFI_DISPLAY */ 20218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 202261d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt buf = wpabuf_alloc(1000 + extra); 20238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (buf == NULL) 20248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return NULL; 20258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 202604949598a23f501be6eec21697465fd46a28840aDmitry Shmidt if (p2p->go_neg_peer) { 202704949598a23f501be6eec21697465fd46a28840aDmitry Shmidt /* Advertise immediate availability of WPS credential */ 202804949598a23f501be6eec21697465fd46a28840aDmitry Shmidt pw_id = p2p_wps_method_pw_id(p2p->go_neg_peer->wps_method); 202904949598a23f501be6eec21697465fd46a28840aDmitry Shmidt } 203004949598a23f501be6eec21697465fd46a28840aDmitry Shmidt 203104949598a23f501be6eec21697465fd46a28840aDmitry Shmidt p2p_build_wps_ie(p2p, buf, pw_id, 1); 20328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 203361d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt#ifdef CONFIG_WIFI_DISPLAY 203461d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt if (p2p->wfd_ie_probe_resp) 203561d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt wpabuf_put_buf(buf, p2p->wfd_ie_probe_resp); 203661d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt#endif /* CONFIG_WIFI_DISPLAY */ 203761d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt 20388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* P2P IE */ 20398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt len = p2p_buf_add_ie_hdr(buf); 204004949598a23f501be6eec21697465fd46a28840aDmitry Shmidt p2p_buf_add_capability(buf, p2p->dev_capab & 204104949598a23f501be6eec21697465fd46a28840aDmitry Shmidt ~P2P_DEV_CAPAB_CLIENT_DISCOVERABILITY, 0); 20428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (p2p->ext_listen_interval) 20438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_buf_add_ext_listen_timing(buf, p2p->ext_listen_period, 20448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p->ext_listen_interval); 20458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_buf_add_device_info(buf, p2p, NULL); 20468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_buf_update_ie_hdr(buf, len); 20478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 20488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return buf; 20498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 20508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 20518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 20521f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidtstatic int is_11b(u8 rate) 20531f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt{ 20541f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt return rate == 0x02 || rate == 0x04 || rate == 0x0b || rate == 0x16; 20551f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt} 20561f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt 20571f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt 20581f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidtstatic int supp_rates_11b_only(struct ieee802_11_elems *elems) 20591f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt{ 20601f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt int num_11b = 0, num_others = 0; 20611f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt int i; 20621f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt 20631f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt if (elems->supp_rates == NULL && elems->ext_supp_rates == NULL) 20641f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt return 0; 20651f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt 20661f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt for (i = 0; elems->supp_rates && i < elems->supp_rates_len; i++) { 20671f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt if (is_11b(elems->supp_rates[i])) 20681f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt num_11b++; 20691f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt else 20701f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt num_others++; 20711f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt } 20721f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt 20731f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt for (i = 0; elems->ext_supp_rates && i < elems->ext_supp_rates_len; 20741f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt i++) { 20751f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt if (is_11b(elems->ext_supp_rates[i])) 20761f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt num_11b++; 20771f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt else 20781f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt num_others++; 20791f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt } 20801f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt 20811f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt return num_11b > 0 && num_others == 0; 20821f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt} 20831f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt 20841f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt 208504949598a23f501be6eec21697465fd46a28840aDmitry Shmidtstatic enum p2p_probe_req_status 208604949598a23f501be6eec21697465fd46a28840aDmitry Shmidtp2p_reply_probe(struct p2p_data *p2p, const u8 *addr, const u8 *dst, 208704949598a23f501be6eec21697465fd46a28840aDmitry Shmidt const u8 *bssid, const u8 *ie, size_t ie_len) 20888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 20898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct ieee802_11_elems elems; 20908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct wpabuf *buf; 20918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct ieee80211_mgmt *resp; 20921f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt struct p2p_message msg; 20938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct wpabuf *ies; 20948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 20958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (!p2p->in_listen || !p2p->drv_in_listen) { 20968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* not in Listen state - ignore Probe Request */ 209704949598a23f501be6eec21697465fd46a28840aDmitry Shmidt return P2P_PREQ_NOT_LISTEN; 20988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 20998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 21008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (ieee802_11_parse_elems((u8 *) ie, ie_len, &elems, 0) == 21018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ParseFailed) { 21028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* Ignore invalid Probe Request frames */ 210304949598a23f501be6eec21697465fd46a28840aDmitry Shmidt return P2P_PREQ_MALFORMED; 21048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 21058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 21068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (elems.p2p == NULL) { 21078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* not a P2P probe - ignore it */ 210804949598a23f501be6eec21697465fd46a28840aDmitry Shmidt return P2P_PREQ_NOT_P2P; 21098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 21108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 21111f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt if (dst && !is_broadcast_ether_addr(dst) && 21121f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt os_memcmp(dst, p2p->cfg->dev_addr, ETH_ALEN) != 0) { 21131f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt /* Not sent to the broadcast address or our P2P Device Address 21141f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt */ 211504949598a23f501be6eec21697465fd46a28840aDmitry Shmidt return P2P_PREQ_NOT_PROCESSED; 21161f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt } 21171f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt 21181f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt if (bssid && !is_broadcast_ether_addr(bssid)) { 21191f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt /* Not sent to the Wildcard BSSID */ 212004949598a23f501be6eec21697465fd46a28840aDmitry Shmidt return P2P_PREQ_NOT_PROCESSED; 21211f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt } 21221f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt 21238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (elems.ssid == NULL || elems.ssid_len != P2P_WILDCARD_SSID_LEN || 21248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memcmp(elems.ssid, P2P_WILDCARD_SSID, P2P_WILDCARD_SSID_LEN) != 21258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 0) { 21268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* not using P2P Wildcard SSID - ignore */ 212704949598a23f501be6eec21697465fd46a28840aDmitry Shmidt return P2P_PREQ_NOT_PROCESSED; 21288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 21298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 21301f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt if (supp_rates_11b_only(&elems)) { 21311f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt /* Indicates support for 11b rates only */ 213204949598a23f501be6eec21697465fd46a28840aDmitry Shmidt return P2P_PREQ_NOT_P2P; 21331f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt } 21341f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt 21351f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt os_memset(&msg, 0, sizeof(msg)); 21361f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt if (p2p_parse_ies(ie, ie_len, &msg) < 0) { 21371f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt /* Could not parse P2P attributes */ 213804949598a23f501be6eec21697465fd46a28840aDmitry Shmidt return P2P_PREQ_NOT_P2P; 21391f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt } 21401f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt 21411f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt if (msg.device_id && 214204949598a23f501be6eec21697465fd46a28840aDmitry Shmidt os_memcmp(msg.device_id, p2p->cfg->dev_addr, ETH_ALEN) != 0) { 21431f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt /* Device ID did not match */ 21441f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt p2p_parse_free(&msg); 214504949598a23f501be6eec21697465fd46a28840aDmitry Shmidt return P2P_PREQ_NOT_PROCESSED; 21461f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt } 21471f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt 21488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* Check Requested Device Type match */ 21491f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt if (msg.wps_attributes && 21501f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt !p2p_match_dev_type(p2p, msg.wps_attributes)) { 21518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* No match with Requested Device Type */ 21521f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt p2p_parse_free(&msg); 215304949598a23f501be6eec21697465fd46a28840aDmitry Shmidt return P2P_PREQ_NOT_PROCESSED; 21548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 21551f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt p2p_parse_free(&msg); 21568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 215704949598a23f501be6eec21697465fd46a28840aDmitry Shmidt if (!p2p->cfg->send_probe_resp) { 215804949598a23f501be6eec21697465fd46a28840aDmitry Shmidt /* Response generated elsewhere */ 215904949598a23f501be6eec21697465fd46a28840aDmitry Shmidt return P2P_PREQ_NOT_PROCESSED; 216004949598a23f501be6eec21697465fd46a28840aDmitry Shmidt } 21618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 21628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG, 21638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "P2P: Reply to P2P Probe Request in Listen state"); 21648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 21658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* 21668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * We do not really have a specific BSS that this frame is advertising, 21678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * so build a frame that has some information in valid format. This is 21688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * really only used for discovery purposes, not to learn exact BSS 21698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * parameters. 21708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */ 21718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ies = p2p_build_probe_resp_ies(p2p); 21728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (ies == NULL) 217304949598a23f501be6eec21697465fd46a28840aDmitry Shmidt return P2P_PREQ_NOT_PROCESSED; 21748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 21758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt buf = wpabuf_alloc(200 + wpabuf_len(ies)); 21768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (buf == NULL) { 21778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpabuf_free(ies); 217804949598a23f501be6eec21697465fd46a28840aDmitry Shmidt return P2P_PREQ_NOT_PROCESSED; 21798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 21808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 21818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt resp = NULL; 21828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt resp = wpabuf_put(buf, resp->u.probe_resp.variable - (u8 *) resp); 21838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 21848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt resp->frame_control = host_to_le16((WLAN_FC_TYPE_MGMT << 2) | 21858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt (WLAN_FC_STYPE_PROBE_RESP << 4)); 21868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memcpy(resp->da, addr, ETH_ALEN); 21878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memcpy(resp->sa, p2p->cfg->dev_addr, ETH_ALEN); 21888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memcpy(resp->bssid, p2p->cfg->dev_addr, ETH_ALEN); 21898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt resp->u.probe_resp.beacon_int = host_to_le16(100); 21908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* hardware or low-level driver will setup seq_ctrl and timestamp */ 21918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt resp->u.probe_resp.capab_info = 21928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt host_to_le16(WLAN_CAPABILITY_SHORT_PREAMBLE | 21938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt WLAN_CAPABILITY_PRIVACY | 21948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt WLAN_CAPABILITY_SHORT_SLOT_TIME); 21958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 21968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpabuf_put_u8(buf, WLAN_EID_SSID); 21978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpabuf_put_u8(buf, P2P_WILDCARD_SSID_LEN); 21988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpabuf_put_data(buf, P2P_WILDCARD_SSID, P2P_WILDCARD_SSID_LEN); 21998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 22008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpabuf_put_u8(buf, WLAN_EID_SUPP_RATES); 22018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpabuf_put_u8(buf, 8); 22028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpabuf_put_u8(buf, (60 / 5) | 0x80); 22038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpabuf_put_u8(buf, 90 / 5); 22048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpabuf_put_u8(buf, (120 / 5) | 0x80); 22058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpabuf_put_u8(buf, 180 / 5); 22068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpabuf_put_u8(buf, (240 / 5) | 0x80); 22078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpabuf_put_u8(buf, 360 / 5); 22088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpabuf_put_u8(buf, 480 / 5); 22098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpabuf_put_u8(buf, 540 / 5); 22108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 22118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpabuf_put_u8(buf, WLAN_EID_DS_PARAMS); 22128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpabuf_put_u8(buf, 1); 22138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpabuf_put_u8(buf, p2p->cfg->channel); 22148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 22158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpabuf_put_buf(buf, ies); 22168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpabuf_free(ies); 22178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 22188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p->cfg->send_probe_resp(p2p->cfg->cb_ctx, buf); 22198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 22208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpabuf_free(buf); 222104949598a23f501be6eec21697465fd46a28840aDmitry Shmidt 222204949598a23f501be6eec21697465fd46a28840aDmitry Shmidt return P2P_PREQ_NOT_PROCESSED; 22238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 22248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 22258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 222604949598a23f501be6eec21697465fd46a28840aDmitry Shmidtenum p2p_probe_req_status 222704949598a23f501be6eec21697465fd46a28840aDmitry Shmidtp2p_probe_req_rx(struct p2p_data *p2p, const u8 *addr, const u8 *dst, 222804949598a23f501be6eec21697465fd46a28840aDmitry Shmidt const u8 *bssid, const u8 *ie, size_t ie_len) 22298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 223004949598a23f501be6eec21697465fd46a28840aDmitry Shmidt enum p2p_probe_req_status res; 223104949598a23f501be6eec21697465fd46a28840aDmitry Shmidt 22328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_add_dev_from_probe_req(p2p, addr, ie, ie_len); 22338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 223404949598a23f501be6eec21697465fd46a28840aDmitry Shmidt res = p2p_reply_probe(p2p, addr, dst, bssid, ie, ie_len); 22358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 22368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if ((p2p->state == P2P_CONNECT || p2p->state == P2P_CONNECT_LISTEN) && 22378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p->go_neg_peer && 22388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memcmp(addr, p2p->go_neg_peer->info.p2p_device_addr, ETH_ALEN) 22399cdf1b905fae57dea42506a1af67f6ece544b261Dmitry Shmidt == 0 && 22409cdf1b905fae57dea42506a1af67f6ece544b261Dmitry Shmidt !(p2p->go_neg_peer->flags & P2P_DEV_WAIT_GO_NEG_CONFIRM)) { 22418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* Received a Probe Request from GO Negotiation peer */ 22428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG, 22438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "P2P: Found GO Negotiation peer - try to start GO " 22448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "negotiation from timeout"); 22459cdf1b905fae57dea42506a1af67f6ece544b261Dmitry Shmidt eloop_cancel_timeout(p2p_go_neg_start, p2p, NULL); 22468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt eloop_register_timeout(0, 0, p2p_go_neg_start, p2p, NULL); 224704949598a23f501be6eec21697465fd46a28840aDmitry Shmidt return P2P_PREQ_PROCESSED; 22488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 22498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 22508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if ((p2p->state == P2P_INVITE || p2p->state == P2P_INVITE_LISTEN) && 22518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p->invite_peer && 22528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memcmp(addr, p2p->invite_peer->info.p2p_device_addr, ETH_ALEN) 22538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt == 0) { 22548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* Received a Probe Request from Invite peer */ 22558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG, 22568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "P2P: Found Invite peer - try to start Invite from " 22578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "timeout"); 22588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt eloop_register_timeout(0, 0, p2p_invite_start, p2p, NULL); 225904949598a23f501be6eec21697465fd46a28840aDmitry Shmidt return P2P_PREQ_PROCESSED; 22608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 22618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 226204949598a23f501be6eec21697465fd46a28840aDmitry Shmidt return res; 22638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 22648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 22658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 22668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic int p2p_assoc_req_ie_wlan_ap(struct p2p_data *p2p, const u8 *bssid, 22678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt u8 *buf, size_t len, struct wpabuf *p2p_ie) 22688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 22698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct wpabuf *tmp; 22708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt u8 *lpos; 22718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt size_t tmplen; 22728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt int res; 22738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt u8 group_capab; 22748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 22758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (p2p_ie == NULL) 22768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; /* WLAN AP is not a P2P manager */ 22778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 22788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* 22798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * (Re)Association Request - P2P IE 22808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * P2P Capability attribute (shall be present) 22818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * P2P Interface attribute (present if concurrent device and 22828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * P2P Management is enabled) 22838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */ 22848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt tmp = wpabuf_alloc(200); 22858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (tmp == NULL) 22868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 22878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 22888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt lpos = p2p_buf_add_ie_hdr(tmp); 22898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt group_capab = 0; 22908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (p2p->num_groups > 0) { 22918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt group_capab |= P2P_GROUP_CAPAB_GROUP_OWNER; 22928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if ((p2p->dev_capab & P2P_DEV_CAPAB_CONCURRENT_OPER) && 22938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt (p2p->dev_capab & P2P_DEV_CAPAB_INFRA_MANAGED) && 22948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p->cross_connect) 22958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt group_capab |= P2P_GROUP_CAPAB_CROSS_CONN; 22968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 22978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_buf_add_capability(tmp, p2p->dev_capab, group_capab); 22988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if ((p2p->dev_capab & P2P_DEV_CAPAB_CONCURRENT_OPER) && 22998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt (p2p->dev_capab & P2P_DEV_CAPAB_INFRA_MANAGED)) 23008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_buf_add_p2p_interface(tmp, p2p); 23018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_buf_update_ie_hdr(tmp, lpos); 23028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 23038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt tmplen = wpabuf_len(tmp); 23048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (tmplen > len) 23058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt res = -1; 23068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt else { 23078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memcpy(buf, wpabuf_head(tmp), tmplen); 23088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt res = tmplen; 23098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 23108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpabuf_free(tmp); 23118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 23128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return res; 23138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 23148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 23158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 23168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtint p2p_assoc_req_ie(struct p2p_data *p2p, const u8 *bssid, u8 *buf, 23178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt size_t len, int p2p_group, struct wpabuf *p2p_ie) 23188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 23198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct wpabuf *tmp; 23208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt u8 *lpos; 23218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct p2p_device *peer; 23228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt size_t tmplen; 23238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt int res; 232461d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt size_t extra = 0; 23258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 23268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (!p2p_group) 23278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return p2p_assoc_req_ie_wlan_ap(p2p, bssid, buf, len, p2p_ie); 23288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 232961d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt#ifdef CONFIG_WIFI_DISPLAY 233061d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt if (p2p->wfd_ie_assoc_req) 233161d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt extra = wpabuf_len(p2p->wfd_ie_assoc_req); 233261d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt#endif /* CONFIG_WIFI_DISPLAY */ 233361d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt 23348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* 23358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * (Re)Association Request - P2P IE 23368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * P2P Capability attribute (shall be present) 23378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * Extended Listen Timing (may be present) 23388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * P2P Device Info attribute (shall be present) 23398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */ 234061d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt tmp = wpabuf_alloc(200 + extra); 23418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (tmp == NULL) 23428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 23438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 234461d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt#ifdef CONFIG_WIFI_DISPLAY 234561d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt if (p2p->wfd_ie_assoc_req) 234661d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt wpabuf_put_buf(tmp, p2p->wfd_ie_assoc_req); 234761d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt#endif /* CONFIG_WIFI_DISPLAY */ 234861d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt 23498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt peer = bssid ? p2p_get_device(p2p, bssid) : NULL; 23508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 23518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt lpos = p2p_buf_add_ie_hdr(tmp); 23528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_buf_add_capability(tmp, p2p->dev_capab, 0); 23538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (p2p->ext_listen_interval) 23548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_buf_add_ext_listen_timing(tmp, p2p->ext_listen_period, 23558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p->ext_listen_interval); 23568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_buf_add_device_info(tmp, p2p, peer); 23578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_buf_update_ie_hdr(tmp, lpos); 23588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 23598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt tmplen = wpabuf_len(tmp); 23608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (tmplen > len) 23618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt res = -1; 23628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt else { 23638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memcpy(buf, wpabuf_head(tmp), tmplen); 23648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt res = tmplen; 23658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 23668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpabuf_free(tmp); 23678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 23688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return res; 23698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 23708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 23718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 23728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtint p2p_scan_result_text(const u8 *ies, size_t ies_len, char *buf, char *end) 23738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 23748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct wpabuf *p2p_ie; 23758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt int ret; 23768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 23778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_ie = ieee802_11_vendor_ie_concat(ies, ies_len, P2P_IE_VENDOR_TYPE); 23788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (p2p_ie == NULL) 23798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 23808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 23818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ret = p2p_attr_text(p2p_ie, buf, end); 23828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpabuf_free(p2p_ie); 23838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return ret; 23848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 23858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 23868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 238704949598a23f501be6eec21697465fd46a28840aDmitry Shmidtint p2p_parse_dev_addr_in_p2p_ie(struct wpabuf *p2p_ie, u8 *dev_addr) 2388c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt{ 2389c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt struct p2p_message msg; 2390c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt 2391c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt os_memset(&msg, 0, sizeof(msg)); 239204949598a23f501be6eec21697465fd46a28840aDmitry Shmidt if (p2p_parse_p2p_ie(p2p_ie, &msg)) 2393c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt return -1; 2394c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt 239504949598a23f501be6eec21697465fd46a28840aDmitry Shmidt if (msg.p2p_device_addr) { 239604949598a23f501be6eec21697465fd46a28840aDmitry Shmidt os_memcpy(dev_addr, msg.p2p_device_addr, ETH_ALEN); 239704949598a23f501be6eec21697465fd46a28840aDmitry Shmidt return 0; 239804949598a23f501be6eec21697465fd46a28840aDmitry Shmidt } else if (msg.device_id) { 239904949598a23f501be6eec21697465fd46a28840aDmitry Shmidt os_memcpy(dev_addr, msg.device_id, ETH_ALEN); 240004949598a23f501be6eec21697465fd46a28840aDmitry Shmidt return 0; 2401c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt } 240204949598a23f501be6eec21697465fd46a28840aDmitry Shmidt return -1; 240304949598a23f501be6eec21697465fd46a28840aDmitry Shmidt} 2404c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt 240504949598a23f501be6eec21697465fd46a28840aDmitry Shmidt 240604949598a23f501be6eec21697465fd46a28840aDmitry Shmidtint p2p_parse_dev_addr(const u8 *ies, size_t ies_len, u8 *dev_addr) 240704949598a23f501be6eec21697465fd46a28840aDmitry Shmidt{ 240804949598a23f501be6eec21697465fd46a28840aDmitry Shmidt struct wpabuf *p2p_ie; 240904949598a23f501be6eec21697465fd46a28840aDmitry Shmidt int ret; 241004949598a23f501be6eec21697465fd46a28840aDmitry Shmidt 241104949598a23f501be6eec21697465fd46a28840aDmitry Shmidt p2p_ie = ieee802_11_vendor_ie_concat(ies, ies_len, 241204949598a23f501be6eec21697465fd46a28840aDmitry Shmidt P2P_IE_VENDOR_TYPE); 241304949598a23f501be6eec21697465fd46a28840aDmitry Shmidt if (p2p_ie == NULL) 241404949598a23f501be6eec21697465fd46a28840aDmitry Shmidt return -1; 241504949598a23f501be6eec21697465fd46a28840aDmitry Shmidt ret = p2p_parse_dev_addr_in_p2p_ie(p2p_ie, dev_addr); 2416c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt wpabuf_free(p2p_ie); 241704949598a23f501be6eec21697465fd46a28840aDmitry Shmidt return ret; 2418c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt} 2419c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt 2420c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt 24218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic void p2p_clear_go_neg(struct p2p_data *p2p) 24228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 24238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p->go_neg_peer = NULL; 24248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_clear_timeout(p2p); 24258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_set_state(p2p, P2P_IDLE); 24268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 24278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 24288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 24298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtvoid p2p_wps_success_cb(struct p2p_data *p2p, const u8 *mac_addr) 24308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 24318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (p2p->go_neg_peer == NULL) { 24328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG, 24338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "P2P: No pending Group Formation - " 24348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "ignore WPS registration success notification"); 24358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; /* No pending Group Formation */ 24368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 24378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 24388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (os_memcmp(mac_addr, p2p->go_neg_peer->intended_addr, ETH_ALEN) != 24398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 0) { 24408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG, 24418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "P2P: Ignore WPS registration success notification " 24428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "for " MACSTR " (GO Negotiation peer " MACSTR ")", 24438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt MAC2STR(mac_addr), 24448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt MAC2STR(p2p->go_neg_peer->intended_addr)); 24458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; /* Ignore unexpected peer address */ 24468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 24478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 24488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG, 24498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "P2P: Group Formation completed successfully with " MACSTR, 24508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt MAC2STR(mac_addr)); 24518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 24528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_clear_go_neg(p2p); 24538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 24548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 24558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 24568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtvoid p2p_group_formation_failed(struct p2p_data *p2p) 24578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 24588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (p2p->go_neg_peer == NULL) { 24598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG, 24608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "P2P: No pending Group Formation - " 24618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "ignore group formation failure notification"); 24628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; /* No pending Group Formation */ 24638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 24648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 24658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG, 24668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "P2P: Group Formation failed with " MACSTR, 24678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt MAC2STR(p2p->go_neg_peer->intended_addr)); 24688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 24698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_clear_go_neg(p2p); 24708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 24718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 24728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 24738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstruct p2p_data * p2p_init(const struct p2p_config *cfg) 24748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 24758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct p2p_data *p2p; 24768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 24778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (cfg->max_peers < 1) 24788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return NULL; 24798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 24808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p = os_zalloc(sizeof(*p2p) + sizeof(*cfg)); 24818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (p2p == NULL) 24828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return NULL; 24838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p->cfg = (struct p2p_config *) (p2p + 1); 24848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memcpy(p2p->cfg, cfg, sizeof(*cfg)); 24858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (cfg->dev_name) 24868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p->cfg->dev_name = os_strdup(cfg->dev_name); 24878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (cfg->manufacturer) 24888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p->cfg->manufacturer = os_strdup(cfg->manufacturer); 24898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (cfg->model_name) 24908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p->cfg->model_name = os_strdup(cfg->model_name); 24918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (cfg->model_number) 24928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p->cfg->model_number = os_strdup(cfg->model_number); 24938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (cfg->serial_number) 24948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p->cfg->serial_number = os_strdup(cfg->serial_number); 249504949598a23f501be6eec21697465fd46a28840aDmitry Shmidt if (cfg->pref_chan) { 249604949598a23f501be6eec21697465fd46a28840aDmitry Shmidt p2p->cfg->pref_chan = os_malloc(cfg->num_pref_chan * 249704949598a23f501be6eec21697465fd46a28840aDmitry Shmidt sizeof(struct p2p_channel)); 249804949598a23f501be6eec21697465fd46a28840aDmitry Shmidt if (p2p->cfg->pref_chan) { 249904949598a23f501be6eec21697465fd46a28840aDmitry Shmidt os_memcpy(p2p->cfg->pref_chan, cfg->pref_chan, 250004949598a23f501be6eec21697465fd46a28840aDmitry Shmidt cfg->num_pref_chan * 250104949598a23f501be6eec21697465fd46a28840aDmitry Shmidt sizeof(struct p2p_channel)); 250204949598a23f501be6eec21697465fd46a28840aDmitry Shmidt } else 250304949598a23f501be6eec21697465fd46a28840aDmitry Shmidt p2p->cfg->num_pref_chan = 0; 250404949598a23f501be6eec21697465fd46a28840aDmitry Shmidt } 250504949598a23f501be6eec21697465fd46a28840aDmitry Shmidt 2506f44b9c4a18d17fbd39901f76a014c32006570fb8Irfan Sheriff#ifdef ANDROID_P2P 2507f44b9c4a18d17fbd39901f76a014c32006570fb8Irfan Sheriff /* 100ms listen time is too less to receive the response frames in some scenarios 2508f44b9c4a18d17fbd39901f76a014c32006570fb8Irfan Sheriff * increasing min listen time to 200ms. 2509f44b9c4a18d17fbd39901f76a014c32006570fb8Irfan Sheriff */ 2510f44b9c4a18d17fbd39901f76a014c32006570fb8Irfan Sheriff p2p->min_disc_int = 2; 2511f44b9c4a18d17fbd39901f76a014c32006570fb8Irfan Sheriff /* SD_FAIR_POLICY: Initializing the SD current serviced pointer to NULL */ 2512f44b9c4a18d17fbd39901f76a014c32006570fb8Irfan Sheriff p2p->sd_dev_list = NULL; 2513f44b9c4a18d17fbd39901f76a014c32006570fb8Irfan Sheriff#else 25148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p->min_disc_int = 1; 2515f44b9c4a18d17fbd39901f76a014c32006570fb8Irfan Sheriff#endif 25168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p->max_disc_int = 3; 2517d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt p2p->max_disc_tu = -1; 25188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 25198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_get_random(&p2p->next_tie_breaker, 1); 25208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p->next_tie_breaker &= 0x01; 25218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (cfg->sd_request) 25228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p->dev_capab |= P2P_DEV_CAPAB_SERVICE_DISCOVERY; 25238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p->dev_capab |= P2P_DEV_CAPAB_INVITATION_PROCEDURE; 25248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (cfg->concurrent_operations) 25258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p->dev_capab |= P2P_DEV_CAPAB_CONCURRENT_OPER; 25268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p->dev_capab |= P2P_DEV_CAPAB_CLIENT_DISCOVERABILITY; 25278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 25288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt dl_list_init(&p2p->devices); 25298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 25308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt eloop_register_timeout(P2P_PEER_EXPIRATION_INTERVAL, 0, 25318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_expiration_timeout, p2p, NULL); 25328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 253361d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt p2p->go_timeout = 100; 253461d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt p2p->client_timeout = 20; 253561d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt 25368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return p2p; 25378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 25388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 25398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 25408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtvoid p2p_deinit(struct p2p_data *p2p) 25418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 254261d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt#ifdef CONFIG_WIFI_DISPLAY 254361d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt wpabuf_free(p2p->wfd_ie_beacon); 254461d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt wpabuf_free(p2p->wfd_ie_probe_req); 254561d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt wpabuf_free(p2p->wfd_ie_probe_resp); 254661d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt wpabuf_free(p2p->wfd_ie_assoc_req); 254761d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt wpabuf_free(p2p->wfd_ie_invitation); 254861d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt wpabuf_free(p2p->wfd_ie_prov_disc_req); 254961d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt wpabuf_free(p2p->wfd_ie_prov_disc_resp); 255061d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt wpabuf_free(p2p->wfd_ie_go_neg); 255161d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt wpabuf_free(p2p->wfd_dev_info); 255261d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt wpabuf_free(p2p->wfd_assoc_bssid); 255361d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt wpabuf_free(p2p->wfd_coupled_sink_info); 255461d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt#endif /* CONFIG_WIFI_DISPLAY */ 255561d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt 25568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt eloop_cancel_timeout(p2p_expiration_timeout, p2p, NULL); 25578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt eloop_cancel_timeout(p2p_ext_listen_timeout, p2p, NULL); 25588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt eloop_cancel_timeout(p2p_scan_timeout, p2p, NULL); 25599cdf1b905fae57dea42506a1af67f6ece544b261Dmitry Shmidt eloop_cancel_timeout(p2p_go_neg_start, p2p, NULL); 25608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_flush(p2p); 25618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_free_req_dev_types(p2p); 25628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_free(p2p->cfg->dev_name); 25638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_free(p2p->cfg->manufacturer); 25648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_free(p2p->cfg->model_name); 25658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_free(p2p->cfg->model_number); 25668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_free(p2p->cfg->serial_number); 256704949598a23f501be6eec21697465fd46a28840aDmitry Shmidt os_free(p2p->cfg->pref_chan); 25688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_free(p2p->groups); 25698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpabuf_free(p2p->sd_resp); 25708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_free(p2p->after_scan_tx); 25718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_remove_wps_vendor_extensions(p2p); 25728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_free(p2p); 25738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 25748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 25758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 25768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtvoid p2p_flush(struct p2p_data *p2p) 25778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 25788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct p2p_device *dev, *prev; 257904949598a23f501be6eec21697465fd46a28840aDmitry Shmidt p2p_stop_find(p2p); 25808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt dl_list_for_each_safe(dev, prev, &p2p->devices, struct p2p_device, 25818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt list) { 25828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt dl_list_del(&dev->list); 25838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_device_free(p2p, dev); 25848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 2585f44b9c4a18d17fbd39901f76a014c32006570fb8Irfan Sheriff#ifdef ANDROID_P2P 2586f44b9c4a18d17fbd39901f76a014c32006570fb8Irfan Sheriff /* SD_FAIR_POLICY: Initializing the SD current serviced pointer to NULL */ 2587f44b9c4a18d17fbd39901f76a014c32006570fb8Irfan Sheriff p2p->sd_dev_list = NULL; 2588f44b9c4a18d17fbd39901f76a014c32006570fb8Irfan Sheriff#endif 25898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_free_sd_queries(p2p); 25908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_free(p2p->after_scan_tx); 25918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p->after_scan_tx = NULL; 25928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 25938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 25948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 25958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtint p2p_unauthorize(struct p2p_data *p2p, const u8 *addr) 25968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 25978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct p2p_device *dev; 25988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 25998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt dev = p2p_get_device(p2p, addr); 26008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (dev == NULL) 26018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 26028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 26038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG, "P2P: Unauthorizing " MACSTR, 26048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt MAC2STR(addr)); 26058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 26068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (p2p->go_neg_peer == dev) 26078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p->go_neg_peer = NULL; 26088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 26098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt dev->wps_method = WPS_NOT_READY; 26108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt dev->flags &= ~P2P_DEV_WAIT_GO_NEG_RESPONSE; 26118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt dev->flags &= ~P2P_DEV_WAIT_GO_NEG_CONFIRM; 26128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 26138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* Check if after_scan_tx is for this peer. If so free it */ 26148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (p2p->after_scan_tx && 26158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memcmp(addr, p2p->after_scan_tx->dst, ETH_ALEN) == 0) { 26168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_free(p2p->after_scan_tx); 26178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p->after_scan_tx = NULL; 26188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 26198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 26208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 26218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 26228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 26238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 26248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtint p2p_set_dev_name(struct p2p_data *p2p, const char *dev_name) 26258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 26268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_free(p2p->cfg->dev_name); 26278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (dev_name) { 26288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p->cfg->dev_name = os_strdup(dev_name); 26298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (p2p->cfg->dev_name == NULL) 26308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 26318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } else 26328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p->cfg->dev_name = NULL; 26338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 26348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 26358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 26368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 26378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtint p2p_set_manufacturer(struct p2p_data *p2p, const char *manufacturer) 26388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 26398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_free(p2p->cfg->manufacturer); 26408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p->cfg->manufacturer = NULL; 26418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (manufacturer) { 26428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p->cfg->manufacturer = os_strdup(manufacturer); 26438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (p2p->cfg->manufacturer == NULL) 26448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 26458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 26468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 26478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 26488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 26498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 26508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 26518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtint p2p_set_model_name(struct p2p_data *p2p, const char *model_name) 26528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 26538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_free(p2p->cfg->model_name); 26548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p->cfg->model_name = NULL; 26558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (model_name) { 26568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p->cfg->model_name = os_strdup(model_name); 26578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (p2p->cfg->model_name == NULL) 26588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 26598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 26608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 26618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 26628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 26638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 26648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 26658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtint p2p_set_model_number(struct p2p_data *p2p, const char *model_number) 26668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 26678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_free(p2p->cfg->model_number); 26688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p->cfg->model_number = NULL; 26698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (model_number) { 26708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p->cfg->model_number = os_strdup(model_number); 26718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (p2p->cfg->model_number == NULL) 26728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 26738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 26748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 26758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 26768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 26778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 26788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 26798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtint p2p_set_serial_number(struct p2p_data *p2p, const char *serial_number) 26808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 26818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_free(p2p->cfg->serial_number); 26828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p->cfg->serial_number = NULL; 26838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (serial_number) { 26848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p->cfg->serial_number = os_strdup(serial_number); 26858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (p2p->cfg->serial_number == NULL) 26868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 26878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 26888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 26898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 26908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 26918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 26928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 26938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtvoid p2p_set_config_methods(struct p2p_data *p2p, u16 config_methods) 26948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 26958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p->cfg->config_methods = config_methods; 26968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 26978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 26988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 26998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtvoid p2p_set_uuid(struct p2p_data *p2p, const u8 *uuid) 27008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 27018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memcpy(p2p->cfg->uuid, uuid, 16); 27028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 27038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 27048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 27058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtint p2p_set_pri_dev_type(struct p2p_data *p2p, const u8 *pri_dev_type) 27068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 27078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memcpy(p2p->cfg->pri_dev_type, pri_dev_type, 8); 27088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 27098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 27108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 27118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 27128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtint p2p_set_sec_dev_types(struct p2p_data *p2p, const u8 dev_types[][8], 27138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt size_t num_dev_types) 27148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 27158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (num_dev_types > P2P_SEC_DEVICE_TYPES) 27168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt num_dev_types = P2P_SEC_DEVICE_TYPES; 27178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p->cfg->num_sec_dev_types = num_dev_types; 27188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memcpy(p2p->cfg->sec_dev_type, dev_types, num_dev_types * 8); 27198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 27208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 27218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 27228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 27238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtvoid p2p_remove_wps_vendor_extensions(struct p2p_data *p2p) 27248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 27258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt int i; 27268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 27278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt for (i = 0; i < P2P_MAX_WPS_VENDOR_EXT; i++) { 27288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpabuf_free(p2p->wps_vendor_ext[i]); 27298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p->wps_vendor_ext[i] = NULL; 27308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 27318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 27328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 27338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 27348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtint p2p_add_wps_vendor_extension(struct p2p_data *p2p, 27358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt const struct wpabuf *vendor_ext) 27368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 27378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt int i; 27388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 27398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (vendor_ext == NULL) 27408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 27418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 27428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt for (i = 0; i < P2P_MAX_WPS_VENDOR_EXT; i++) { 27438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (p2p->wps_vendor_ext[i] == NULL) 27448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 27458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 27468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (i >= P2P_MAX_WPS_VENDOR_EXT) 27478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 27488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 27498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p->wps_vendor_ext[i] = wpabuf_dup(vendor_ext); 27508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (p2p->wps_vendor_ext[i] == NULL) 27518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 27528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 27538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 27548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 27558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 27568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 27578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtint p2p_set_country(struct p2p_data *p2p, const char *country) 27588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 27598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memcpy(p2p->cfg->country, country, 3); 27608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 27618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 27628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 27638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 27648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtvoid p2p_continue_find(struct p2p_data *p2p) 27658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 27668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct p2p_device *dev; 2767f44b9c4a18d17fbd39901f76a014c32006570fb8Irfan Sheriff#ifdef ANDROID_P2P 2768f44b9c4a18d17fbd39901f76a014c32006570fb8Irfan Sheriff int skip=1; 2769f44b9c4a18d17fbd39901f76a014c32006570fb8Irfan Sheriff#endif 27708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_set_state(p2p, P2P_SEARCH); 27718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt dl_list_for_each(dev, &p2p->devices, struct p2p_device, list) { 2772f44b9c4a18d17fbd39901f76a014c32006570fb8Irfan Sheriff#ifdef ANDROID_P2P 2773f44b9c4a18d17fbd39901f76a014c32006570fb8Irfan Sheriff /* SD_FAIR_POLICY: We need to give chance to all devices in the device list 2774f44b9c4a18d17fbd39901f76a014c32006570fb8Irfan Sheriff * There may be a scenario, where a particular peer device have 2775f44b9c4a18d17fbd39901f76a014c32006570fb8Irfan Sheriff * not registered any query response. When we send a SD request to such device, 2776f44b9c4a18d17fbd39901f76a014c32006570fb8Irfan Sheriff * no response will be received. And if we continue to get probe responses from that device, 2777f44b9c4a18d17fbd39901f76a014c32006570fb8Irfan Sheriff * and if that device happens to be on top in our device list, 2778f44b9c4a18d17fbd39901f76a014c32006570fb8Irfan Sheriff * we will always continue to send SD requests always to that peer only. 2779f44b9c4a18d17fbd39901f76a014c32006570fb8Irfan Sheriff * We will not be able to send SD requests to other devices in that case. 2780f44b9c4a18d17fbd39901f76a014c32006570fb8Irfan Sheriff * This implementation keeps track of last serviced peer device. 2781f44b9c4a18d17fbd39901f76a014c32006570fb8Irfan Sheriff * And then takes the next one from the device list, in the next iteration. 2782f44b9c4a18d17fbd39901f76a014c32006570fb8Irfan Sheriff */ 2783f44b9c4a18d17fbd39901f76a014c32006570fb8Irfan Sheriff if (p2p->sd_dev_list && p2p->sd_dev_list != &p2p->devices) { 2784f44b9c4a18d17fbd39901f76a014c32006570fb8Irfan Sheriff if(skip) { 2785f44b9c4a18d17fbd39901f76a014c32006570fb8Irfan Sheriff if ((&dev->list == p2p->sd_dev_list) ) { 2786f44b9c4a18d17fbd39901f76a014c32006570fb8Irfan Sheriff skip = 0; 2787f44b9c4a18d17fbd39901f76a014c32006570fb8Irfan Sheriff if (dev->list.next == &p2p->devices) 2788f44b9c4a18d17fbd39901f76a014c32006570fb8Irfan Sheriff p2p->sd_dev_list = NULL; 2789f44b9c4a18d17fbd39901f76a014c32006570fb8Irfan Sheriff } 2790f44b9c4a18d17fbd39901f76a014c32006570fb8Irfan Sheriff continue; 2791f44b9c4a18d17fbd39901f76a014c32006570fb8Irfan Sheriff } 2792f44b9c4a18d17fbd39901f76a014c32006570fb8Irfan Sheriff } 2793f44b9c4a18d17fbd39901f76a014c32006570fb8Irfan Sheriff p2p->sd_dev_list = &dev->list; 2794f44b9c4a18d17fbd39901f76a014c32006570fb8Irfan Sheriff wpa_printf(MSG_DEBUG, "P2P: ### Servicing %p dev->flags 0x%x SD schedule %s devaddr " MACSTR, 2795f44b9c4a18d17fbd39901f76a014c32006570fb8Irfan Sheriff p2p->sd_dev_list, dev->flags, dev->flags & P2P_DEV_SD_SCHEDULE ? "TRUE": "FALSE", 2796f44b9c4a18d17fbd39901f76a014c32006570fb8Irfan Sheriff MAC2STR(dev->info.p2p_device_addr)); 2797f44b9c4a18d17fbd39901f76a014c32006570fb8Irfan Sheriff#endif 27988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (dev->flags & P2P_DEV_SD_SCHEDULE) { 27998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (p2p_start_sd(p2p, dev) == 0) 28008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; 28018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt else 28028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 28038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } else if (dev->req_config_methods && 28048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt !(dev->flags & P2P_DEV_PD_FOR_JOIN)) { 28058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG, "P2P: Send " 28061f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt "pending Provision Discovery Request to " 28078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt MACSTR " (config methods 0x%x)", 28088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt MAC2STR(dev->info.p2p_device_addr), 28098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt dev->req_config_methods); 28101f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt if (p2p_send_prov_disc_req(p2p, dev, 0, 0) == 0) 28118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; 28128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 28138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 28148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2815d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt p2p_listen_in_find(p2p, 1); 28168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 28178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 28188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 28198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic void p2p_sd_cb(struct p2p_data *p2p, int success) 28208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 28218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG, 28228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "P2P: Service Discovery Query TX callback: success=%d", 28238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt success); 28248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p->pending_action_state = P2P_NO_PENDING_ACTION; 28258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 28268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (!success) { 28278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (p2p->sd_peer) { 28288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p->sd_peer->flags &= ~P2P_DEV_SD_SCHEDULE; 28298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p->sd_peer = NULL; 28308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 28318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_continue_find(p2p); 28328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; 28338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 28348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 28358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (p2p->sd_peer == NULL) { 28368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG, 28378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "P2P: No SD peer entry known"); 28388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_continue_find(p2p); 28398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; 28408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 28418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 28428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* Wait for response from the peer */ 28438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_set_state(p2p, P2P_SD_DURING_FIND); 28448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_set_timeout(p2p, 0, 200000); 28458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 28468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 284775ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen 284875ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen/** 284975ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen * p2p_retry_pd - Retry any pending provision disc requests in IDLE state 285075ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen * @p2p: P2P module context from p2p_init() 285175ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen */ 28521f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidtstatic void p2p_retry_pd(struct p2p_data *p2p) 285375ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen{ 285475ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen struct p2p_device *dev; 285575ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen 285675ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen if (p2p->state != P2P_IDLE) 285775ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen return; 285875ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen 285975ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen /* 286075ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen * Retry the prov disc req attempt only for the peer that the user had 2861d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt * requested. 286275ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen */ 286375ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen 286475ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen dl_list_for_each(dev, &p2p->devices, struct p2p_device, list) { 286575ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen if (os_memcmp(p2p->pending_pd_devaddr, 286675ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen dev->info.p2p_device_addr, ETH_ALEN) != 0) 286775ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen continue; 286875ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen if (!dev->req_config_methods) 286975ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen continue; 287075ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen 287175ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG, "P2P: Send " 28721f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt "pending Provision Discovery Request to " 287375ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen MACSTR " (config methods 0x%x)", 287475ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen MAC2STR(dev->info.p2p_device_addr), 287575ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen dev->req_config_methods); 2876d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt p2p_send_prov_disc_req(p2p, dev, 2877d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt dev->flags & P2P_DEV_PD_FOR_JOIN, 0); 287875ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen return; 287975ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen } 288075ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen} 288175ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen 288275ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen 28838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic void p2p_prov_disc_cb(struct p2p_data *p2p, int success) 28848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 28858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG, 28868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "P2P: Provision Discovery Request TX callback: success=%d", 28878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt success); 288875ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen 288975ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen /* 289075ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen * Postpone resetting the pending action state till after we actually 289175ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen * time out. This allows us to take some action like notifying any 289275ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen * interested parties about no response to the request. 289375ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen * 289475ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen * When the timer (below) goes off we check in IDLE, SEARCH, or 289575ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen * LISTEN_ONLY state, which are the only allowed states to issue a PD 289675ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen * requests in, if this was still pending and then raise notification. 289775ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen */ 28988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 28998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (!success) { 290075ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen p2p->pending_action_state = P2P_NO_PENDING_ACTION; 290175ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen 290261d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt if (p2p->user_initiated_pd && 290361d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt (p2p->state == P2P_SEARCH || p2p->state == P2P_LISTEN_ONLY)) 290461d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt { 290561d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt /* Retry request from timeout to avoid busy loops */ 290661d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt p2p->pending_action_state = P2P_PENDING_PD; 290761d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt p2p_set_timeout(p2p, 0, 50000); 290861d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt } else if (p2p->state != P2P_IDLE) 29098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_continue_find(p2p); 291075ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen else if (p2p->user_initiated_pd) { 291175ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen p2p->pending_action_state = P2P_PENDING_PD; 29121a2ce111ade9563d99ed7bb8156d6148ffd6c3a3Irfan Sheriff#ifdef ANDROID_P2P 29131a2ce111ade9563d99ed7bb8156d6148ffd6c3a3Irfan Sheriff p2p_set_timeout(p2p, 0, 350000); 29141a2ce111ade9563d99ed7bb8156d6148ffd6c3a3Irfan Sheriff#else 291575ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen p2p_set_timeout(p2p, 0, 300000); 29161a2ce111ade9563d99ed7bb8156d6148ffd6c3a3Irfan Sheriff#endif 291775ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen } 29188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; 29198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 29208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 292175ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen /* 292275ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen * This postponing, of resetting pending_action_state, needs to be 292375ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen * done only for user initiated PD requests and not internal ones. 292475ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen */ 292575ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen if (p2p->user_initiated_pd) 292675ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen p2p->pending_action_state = P2P_PENDING_PD; 292775ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen else 292875ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen p2p->pending_action_state = P2P_NO_PENDING_ACTION; 292975ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen 29308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* Wait for response from the peer */ 29318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (p2p->state == P2P_SEARCH) 29328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_set_state(p2p, P2P_PD_DURING_FIND); 29331a2ce111ade9563d99ed7bb8156d6148ffd6c3a3Irfan Sheriff#ifdef ANDROID_P2P 29341a2ce111ade9563d99ed7bb8156d6148ffd6c3a3Irfan Sheriff p2p_set_timeout(p2p, 0, 350000); 29351a2ce111ade9563d99ed7bb8156d6148ffd6c3a3Irfan Sheriff#else 29368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_set_timeout(p2p, 0, 200000); 29371a2ce111ade9563d99ed7bb8156d6148ffd6c3a3Irfan Sheriff#endif 29388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 29398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 29408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 29418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtint p2p_scan_res_handler(struct p2p_data *p2p, const u8 *bssid, int freq, 2942f86232838cf712377867cb42417c1613ab5dc425Dmitry Shmidt struct os_time *rx_time, int level, const u8 *ies, 2943a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt size_t ies_len) 29448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 2945f86232838cf712377867cb42417c1613ab5dc425Dmitry Shmidt if (os_time_before(rx_time, &p2p->find_start)) { 2946f86232838cf712377867cb42417c1613ab5dc425Dmitry Shmidt /* 2947f86232838cf712377867cb42417c1613ab5dc425Dmitry Shmidt * The driver may have cached (e.g., in cfg80211 BSS table) the 2948f86232838cf712377867cb42417c1613ab5dc425Dmitry Shmidt * scan results for relatively long time. To avoid reporting 2949f86232838cf712377867cb42417c1613ab5dc425Dmitry Shmidt * stale information, update P2P peers only based on results 2950f86232838cf712377867cb42417c1613ab5dc425Dmitry Shmidt * that have based on frames received after the last p2p_find 2951f86232838cf712377867cb42417c1613ab5dc425Dmitry Shmidt * operation was started. 2952f86232838cf712377867cb42417c1613ab5dc425Dmitry Shmidt */ 2953f86232838cf712377867cb42417c1613ab5dc425Dmitry Shmidt wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG, "P2P: Ignore old scan " 2954f86232838cf712377867cb42417c1613ab5dc425Dmitry Shmidt "result for " MACSTR " (rx_time=%u.%06u)", 2955f86232838cf712377867cb42417c1613ab5dc425Dmitry Shmidt MAC2STR(bssid), (unsigned int) rx_time->sec, 2956f86232838cf712377867cb42417c1613ab5dc425Dmitry Shmidt (unsigned int) rx_time->usec); 2957f86232838cf712377867cb42417c1613ab5dc425Dmitry Shmidt return 0; 2958f86232838cf712377867cb42417c1613ab5dc425Dmitry Shmidt } 2959f86232838cf712377867cb42417c1613ab5dc425Dmitry Shmidt 2960f86232838cf712377867cb42417c1613ab5dc425Dmitry Shmidt p2p_add_device(p2p, bssid, freq, rx_time, level, ies, ies_len, 1); 29618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 29628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 29638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 29648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 29658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 29668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtvoid p2p_scan_res_handled(struct p2p_data *p2p) 29678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 29688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (!p2p->p2p_scan_running) { 29698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG, "P2P: p2p_scan was not " 29708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "running, but scan results received"); 29718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 29728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p->p2p_scan_running = 0; 29738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt eloop_cancel_timeout(p2p_scan_timeout, p2p, NULL); 29748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 29758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (p2p_run_after_scan(p2p)) 29768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; 29778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (p2p->state == P2P_SEARCH) 29788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_continue_find(p2p); 29798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 29808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 29818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2982c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidtvoid p2p_scan_ie(struct p2p_data *p2p, struct wpabuf *ies, const u8 *dev_id) 29838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 298461d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt u8 *len; 298561d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt 298661d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt#ifdef CONFIG_WIFI_DISPLAY 298761d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt if (p2p->wfd_ie_probe_req) 298861d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt wpabuf_put_buf(ies, p2p->wfd_ie_probe_req); 298961d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt#endif /* CONFIG_WIFI_DISPLAY */ 299061d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt 299161d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt len = p2p_buf_add_ie_hdr(ies); 299204949598a23f501be6eec21697465fd46a28840aDmitry Shmidt p2p_buf_add_capability(ies, p2p->dev_capab & 299304949598a23f501be6eec21697465fd46a28840aDmitry Shmidt ~P2P_DEV_CAPAB_CLIENT_DISCOVERABILITY, 0); 2994c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt if (dev_id) 2995c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt p2p_buf_add_device_id(ies, dev_id); 29968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (p2p->cfg->reg_class && p2p->cfg->channel) 29978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_buf_add_listen_channel(ies, p2p->cfg->country, 29988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p->cfg->reg_class, 29998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p->cfg->channel); 30008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (p2p->ext_listen_interval) 30018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_buf_add_ext_listen_timing(ies, p2p->ext_listen_period, 30028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p->ext_listen_interval); 30038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* TODO: p2p_buf_add_operating_channel() if GO */ 30048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_buf_update_ie_hdr(ies, len); 30058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 30068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 30078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 30081f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidtsize_t p2p_scan_ie_buf_len(struct p2p_data *p2p) 30091f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt{ 301061d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt size_t len = 100; 301161d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt 301261d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt#ifdef CONFIG_WIFI_DISPLAY 301361d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt if (p2p && p2p->wfd_ie_probe_req) 301461d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt len += wpabuf_len(p2p->wfd_ie_probe_req); 301561d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt#endif /* CONFIG_WIFI_DISPLAY */ 301661d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt 301761d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt return len; 30181f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt} 30191f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt 30201f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt 30218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtint p2p_ie_text(struct wpabuf *p2p_ie, char *buf, char *end) 30228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 30238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return p2p_attr_text(p2p_ie, buf, end); 30248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 30258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 30268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 30278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic void p2p_go_neg_req_cb(struct p2p_data *p2p, int success) 30288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 30298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct p2p_device *dev = p2p->go_neg_peer; 30308c65289885e84727226d81b3d32856f79c31ee5fDmitry Shmidt int timeout; 30318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 30328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG, 30338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "P2P: GO Negotiation Request TX callback: success=%d", 30348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt success); 30358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 30368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (dev == NULL) { 30378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG, 30388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "P2P: No pending GO Negotiation"); 30398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; 30408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 30418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 30428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (success) { 30438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (dev->flags & P2P_DEV_USER_REJECTED) { 30448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_set_state(p2p, P2P_IDLE); 30458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; 30468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 304704949598a23f501be6eec21697465fd46a28840aDmitry Shmidt } else if (dev->go_neg_req_sent) { 304804949598a23f501be6eec21697465fd46a28840aDmitry Shmidt /* Cancel the increment from p2p_connect_send() on failure */ 304998f9e76624da6bb96edc1982c423e4a119c5170aDmitry Shmidt dev->go_neg_req_sent--; 305098f9e76624da6bb96edc1982c423e4a119c5170aDmitry Shmidt } 30518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 30528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (!success && 30538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt (dev->info.dev_capab & P2P_DEV_CAPAB_CLIENT_DISCOVERABILITY) && 30548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt !is_zero_ether_addr(dev->member_in_go_dev)) { 30558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG, 30568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "P2P: Peer " MACSTR " did not acknowledge request - " 30578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "try to use device discoverability through its GO", 30588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt MAC2STR(dev->info.p2p_device_addr)); 30598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p->cfg->send_action_done(p2p->cfg->cb_ctx); 30608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_send_dev_disc_req(p2p, dev); 30618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; 30628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 30638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 30648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* 30658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * Use P2P find, if needed, to find the other device from its listen 30668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * channel. 30678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */ 30688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_set_state(p2p, P2P_CONNECT); 30698c65289885e84727226d81b3d32856f79c31ee5fDmitry Shmidt timeout = success ? 500000 : 100000; 30708c65289885e84727226d81b3d32856f79c31ee5fDmitry Shmidt if (!success && p2p->go_neg_peer && 30718c65289885e84727226d81b3d32856f79c31ee5fDmitry Shmidt (p2p->go_neg_peer->flags & P2P_DEV_PEER_WAITING_RESPONSE)) { 30728c65289885e84727226d81b3d32856f79c31ee5fDmitry Shmidt unsigned int r; 30738c65289885e84727226d81b3d32856f79c31ee5fDmitry Shmidt /* 30748c65289885e84727226d81b3d32856f79c31ee5fDmitry Shmidt * Peer is expected to wait our response and we will skip the 30758c65289885e84727226d81b3d32856f79c31ee5fDmitry Shmidt * listen phase. Add some randomness to the wait time here to 30768c65289885e84727226d81b3d32856f79c31ee5fDmitry Shmidt * make it less likely to hit cases where we could end up in 30778c65289885e84727226d81b3d32856f79c31ee5fDmitry Shmidt * sync with peer not listening. 30788c65289885e84727226d81b3d32856f79c31ee5fDmitry Shmidt */ 30798c65289885e84727226d81b3d32856f79c31ee5fDmitry Shmidt os_get_random((u8 *) &r, sizeof(r)); 30808c65289885e84727226d81b3d32856f79c31ee5fDmitry Shmidt timeout += r % 100000; 30818c65289885e84727226d81b3d32856f79c31ee5fDmitry Shmidt } 30828c65289885e84727226d81b3d32856f79c31ee5fDmitry Shmidt p2p_set_timeout(p2p, 0, timeout); 30838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 30848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 30858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 30868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic void p2p_go_neg_resp_cb(struct p2p_data *p2p, int success) 30878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 30888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG, 30898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "P2P: GO Negotiation Response TX callback: success=%d", 30908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt success); 30918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (!p2p->go_neg_peer && p2p->state == P2P_PROVISIONING) { 30928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG, 30938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "P2P: Ignore TX callback event - GO Negotiation is " 30948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "not running anymore"); 30958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; 30968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 30978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_set_state(p2p, P2P_CONNECT); 30988c65289885e84727226d81b3d32856f79c31ee5fDmitry Shmidt p2p_set_timeout(p2p, 0, 500000); 30998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 31008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 31018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 31028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic void p2p_go_neg_resp_failure_cb(struct p2p_data *p2p, int success) 31038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 31048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG, 31058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "P2P: GO Negotiation Response (failure) TX callback: " 31068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "success=%d", success); 31078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (p2p->go_neg_peer && p2p->go_neg_peer->status != P2P_SC_SUCCESS) { 31088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_go_neg_failed(p2p, p2p->go_neg_peer, 31098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p->go_neg_peer->status); 31108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 31118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 31128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 31138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 31148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic void p2p_go_neg_conf_cb(struct p2p_data *p2p, 31158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt enum p2p_send_action_result result) 31168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 31178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct p2p_device *dev; 31188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 31198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG, 31208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "P2P: GO Negotiation Confirm TX callback: result=%d", 31218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt result); 31228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p->cfg->send_action_done(p2p->cfg->cb_ctx); 31238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (result == P2P_SEND_ACTION_FAILED) { 31248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_go_neg_failed(p2p, p2p->go_neg_peer, -1); 31258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; 31268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 31278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (result == P2P_SEND_ACTION_NO_ACK) { 31288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* 31298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * It looks like the TX status for GO Negotiation Confirm is 31308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * often showing failure even when the peer has actually 31318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * received the frame. Since the peer may change channels 31328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * immediately after having received the frame, we may not see 31338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * an Ack for retries, so just dropping a single frame may 31348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * trigger this. To allow the group formation to succeed if the 31358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * peer did indeed receive the frame, continue regardless of 31368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * the TX status. 31378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */ 31388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG, 31398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "P2P: Assume GO Negotiation Confirm TX was actually " 31408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "received by the peer even though Ack was not " 31418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "reported"); 31428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 31438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 31448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt dev = p2p->go_neg_peer; 31458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (dev == NULL) 31468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; 31478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 31488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_go_complete(p2p, dev); 31498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 31508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 31518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 31528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtvoid p2p_send_action_cb(struct p2p_data *p2p, unsigned int freq, const u8 *dst, 31538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt const u8 *src, const u8 *bssid, 31548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt enum p2p_send_action_result result) 31558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 31568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt enum p2p_pending_action_state state; 31578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt int success; 31588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 31598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG, 31608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "P2P: Action frame TX callback (state=%d freq=%u dst=" MACSTR 31618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt " src=" MACSTR " bssid=" MACSTR " result=%d", 31628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p->pending_action_state, freq, MAC2STR(dst), MAC2STR(src), 31638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt MAC2STR(bssid), result); 31648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt success = result == P2P_SEND_ACTION_SUCCESS; 31658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt state = p2p->pending_action_state; 31668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p->pending_action_state = P2P_NO_PENDING_ACTION; 31678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt switch (state) { 31688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case P2P_NO_PENDING_ACTION: 31698da800a193fb6f8832218715f82a7b4e2d2ad338Dmitry Shmidt if (p2p->after_scan_tx_in_progress) { 31708da800a193fb6f8832218715f82a7b4e2d2ad338Dmitry Shmidt p2p->after_scan_tx_in_progress = 0; 31718da800a193fb6f8832218715f82a7b4e2d2ad338Dmitry Shmidt if (p2p->start_after_scan != P2P_AFTER_SCAN_NOTHING && 31728da800a193fb6f8832218715f82a7b4e2d2ad338Dmitry Shmidt p2p_run_after_scan(p2p)) 31738da800a193fb6f8832218715f82a7b4e2d2ad338Dmitry Shmidt break; 31748da800a193fb6f8832218715f82a7b4e2d2ad338Dmitry Shmidt if (p2p->state == P2P_SEARCH) { 31758da800a193fb6f8832218715f82a7b4e2d2ad338Dmitry Shmidt wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG, 31768da800a193fb6f8832218715f82a7b4e2d2ad338Dmitry Shmidt "P2P: Continue find after " 31778da800a193fb6f8832218715f82a7b4e2d2ad338Dmitry Shmidt "after_scan_tx completion"); 31788da800a193fb6f8832218715f82a7b4e2d2ad338Dmitry Shmidt p2p_continue_find(p2p); 31798da800a193fb6f8832218715f82a7b4e2d2ad338Dmitry Shmidt } 31808da800a193fb6f8832218715f82a7b4e2d2ad338Dmitry Shmidt } 31818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 31828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case P2P_PENDING_GO_NEG_REQUEST: 31838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_go_neg_req_cb(p2p, success); 31848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 31858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case P2P_PENDING_GO_NEG_RESPONSE: 31868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_go_neg_resp_cb(p2p, success); 31878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 31888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case P2P_PENDING_GO_NEG_RESPONSE_FAILURE: 31898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_go_neg_resp_failure_cb(p2p, success); 31908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 31918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case P2P_PENDING_GO_NEG_CONFIRM: 31928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_go_neg_conf_cb(p2p, result); 31938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 31948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case P2P_PENDING_SD: 31958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_sd_cb(p2p, success); 31968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 31978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case P2P_PENDING_PD: 31988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_prov_disc_cb(p2p, success); 31998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 32008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case P2P_PENDING_INVITATION_REQUEST: 32018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_invitation_req_cb(p2p, success); 32028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 32038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case P2P_PENDING_INVITATION_RESPONSE: 32048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_invitation_resp_cb(p2p, success); 32058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 32068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case P2P_PENDING_DEV_DISC_REQUEST: 32078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_dev_disc_req_cb(p2p, success); 32088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 32098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case P2P_PENDING_DEV_DISC_RESPONSE: 32108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_dev_disc_resp_cb(p2p, success); 32118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 32128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case P2P_PENDING_GO_DISC_REQ: 32138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_go_disc_req_cb(p2p, success); 32148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 32158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 32168da800a193fb6f8832218715f82a7b4e2d2ad338Dmitry Shmidt 32178da800a193fb6f8832218715f82a7b4e2d2ad338Dmitry Shmidt p2p->after_scan_tx_in_progress = 0; 32188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 32198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 32208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 32218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtvoid p2p_listen_cb(struct p2p_data *p2p, unsigned int freq, 32228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt unsigned int duration) 32238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 32248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (freq == p2p->pending_client_disc_freq) { 32258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG, 32268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "P2P: Client discoverability remain-awake completed"); 32278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p->pending_client_disc_freq = 0; 32288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; 32298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 32308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 32318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (freq != p2p->pending_listen_freq) { 32328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG, 32338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "P2P: Unexpected listen callback for freq=%u " 32348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "duration=%u (pending_listen_freq=%u)", 32358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt freq, duration, p2p->pending_listen_freq); 32368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; 32378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 32388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 32398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG, 32408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "P2P: Starting Listen timeout(%u,%u) on freq=%u based on " 32418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "callback", 32428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p->pending_listen_sec, p2p->pending_listen_usec, 32438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p->pending_listen_freq); 32448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p->in_listen = 1; 32458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p->drv_in_listen = freq; 32468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (p2p->pending_listen_sec || p2p->pending_listen_usec) { 32478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* 32488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * Add 20 msec extra wait to avoid race condition with driver 32498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * remain-on-channel end event, i.e., give driver more time to 32508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * complete the operation before our timeout expires. 32518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */ 32528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_set_timeout(p2p, p2p->pending_listen_sec, 32538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p->pending_listen_usec + 20000); 32548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 32558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 32568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p->pending_listen_freq = 0; 32578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 32588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 32598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 32608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtint p2p_listen_end(struct p2p_data *p2p, unsigned int freq) 32618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 32628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG, "P2P: Driver ended Listen " 32638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "state (freq=%u)", freq); 32648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p->drv_in_listen = 0; 32658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (p2p->in_listen) 32668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; /* Internal timeout will trigger the next step */ 32678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 32688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (p2p->state == P2P_CONNECT_LISTEN && p2p->go_neg_peer) { 32698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (p2p->go_neg_peer->connect_reqs >= 120) { 32708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG, 32718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "P2P: Timeout on sending GO Negotiation " 32728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "Request without getting response"); 32738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_go_neg_failed(p2p, p2p->go_neg_peer, -1); 32748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 32758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 32768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 32778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_set_state(p2p, P2P_CONNECT); 32788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_connect_send(p2p, p2p->go_neg_peer); 32798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 1; 32808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } else if (p2p->state == P2P_SEARCH) { 3281c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt if (p2p->p2p_scan_running) { 3282c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt /* 3283c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt * Search is already in progress. This can happen if 3284c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt * an Action frame RX is reported immediately after 3285c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt * the end of a remain-on-channel operation and the 3286c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt * response frame to that is sent using an offchannel 3287c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt * operation while in p2p_find. Avoid an attempt to 3288c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt * restart a scan here. 3289c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt */ 3290c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG, "P2P: p2p_scan " 3291c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt "already in progress - do not try to start a " 3292c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt "new one"); 3293c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt return 1; 3294c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt } 329504949598a23f501be6eec21697465fd46a28840aDmitry Shmidt if (p2p->pending_listen_freq) { 329604949598a23f501be6eec21697465fd46a28840aDmitry Shmidt /* 329704949598a23f501be6eec21697465fd46a28840aDmitry Shmidt * Better wait a bit if the driver is unable to start 329804949598a23f501be6eec21697465fd46a28840aDmitry Shmidt * offchannel operation for some reason. p2p_search() 329904949598a23f501be6eec21697465fd46a28840aDmitry Shmidt * will be started from internal timeout. 330004949598a23f501be6eec21697465fd46a28840aDmitry Shmidt */ 330104949598a23f501be6eec21697465fd46a28840aDmitry Shmidt wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG, "P2P: Listen " 330204949598a23f501be6eec21697465fd46a28840aDmitry Shmidt "operation did not seem to start - delay " 330304949598a23f501be6eec21697465fd46a28840aDmitry Shmidt "search phase to avoid busy loop"); 330404949598a23f501be6eec21697465fd46a28840aDmitry Shmidt p2p_set_timeout(p2p, 0, 100000); 330504949598a23f501be6eec21697465fd46a28840aDmitry Shmidt return 1; 330604949598a23f501be6eec21697465fd46a28840aDmitry Shmidt } 330761d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt if (p2p->search_delay) { 330861d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG, "P2P: Delay " 330961d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt "search operation by %u ms", 331061d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt p2p->search_delay); 331161d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt p2p_set_timeout(p2p, p2p->search_delay / 1000, 331261d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt (p2p->search_delay % 1000) * 1000); 331361d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt return 1; 331461d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt } 33158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_search(p2p); 33168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 1; 33178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 33188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 33198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 33208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 33218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 33228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 33238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic void p2p_timeout_connect(struct p2p_data *p2p) 33248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 33258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p->cfg->send_action_done(p2p->cfg->cb_ctx); 332604949598a23f501be6eec21697465fd46a28840aDmitry Shmidt if (p2p->go_neg_peer && 332704949598a23f501be6eec21697465fd46a28840aDmitry Shmidt (p2p->go_neg_peer->flags & P2P_DEV_WAIT_GO_NEG_CONFIRM)) { 332804949598a23f501be6eec21697465fd46a28840aDmitry Shmidt wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG, "P2P: Wait for GO " 332904949598a23f501be6eec21697465fd46a28840aDmitry Shmidt "Negotiation Confirm timed out - assume GO " 333004949598a23f501be6eec21697465fd46a28840aDmitry Shmidt "Negotiation failed"); 333104949598a23f501be6eec21697465fd46a28840aDmitry Shmidt p2p_go_neg_failed(p2p, p2p->go_neg_peer, -1); 333204949598a23f501be6eec21697465fd46a28840aDmitry Shmidt return; 333304949598a23f501be6eec21697465fd46a28840aDmitry Shmidt } 33348c65289885e84727226d81b3d32856f79c31ee5fDmitry Shmidt if (p2p->go_neg_peer && 33358c65289885e84727226d81b3d32856f79c31ee5fDmitry Shmidt (p2p->go_neg_peer->flags & P2P_DEV_PEER_WAITING_RESPONSE) && 33368c65289885e84727226d81b3d32856f79c31ee5fDmitry Shmidt p2p->go_neg_peer->connect_reqs < 120) { 33378c65289885e84727226d81b3d32856f79c31ee5fDmitry Shmidt wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG, "P2P: Peer expected to " 33388c65289885e84727226d81b3d32856f79c31ee5fDmitry Shmidt "wait our response - skip listen"); 33398c65289885e84727226d81b3d32856f79c31ee5fDmitry Shmidt p2p_connect_send(p2p, p2p->go_neg_peer); 33408c65289885e84727226d81b3d32856f79c31ee5fDmitry Shmidt return; 33418c65289885e84727226d81b3d32856f79c31ee5fDmitry Shmidt } 33428c65289885e84727226d81b3d32856f79c31ee5fDmitry Shmidt 33438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_set_state(p2p, P2P_CONNECT_LISTEN); 3344d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt p2p_listen_in_find(p2p, 0); 33458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 33468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 33478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 33488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic void p2p_timeout_connect_listen(struct p2p_data *p2p) 33498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 33508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (p2p->go_neg_peer) { 33518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (p2p->drv_in_listen) { 33528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG, "P2P: Driver is " 33538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "still in Listen state; wait for it to " 33548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "complete"); 33558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; 33568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 33578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 33588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (p2p->go_neg_peer->connect_reqs >= 120) { 33598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG, 33608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "P2P: Timeout on sending GO Negotiation " 33618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "Request without getting response"); 33628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_go_neg_failed(p2p, p2p->go_neg_peer, -1); 33638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; 33648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 33658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 33668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_set_state(p2p, P2P_CONNECT); 33678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_connect_send(p2p, p2p->go_neg_peer); 33688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } else 33698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_set_state(p2p, P2P_IDLE); 33708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 33718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 33728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 33738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic void p2p_timeout_wait_peer_connect(struct p2p_data *p2p) 33748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 33758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* 33768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * TODO: could remain constantly in Listen state for some time if there 33778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * are no other concurrent uses for the radio. For now, go to listen 33788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * state once per second to give other uses a chance to use the radio. 33798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */ 33808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_set_state(p2p, P2P_WAIT_PEER_IDLE); 33811f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt p2p_set_timeout(p2p, 0, 500000); 33828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 33838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 33848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 33858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic void p2p_timeout_wait_peer_idle(struct p2p_data *p2p) 33868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 33878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct p2p_device *dev = p2p->go_neg_peer; 33888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 33898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (dev == NULL) { 33908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG, 33918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "P2P: Unknown GO Neg peer - stop GO Neg wait"); 33928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; 33938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 33948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 33958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt dev->wait_count++; 33968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (dev->wait_count >= 120) { 33978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG, 33988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "P2P: Timeout on waiting peer to become ready for GO " 33998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "Negotiation"); 34008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_go_neg_failed(p2p, dev, -1); 34018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; 34028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 34038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 34048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG, 34058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "P2P: Go to Listen state while waiting for the peer to become " 34068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "ready for GO Negotiation"); 34078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_set_state(p2p, P2P_WAIT_PEER_CONNECT); 3408d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt p2p_listen_in_find(p2p, 0); 34098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 34108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 34118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 34128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic void p2p_timeout_sd_during_find(struct p2p_data *p2p) 34138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 34148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG, 34158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "P2P: Service Discovery Query timeout"); 34168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (p2p->sd_peer) { 34178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p->cfg->send_action_done(p2p->cfg->cb_ctx); 34188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p->sd_peer->flags &= ~P2P_DEV_SD_SCHEDULE; 34198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p->sd_peer = NULL; 34208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 34218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_continue_find(p2p); 34228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 34238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 34248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 34258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic void p2p_timeout_prov_disc_during_find(struct p2p_data *p2p) 34268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 34278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG, 34288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "P2P: Provision Discovery Request timeout"); 34298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p->cfg->send_action_done(p2p->cfg->cb_ctx); 34308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_continue_find(p2p); 34318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 34328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 34338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 343475ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinenstatic void p2p_timeout_prov_disc_req(struct p2p_data *p2p) 343575ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen{ 343675ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen p2p->pending_action_state = P2P_NO_PENDING_ACTION; 343775ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen 343875ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen /* 343975ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen * For user initiated PD requests that we have not gotten any responses 344075ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen * for while in IDLE state, we retry them a couple of times before 344175ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen * giving up. 344275ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen */ 344375ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen if (!p2p->user_initiated_pd) 344475ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen return; 344575ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen 344675ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG, 344775ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen "P2P: User initiated Provision Discovery Request timeout"); 344875ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen 344975ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen if (p2p->pd_retries) { 345075ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen p2p->pd_retries--; 345175ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen p2p_retry_pd(p2p); 345275ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen } else { 3453d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt struct p2p_device *dev; 3454d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt int for_join = 0; 3455d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt 3456d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt dl_list_for_each(dev, &p2p->devices, struct p2p_device, list) { 3457d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt if (os_memcmp(p2p->pending_pd_devaddr, 3458d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt dev->info.p2p_device_addr, ETH_ALEN) != 0) 3459d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt continue; 3460d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt if (dev->req_config_methods && 3461d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt (dev->flags & P2P_DEV_PD_FOR_JOIN)) 3462d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt for_join = 1; 3463d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt } 3464d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt 346575ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen if (p2p->cfg->prov_disc_fail) 346675ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen p2p->cfg->prov_disc_fail(p2p->cfg->cb_ctx, 346775ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen p2p->pending_pd_devaddr, 3468d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt for_join ? 3469d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt P2P_PROV_DISC_TIMEOUT_JOIN : 347075ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen P2P_PROV_DISC_TIMEOUT); 347175ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen p2p_reset_pending_pd(p2p); 347275ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen } 347375ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen} 347475ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen 347575ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen 34768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic void p2p_timeout_invite(struct p2p_data *p2p) 34778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 34788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p->cfg->send_action_done(p2p->cfg->cb_ctx); 34798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_set_state(p2p, P2P_INVITE_LISTEN); 34808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (p2p->inv_role == P2P_INVITE_ROLE_ACTIVE_GO) { 34818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* 34828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * Better remain on operating channel instead of listen channel 34838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * when running a group. 34848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */ 34858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG, "P2P: Inviting in " 34868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "active GO role - wait on operating channel"); 34878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_set_timeout(p2p, 0, 100000); 34888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; 34898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 3490d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt p2p_listen_in_find(p2p, 0); 34918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 34928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 34938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 34948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic void p2p_timeout_invite_listen(struct p2p_data *p2p) 34958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 34968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (p2p->invite_peer && p2p->invite_peer->invitation_reqs < 100) { 34978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_set_state(p2p, P2P_INVITE); 34988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_invite_send(p2p, p2p->invite_peer, 34998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p->invite_go_dev_addr); 35008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } else { 35018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (p2p->invite_peer) { 35028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG, 35038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "P2P: Invitation Request retry limit reached"); 35048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (p2p->cfg->invitation_result) 35058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p->cfg->invitation_result( 3506700a137ab366edc72e371da68ba187b4717ee660Dmitry Shmidt p2p->cfg->cb_ctx, -1, NULL, NULL, 3507700a137ab366edc72e371da68ba187b4717ee660Dmitry Shmidt p2p->invite_peer->info.p2p_device_addr); 35088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 35098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_set_state(p2p, P2P_IDLE); 35108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 35118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 35128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 35138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 35148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic void p2p_state_timeout(void *eloop_ctx, void *timeout_ctx) 35158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 35168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct p2p_data *p2p = eloop_ctx; 35178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 35188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG, "P2P: Timeout (state=%s)", 35198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_state_txt(p2p->state)); 35208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 35218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p->in_listen = 0; 35228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 35238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt switch (p2p->state) { 35248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case P2P_IDLE: 352575ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen /* Check if we timed out waiting for PD req */ 352675ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen if (p2p->pending_action_state == P2P_PENDING_PD) 352775ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen p2p_timeout_prov_disc_req(p2p); 35288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 35298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case P2P_SEARCH: 353075ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen /* Check if we timed out waiting for PD req */ 353175ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen if (p2p->pending_action_state == P2P_PENDING_PD) 353275ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen p2p_timeout_prov_disc_req(p2p); 353361d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt if (p2p->search_delay && !p2p->in_search_delay) { 353461d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG, "P2P: Delay " 353561d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt "search operation by %u ms", 353661d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt p2p->search_delay); 353761d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt p2p->in_search_delay = 1; 353861d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt p2p_set_timeout(p2p, p2p->search_delay / 1000, 353961d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt (p2p->search_delay % 1000) * 1000); 354061d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt break; 354161d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt } 354261d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt p2p->in_search_delay = 0; 35438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_search(p2p); 35448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 35458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case P2P_CONNECT: 35468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_timeout_connect(p2p); 35478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 35488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case P2P_CONNECT_LISTEN: 35498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_timeout_connect_listen(p2p); 35508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 35518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case P2P_GO_NEG: 35528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 35538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case P2P_LISTEN_ONLY: 355475ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen /* Check if we timed out waiting for PD req */ 355575ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen if (p2p->pending_action_state == P2P_PENDING_PD) 355675ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen p2p_timeout_prov_disc_req(p2p); 355775ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen 35588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (p2p->ext_listen_only) { 35598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG, 35608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "P2P: Extended Listen Timing - Listen State " 35618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "completed"); 35628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p->ext_listen_only = 0; 35638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_set_state(p2p, P2P_IDLE); 35648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 35658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 35668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case P2P_WAIT_PEER_CONNECT: 35678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_timeout_wait_peer_connect(p2p); 35688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 35698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case P2P_WAIT_PEER_IDLE: 35708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_timeout_wait_peer_idle(p2p); 35718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 35728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case P2P_SD_DURING_FIND: 35738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_timeout_sd_during_find(p2p); 35748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 35758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case P2P_PROVISIONING: 35768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 35778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case P2P_PD_DURING_FIND: 35788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_timeout_prov_disc_during_find(p2p); 35798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 35808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case P2P_INVITE: 35818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_timeout_invite(p2p); 35828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 35838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case P2P_INVITE_LISTEN: 35848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_timeout_invite_listen(p2p); 35858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 35861f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt case P2P_SEARCH_WHEN_READY: 35871f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt break; 358861d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt case P2P_CONTINUE_SEARCH_WHEN_READY: 358961d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt break; 35908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 35918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 35928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 35938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 35948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtint p2p_reject(struct p2p_data *p2p, const u8 *peer_addr) 35958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 35968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct p2p_device *dev; 35978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 35988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt dev = p2p_get_device(p2p, peer_addr); 35998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG, "P2P: Local request to reject " 36008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "connection attempts by peer " MACSTR, MAC2STR(peer_addr)); 36018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (dev == NULL) { 36028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG, "P2P: Peer " MACSTR 36038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt " unknown", MAC2STR(peer_addr)); 36048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 36058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 36068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt dev->status = P2P_SC_FAIL_REJECTED_BY_USER; 36078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt dev->flags |= P2P_DEV_USER_REJECTED; 36088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 36098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 36108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 36118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 36121f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidtconst char * p2p_wps_method_text(enum p2p_wps_method method) 36138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 36148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt switch (method) { 36158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case WPS_NOT_READY: 36168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return "not-ready"; 36178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case WPS_PIN_DISPLAY: 36188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return "Display"; 36198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case WPS_PIN_KEYPAD: 36208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return "Keypad"; 36218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case WPS_PBC: 36228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return "PBC"; 36238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 36248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 36258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return "??"; 36268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 36278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 36288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 36298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic const char * p2p_go_state_text(enum p2p_go_state go_state) 36308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 36318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt switch (go_state) { 36328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case UNKNOWN_GO: 36338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return "unknown"; 36348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case LOCAL_GO: 36358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return "local"; 36368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case REMOTE_GO: 36378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return "remote"; 36388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 36398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 36408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return "??"; 36418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 36428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 36438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 36441f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidtconst struct p2p_peer_info * p2p_get_peer_info(struct p2p_data *p2p, 36451f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt const u8 *addr, int next) 36468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 36478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct p2p_device *dev; 36488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 36498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (addr) 36508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt dev = p2p_get_device(p2p, addr); 36518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt else 36528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt dev = dl_list_first(&p2p->devices, struct p2p_device, list); 36538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 36548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (dev && next) { 36558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt dev = dl_list_first(&dev->list, struct p2p_device, list); 36568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (&dev->list == &p2p->devices) 36578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt dev = NULL; 36588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 36598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 36608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (dev == NULL) 36611f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt return NULL; 36621f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt 36631f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt return &dev->info; 36641f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt} 36651f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt 36661f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt 36671f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidtint p2p_get_peer_info_txt(const struct p2p_peer_info *info, 36681f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt char *buf, size_t buflen) 36691f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt{ 36701f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt struct p2p_device *dev; 36711f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt int res; 36721f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt char *pos, *end; 36731f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt struct os_time now; 36741f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt 36751f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt if (info == NULL) 36768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 36778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 36781f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt dev = (struct p2p_device *) (((u8 *) info) - 36791f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt offsetof(struct p2p_device, info)); 36801f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt 36818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt pos = buf; 36828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt end = buf + buflen; 36838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 36848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_get_time(&now); 36858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt res = os_snprintf(pos, end - pos, 36868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "age=%d\n" 36878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "listen_freq=%d\n" 36888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "wps_method=%s\n" 36898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "interface_addr=" MACSTR "\n" 36908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "member_in_go_dev=" MACSTR "\n" 36918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "member_in_go_iface=" MACSTR "\n" 36928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "go_neg_req_sent=%d\n" 36938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "go_state=%s\n" 36948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "dialog_token=%u\n" 36958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "intended_addr=" MACSTR "\n" 36968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "country=%c%c\n" 36978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "oper_freq=%d\n" 36988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "req_config_methods=0x%x\n" 36998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "flags=%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s\n" 37008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "status=%d\n" 37018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "wait_count=%u\n" 37028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "invitation_reqs=%u\n", 37038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt (int) (now.sec - dev->last_seen.sec), 37048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt dev->listen_freq, 37058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_wps_method_text(dev->wps_method), 37068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt MAC2STR(dev->interface_addr), 37078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt MAC2STR(dev->member_in_go_dev), 37088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt MAC2STR(dev->member_in_go_iface), 37098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt dev->go_neg_req_sent, 37108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_go_state_text(dev->go_state), 37118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt dev->dialog_token, 37128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt MAC2STR(dev->intended_addr), 37138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt dev->country[0] ? dev->country[0] : '_', 37148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt dev->country[1] ? dev->country[1] : '_', 37158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt dev->oper_freq, 37168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt dev->req_config_methods, 37178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt dev->flags & P2P_DEV_PROBE_REQ_ONLY ? 37188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "[PROBE_REQ_ONLY]" : "", 37198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt dev->flags & P2P_DEV_REPORTED ? "[REPORTED]" : "", 37208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt dev->flags & P2P_DEV_NOT_YET_READY ? 37218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "[NOT_YET_READY]" : "", 37228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt dev->flags & P2P_DEV_SD_INFO ? "[SD_INFO]" : "", 37238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt dev->flags & P2P_DEV_SD_SCHEDULE ? "[SD_SCHEDULE]" : 37248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "", 37258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt dev->flags & P2P_DEV_PD_PEER_DISPLAY ? 37268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "[PD_PEER_DISPLAY]" : "", 37278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt dev->flags & P2P_DEV_PD_PEER_KEYPAD ? 37288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "[PD_PEER_KEYPAD]" : "", 37298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt dev->flags & P2P_DEV_USER_REJECTED ? 37308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "[USER_REJECTED]" : "", 37318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt dev->flags & P2P_DEV_PEER_WAITING_RESPONSE ? 37328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "[PEER_WAITING_RESPONSE]" : "", 37338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt dev->flags & P2P_DEV_PREFER_PERSISTENT_GROUP ? 37348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "[PREFER_PERSISTENT_GROUP]" : "", 37358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt dev->flags & P2P_DEV_WAIT_GO_NEG_RESPONSE ? 37368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "[WAIT_GO_NEG_RESPONSE]" : "", 37378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt dev->flags & P2P_DEV_WAIT_GO_NEG_CONFIRM ? 37388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "[WAIT_GO_NEG_CONFIRM]" : "", 37398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt dev->flags & P2P_DEV_GROUP_CLIENT_ONLY ? 37408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "[GROUP_CLIENT_ONLY]" : "", 37418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt dev->flags & P2P_DEV_FORCE_FREQ ? 37428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "[FORCE_FREQ]" : "", 37438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt dev->flags & P2P_DEV_PD_FOR_JOIN ? 37448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "[PD_FOR_JOIN]" : "", 37458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt dev->status, 37468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt dev->wait_count, 37478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt dev->invitation_reqs); 37488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (res < 0 || res >= end - pos) 37498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return pos - buf; 37508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt pos += res; 37518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 37528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (dev->ext_listen_period) { 37538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt res = os_snprintf(pos, end - pos, 37548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "ext_listen_period=%u\n" 37558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "ext_listen_interval=%u\n", 37568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt dev->ext_listen_period, 37578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt dev->ext_listen_interval); 37588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (res < 0 || res >= end - pos) 37598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return pos - buf; 37608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt pos += res; 37618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 37628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 37638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (dev->oper_ssid_len) { 37648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt res = os_snprintf(pos, end - pos, 37658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "oper_ssid=%s\n", 37668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_ssid_txt(dev->oper_ssid, 37678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt dev->oper_ssid_len)); 37688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (res < 0 || res >= end - pos) 37698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return pos - buf; 37708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt pos += res; 37718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 37728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 377361d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt#ifdef CONFIG_WIFI_DISPLAY 377461d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt if (dev->info.wfd_subelems) { 377561d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt res = os_snprintf(pos, end - pos, "wfd_subelems="); 377661d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt if (res < 0 || res >= end - pos) 377761d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt return pos - buf; 377861d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt pos += res; 377961d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt 378061d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt pos += wpa_snprintf_hex(pos, end - pos, 378161d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt wpabuf_head(dev->info.wfd_subelems), 378261d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt wpabuf_len(dev->info.wfd_subelems)); 378361d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt 378461d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt res = os_snprintf(pos, end - pos, "\n"); 378561d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt if (res < 0 || res >= end - pos) 378661d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt return pos - buf; 378761d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt pos += res; 378861d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt } 378961d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt#endif /* CONFIG_WIFI_DISPLAY */ 379061d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt 37918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return pos - buf; 37928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 37938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 37948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 37951f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidtint p2p_peer_known(struct p2p_data *p2p, const u8 *addr) 37961f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt{ 37971f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt return p2p_get_device(p2p, addr) != NULL; 37981f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt} 37991f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt 38001f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt 38018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtvoid p2p_set_client_discoverability(struct p2p_data *p2p, int enabled) 38028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 38038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (enabled) { 38048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG, "P2P: Client " 38058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "discoverability enabled"); 38068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p->dev_capab |= P2P_DEV_CAPAB_CLIENT_DISCOVERABILITY; 38078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } else { 38088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG, "P2P: Client " 38098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "discoverability disabled"); 38108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p->dev_capab &= ~P2P_DEV_CAPAB_CLIENT_DISCOVERABILITY; 38118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 38128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 38138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 38148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 38158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic struct wpabuf * p2p_build_presence_req(u32 duration1, u32 interval1, 38168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt u32 duration2, u32 interval2) 38178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 38188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct wpabuf *req; 38198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct p2p_noa_desc desc1, desc2, *ptr1 = NULL, *ptr2 = NULL; 38208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt u8 *len; 38218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 38228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt req = wpabuf_alloc(100); 38238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (req == NULL) 38248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return NULL; 38258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 38268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (duration1 || interval1) { 38278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memset(&desc1, 0, sizeof(desc1)); 38288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt desc1.count_type = 1; 38298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt desc1.duration = duration1; 38308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt desc1.interval = interval1; 38318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ptr1 = &desc1; 38328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 38338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (duration2 || interval2) { 38348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memset(&desc2, 0, sizeof(desc2)); 38358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt desc2.count_type = 2; 38368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt desc2.duration = duration2; 38378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt desc2.interval = interval2; 38388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ptr2 = &desc2; 38398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 38408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 38418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 38428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_buf_add_action_hdr(req, P2P_PRESENCE_REQ, 1); 38438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt len = p2p_buf_add_ie_hdr(req); 38448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_buf_add_noa(req, 0, 0, 0, ptr1, ptr2); 38458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_buf_update_ie_hdr(req, len); 38468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 38478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return req; 38488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 38498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 38508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 38518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtint p2p_presence_req(struct p2p_data *p2p, const u8 *go_interface_addr, 38528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt const u8 *own_interface_addr, unsigned int freq, 38538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt u32 duration1, u32 interval1, u32 duration2, 38548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt u32 interval2) 38558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 38568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct wpabuf *req; 38578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 38588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG, "P2P: Send Presence Request to " 38598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "GO " MACSTR " (own interface " MACSTR ") freq=%u dur1=%u " 38608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "int1=%u dur2=%u int2=%u", 38618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt MAC2STR(go_interface_addr), MAC2STR(own_interface_addr), 38628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt freq, duration1, interval1, duration2, interval2); 38638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 38648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt req = p2p_build_presence_req(duration1, interval1, duration2, 38658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt interval2); 38668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (req == NULL) 38678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 38688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 38698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p->pending_action_state = P2P_NO_PENDING_ACTION; 38708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (p2p_send_action(p2p, freq, go_interface_addr, own_interface_addr, 38718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt go_interface_addr, 38728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpabuf_head(req), wpabuf_len(req), 200) < 0) { 38738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG, 38748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "P2P: Failed to send Action frame"); 38758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 38768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpabuf_free(req); 38778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 38788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 38798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 38808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 38818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 38828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic struct wpabuf * p2p_build_presence_resp(u8 status, const u8 *noa, 38838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt size_t noa_len, u8 dialog_token) 38848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 38858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct wpabuf *resp; 38868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt u8 *len; 38878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 38888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt resp = wpabuf_alloc(100 + noa_len); 38898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (resp == NULL) 38908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return NULL; 38918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 38928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_buf_add_action_hdr(resp, P2P_PRESENCE_RESP, dialog_token); 38938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt len = p2p_buf_add_ie_hdr(resp); 38948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_buf_add_status(resp, status); 38958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (noa) { 38968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpabuf_put_u8(resp, P2P_ATTR_NOTICE_OF_ABSENCE); 38978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpabuf_put_le16(resp, noa_len); 38988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpabuf_put_data(resp, noa, noa_len); 38998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } else 39008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_buf_add_noa(resp, 0, 0, 0, NULL, NULL); 39018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_buf_update_ie_hdr(resp, len); 39028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 39038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return resp; 39048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 39058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 39068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 39078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic void p2p_process_presence_req(struct p2p_data *p2p, const u8 *da, 39088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt const u8 *sa, const u8 *data, size_t len, 39098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt int rx_freq) 39108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 39118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct p2p_message msg; 39128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt u8 status; 39138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct wpabuf *resp; 39148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt size_t g; 39158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct p2p_group *group = NULL; 39168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt int parsed = 0; 39178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt u8 noa[50]; 39188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt int noa_len; 39198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 39208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG, 39218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "P2P: Received P2P Action - P2P Presence Request"); 39228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 39238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt for (g = 0; g < p2p->num_groups; g++) { 39248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (os_memcmp(da, p2p_group_get_interface_addr(p2p->groups[g]), 39258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ETH_ALEN) == 0) { 39268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt group = p2p->groups[g]; 39278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 39288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 39298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 39308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (group == NULL) { 39318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG, 39328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "P2P: Ignore P2P Presence Request for unknown group " 39338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt MACSTR, MAC2STR(da)); 39348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; 39358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 39368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 39378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (p2p_parse(data, len, &msg) < 0) { 39388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG, 39398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "P2P: Failed to parse P2P Presence Request"); 39408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt status = P2P_SC_FAIL_INVALID_PARAMS; 39418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt goto fail; 39428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 39438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt parsed = 1; 39448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 39458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (msg.noa == NULL) { 39468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG, 39478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "P2P: No NoA attribute in P2P Presence Request"); 39488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt status = P2P_SC_FAIL_INVALID_PARAMS; 39498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt goto fail; 39508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 39518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 39528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt status = p2p_group_presence_req(group, sa, msg.noa, msg.noa_len); 39538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 39548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtfail: 39558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (p2p->cfg->get_noa) 39568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt noa_len = p2p->cfg->get_noa(p2p->cfg->cb_ctx, da, noa, 39578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sizeof(noa)); 39588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt else 39598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt noa_len = -1; 39608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt resp = p2p_build_presence_resp(status, noa_len > 0 ? noa : NULL, 39618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt noa_len > 0 ? noa_len : 0, 39628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt msg.dialog_token); 39638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (parsed) 39648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_parse_free(&msg); 39658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (resp == NULL) 39668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; 39678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 39688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p->pending_action_state = P2P_NO_PENDING_ACTION; 39698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (p2p_send_action(p2p, rx_freq, sa, da, da, 39708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpabuf_head(resp), wpabuf_len(resp), 200) < 0) { 39718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG, 39728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "P2P: Failed to send Action frame"); 39738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 39748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpabuf_free(resp); 39758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 39768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 39778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 39788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic void p2p_process_presence_resp(struct p2p_data *p2p, const u8 *da, 39798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt const u8 *sa, const u8 *data, size_t len) 39808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 39818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct p2p_message msg; 39828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 39838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG, 39848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "P2P: Received P2P Action - P2P Presence Response"); 39858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 39868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (p2p_parse(data, len, &msg) < 0) { 39878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG, 39888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "P2P: Failed to parse P2P Presence Response"); 39898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; 39908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 39918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 39928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (msg.status == NULL || msg.noa == NULL) { 39938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG, 39948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "P2P: No Status or NoA attribute in P2P Presence " 39958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "Response"); 39968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_parse_free(&msg); 39978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; 39988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 39998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 40008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (*msg.status) { 40018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG, 40028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "P2P: P2P Presence Request was rejected: status %u", 40038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt *msg.status); 40048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_parse_free(&msg); 40058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; 40068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 40078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 40088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG, 40098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "P2P: P2P Presence Request was accepted"); 40108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_hexdump(MSG_DEBUG, "P2P: P2P Presence Response - NoA", 40118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt msg.noa, msg.noa_len); 40128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* TODO: process NoA */ 40138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_parse_free(&msg); 40148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 40158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 40168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 40178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic void p2p_ext_listen_timeout(void *eloop_ctx, void *timeout_ctx) 40188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 40198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct p2p_data *p2p = eloop_ctx; 40208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 40218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (p2p->ext_listen_interval) { 40228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* Schedule next extended listen timeout */ 40238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt eloop_register_timeout(p2p->ext_listen_interval_sec, 40248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p->ext_listen_interval_usec, 40258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_ext_listen_timeout, p2p, NULL); 40268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 40278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 40288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (p2p->state == P2P_LISTEN_ONLY && p2p->ext_listen_only) { 40298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* 40308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * This should not really happen, but it looks like the Listen 40318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * command may fail is something else (e.g., a scan) was 40328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * running at an inconvenient time. As a workaround, allow new 40338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * Extended Listen operation to be started. 40348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */ 40358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG, "P2P: Previous " 40368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "Extended Listen operation had not been completed - " 40378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "try again"); 40388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p->ext_listen_only = 0; 40398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_set_state(p2p, P2P_IDLE); 40408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 40418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 40428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (p2p->state != P2P_IDLE) { 40438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG, "P2P: Skip Extended " 40448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "Listen timeout in active state (%s)", 40458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_state_txt(p2p->state)); 40468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; 40478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 40488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 40498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG, "P2P: Extended Listen timeout"); 40508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p->ext_listen_only = 1; 40518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (p2p_listen(p2p, p2p->ext_listen_period) < 0) { 40528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG, "P2P: Failed to start " 40538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "Listen state for Extended Listen Timing"); 40548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p->ext_listen_only = 0; 40558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 40568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 40578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 40588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 40598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtint p2p_ext_listen(struct p2p_data *p2p, unsigned int period, 40608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt unsigned int interval) 40618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 40628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (period > 65535 || interval > 65535 || period > interval || 40638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt (period == 0 && interval > 0) || (period > 0 && interval == 0)) { 40648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG, 40658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "P2P: Invalid Extended Listen Timing request: " 40668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "period=%u interval=%u", period, interval); 40678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 40688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 40698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 40708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt eloop_cancel_timeout(p2p_ext_listen_timeout, p2p, NULL); 40718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 40728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (interval == 0) { 40738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG, 40748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "P2P: Disabling Extended Listen Timing"); 40758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p->ext_listen_period = 0; 40768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p->ext_listen_interval = 0; 40778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 40788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 40798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 40808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG, 40818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "P2P: Enabling Extended Listen Timing: period %u msec, " 40828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "interval %u msec", period, interval); 40838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p->ext_listen_period = period; 40848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p->ext_listen_interval = interval; 40858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p->ext_listen_interval_sec = interval / 1000; 40868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p->ext_listen_interval_usec = (interval % 1000) * 1000; 40878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 40888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt eloop_register_timeout(p2p->ext_listen_interval_sec, 40898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p->ext_listen_interval_usec, 40908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_ext_listen_timeout, p2p, NULL); 40918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 40928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 40938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 40948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 40958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 40968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtvoid p2p_deauth_notif(struct p2p_data *p2p, const u8 *bssid, u16 reason_code, 40978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt const u8 *ie, size_t ie_len) 40988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 40998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct p2p_message msg; 41008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 41018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (bssid == NULL || ie == NULL) 41028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; 41038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 41048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memset(&msg, 0, sizeof(msg)); 41058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (p2p_parse_ies(ie, ie_len, &msg)) 41068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; 41078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (msg.minor_reason_code == NULL) 41088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; 41098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 41108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_msg(p2p->cfg->msg_ctx, MSG_INFO, 41118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "P2P: Deauthentication notification BSSID " MACSTR 41128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt " reason_code=%u minor_reason_code=%u", 41138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt MAC2STR(bssid), reason_code, *msg.minor_reason_code); 41148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 41158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_parse_free(&msg); 41168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 41178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 41188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 41198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtvoid p2p_disassoc_notif(struct p2p_data *p2p, const u8 *bssid, u16 reason_code, 41208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt const u8 *ie, size_t ie_len) 41218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 41228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct p2p_message msg; 41238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 41248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (bssid == NULL || ie == NULL) 41258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; 41268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 41278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memset(&msg, 0, sizeof(msg)); 41288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (p2p_parse_ies(ie, ie_len, &msg)) 41298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; 41308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (msg.minor_reason_code == NULL) 41318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; 41328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 41338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_msg(p2p->cfg->msg_ctx, MSG_INFO, 41348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "P2P: Disassociation notification BSSID " MACSTR 41358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt " reason_code=%u minor_reason_code=%u", 41368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt MAC2STR(bssid), reason_code, *msg.minor_reason_code); 41378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 41388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_parse_free(&msg); 41398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 41408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 41418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 41428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtvoid p2p_set_managed_oper(struct p2p_data *p2p, int enabled) 41438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 41448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (enabled) { 41458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG, "P2P: Managed P2P " 41468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "Device operations enabled"); 41478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p->dev_capab |= P2P_DEV_CAPAB_INFRA_MANAGED; 41488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } else { 41498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG, "P2P: Managed P2P " 41508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "Device operations disabled"); 41518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p->dev_capab &= ~P2P_DEV_CAPAB_INFRA_MANAGED; 41528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 41538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 41548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 41558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 41568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtint p2p_set_listen_channel(struct p2p_data *p2p, u8 reg_class, u8 channel) 41578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 41588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (p2p_channel_to_freq(p2p->cfg->country, reg_class, channel) < 0) 41598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 41608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 41618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG, "P2P: Set Listen channel: " 41628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "reg_class %u channel %u", reg_class, channel); 41638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p->cfg->reg_class = reg_class; 41648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p->cfg->channel = channel; 41658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 41668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 41678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 41688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 41698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 41708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtint p2p_set_ssid_postfix(struct p2p_data *p2p, const u8 *postfix, size_t len) 41718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 41728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_hexdump_ascii(MSG_DEBUG, "P2P: New SSID postfix", postfix, len); 41738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (postfix == NULL) { 41748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p->cfg->ssid_postfix_len = 0; 41758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 41768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 41778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (len > sizeof(p2p->cfg->ssid_postfix)) 41788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 41798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memcpy(p2p->cfg->ssid_postfix, postfix, len); 41808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p->cfg->ssid_postfix_len = len; 41818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 41828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 41838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 41848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 418575ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinenint p2p_set_oper_channel(struct p2p_data *p2p, u8 op_reg_class, u8 op_channel, 418675ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen int cfg_op_channel) 418775ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen{ 418875ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen if (p2p_channel_to_freq(p2p->cfg->country, op_reg_class, op_channel) 418975ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen < 0) 419075ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen return -1; 419175ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen 419275ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen wpa_msg(p2p->cfg->msg_ctx, MSG_INFO, "P2P: Set Operating channel: " 419375ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen "reg_class %u channel %u", op_reg_class, op_channel); 419475ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen p2p->cfg->op_reg_class = op_reg_class; 419575ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen p2p->cfg->op_channel = op_channel; 419675ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen p2p->cfg->cfg_op_channel = cfg_op_channel; 419775ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen return 0; 419875ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen} 419975ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen 420075ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen 420104949598a23f501be6eec21697465fd46a28840aDmitry Shmidtint p2p_set_pref_chan(struct p2p_data *p2p, unsigned int num_pref_chan, 420204949598a23f501be6eec21697465fd46a28840aDmitry Shmidt const struct p2p_channel *pref_chan) 420304949598a23f501be6eec21697465fd46a28840aDmitry Shmidt{ 420404949598a23f501be6eec21697465fd46a28840aDmitry Shmidt struct p2p_channel *n; 420504949598a23f501be6eec21697465fd46a28840aDmitry Shmidt 420604949598a23f501be6eec21697465fd46a28840aDmitry Shmidt if (pref_chan) { 420704949598a23f501be6eec21697465fd46a28840aDmitry Shmidt n = os_malloc(num_pref_chan * sizeof(struct p2p_channel)); 420804949598a23f501be6eec21697465fd46a28840aDmitry Shmidt if (n == NULL) 420904949598a23f501be6eec21697465fd46a28840aDmitry Shmidt return -1; 421004949598a23f501be6eec21697465fd46a28840aDmitry Shmidt os_memcpy(n, pref_chan, 421104949598a23f501be6eec21697465fd46a28840aDmitry Shmidt num_pref_chan * sizeof(struct p2p_channel)); 421204949598a23f501be6eec21697465fd46a28840aDmitry Shmidt } else 421304949598a23f501be6eec21697465fd46a28840aDmitry Shmidt n = NULL; 421404949598a23f501be6eec21697465fd46a28840aDmitry Shmidt 421504949598a23f501be6eec21697465fd46a28840aDmitry Shmidt os_free(p2p->cfg->pref_chan); 421604949598a23f501be6eec21697465fd46a28840aDmitry Shmidt p2p->cfg->pref_chan = n; 421704949598a23f501be6eec21697465fd46a28840aDmitry Shmidt p2p->cfg->num_pref_chan = num_pref_chan; 421804949598a23f501be6eec21697465fd46a28840aDmitry Shmidt 421904949598a23f501be6eec21697465fd46a28840aDmitry Shmidt return 0; 422004949598a23f501be6eec21697465fd46a28840aDmitry Shmidt} 422104949598a23f501be6eec21697465fd46a28840aDmitry Shmidt 422204949598a23f501be6eec21697465fd46a28840aDmitry Shmidt 42238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtint p2p_get_interface_addr(struct p2p_data *p2p, const u8 *dev_addr, 42248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt u8 *iface_addr) 42258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 42268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct p2p_device *dev = p2p_get_device(p2p, dev_addr); 42278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (dev == NULL || is_zero_ether_addr(dev->interface_addr)) 42288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 42298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memcpy(iface_addr, dev->interface_addr, ETH_ALEN); 42308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 42318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 42328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 42338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 42348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtint p2p_get_dev_addr(struct p2p_data *p2p, const u8 *iface_addr, 42358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt u8 *dev_addr) 42368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 42378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct p2p_device *dev = p2p_get_device_interface(p2p, iface_addr); 42388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (dev == NULL) 42398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 42408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memcpy(dev_addr, dev->info.p2p_device_addr, ETH_ALEN); 42418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 42428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 42438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 42448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 42458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtvoid p2p_set_peer_filter(struct p2p_data *p2p, const u8 *addr) 42468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 42478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memcpy(p2p->peer_filter, addr, ETH_ALEN); 42488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (is_zero_ether_addr(p2p->peer_filter)) 42498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG, "P2P: Disable peer " 42508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "filter"); 42518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt else 42528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG, "P2P: Enable peer " 42538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "filter for " MACSTR, MAC2STR(p2p->peer_filter)); 42548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 42558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 42568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 42578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtvoid p2p_set_cross_connect(struct p2p_data *p2p, int enabled) 42588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 42598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG, "P2P: Cross connection %s", 42608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt enabled ? "enabled" : "disabled"); 42618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (p2p->cross_connect == enabled) 42628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; 42638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p->cross_connect = enabled; 42648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* TODO: may need to tear down any action group where we are GO(?) */ 42658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 42668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 42678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 42688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtint p2p_get_oper_freq(struct p2p_data *p2p, const u8 *iface_addr) 42698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 42708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct p2p_device *dev = p2p_get_device_interface(p2p, iface_addr); 42718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (dev == NULL) 42728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 42738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (dev->oper_freq <= 0) 42748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 42758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return dev->oper_freq; 42768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 42778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 42788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 42798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtvoid p2p_set_intra_bss_dist(struct p2p_data *p2p, int enabled) 42808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 42818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG, "P2P: Intra BSS distribution %s", 42828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt enabled ? "enabled" : "disabled"); 42838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p->cfg->p2p_intra_bss = enabled; 42848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 42858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 42868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 42878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtvoid p2p_update_channel_list(struct p2p_data *p2p, struct p2p_channels *chan) 42888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 42898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG, "P2P: Update channel list"); 42908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memcpy(&p2p->cfg->channels, chan, sizeof(struct p2p_channels)); 42918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 42928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 42938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 42948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtint p2p_send_action(struct p2p_data *p2p, unsigned int freq, const u8 *dst, 42958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt const u8 *src, const u8 *bssid, const u8 *buf, 42968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt size_t len, unsigned int wait_time) 42978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 42988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (p2p->p2p_scan_running) { 42998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG, "P2P: Delay Action " 43008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "frame TX until p2p_scan completes"); 43018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (p2p->after_scan_tx) { 43028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG, "P2P: Dropped " 43038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "previous pending Action frame TX"); 43048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_free(p2p->after_scan_tx); 43058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 43068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p->after_scan_tx = os_malloc(sizeof(*p2p->after_scan_tx) + 43078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt len); 43088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (p2p->after_scan_tx == NULL) 43098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 43108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p->after_scan_tx->freq = freq; 43118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memcpy(p2p->after_scan_tx->dst, dst, ETH_ALEN); 43128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memcpy(p2p->after_scan_tx->src, src, ETH_ALEN); 43138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memcpy(p2p->after_scan_tx->bssid, bssid, ETH_ALEN); 43148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p->after_scan_tx->len = len; 43158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p->after_scan_tx->wait_time = wait_time; 43168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memcpy(p2p->after_scan_tx + 1, buf, len); 43178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 43188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 43198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 43208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return p2p->cfg->send_action(p2p->cfg->cb_ctx, freq, dst, src, bssid, 43218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt buf, len, wait_time); 43228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 43238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 43248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 43258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtvoid p2p_set_best_channels(struct p2p_data *p2p, int freq_24, int freq_5, 43268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt int freq_overall) 43278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 43288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG, "P2P: Best channel: 2.4 GHz: %d," 43298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt " 5 GHz: %d, overall: %d", freq_24, freq_5, freq_overall); 43308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p->best_freq_24 = freq_24; 43318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p->best_freq_5 = freq_5; 43328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p->best_freq_overall = freq_overall; 43338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 43348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 43358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 4336700a137ab366edc72e371da68ba187b4717ee660Dmitry Shmidtvoid p2p_set_own_freq_preference(struct p2p_data *p2p, int freq) 4337700a137ab366edc72e371da68ba187b4717ee660Dmitry Shmidt{ 4338700a137ab366edc72e371da68ba187b4717ee660Dmitry Shmidt wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG, "P2P: Own frequency preference: " 4339700a137ab366edc72e371da68ba187b4717ee660Dmitry Shmidt "%d MHz", freq); 4340700a137ab366edc72e371da68ba187b4717ee660Dmitry Shmidt p2p->own_freq_preference = freq; 4341700a137ab366edc72e371da68ba187b4717ee660Dmitry Shmidt} 4342700a137ab366edc72e371da68ba187b4717ee660Dmitry Shmidt 4343700a137ab366edc72e371da68ba187b4717ee660Dmitry Shmidt 43448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtconst u8 * p2p_get_go_neg_peer(struct p2p_data *p2p) 43458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 43468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (p2p == NULL || p2p->go_neg_peer == NULL) 43478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return NULL; 43488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return p2p->go_neg_peer->info.p2p_device_addr; 43498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 43508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 43518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 43528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtconst struct p2p_peer_info * 43538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtp2p_get_peer_found(struct p2p_data *p2p, const u8 *addr, int next) 43548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 43558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct p2p_device *dev; 43568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 43578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (addr) { 43588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt dev = p2p_get_device(p2p, addr); 43598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (!dev) 43608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return NULL; 43618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 43628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (!next) { 43638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (dev->flags & P2P_DEV_PROBE_REQ_ONLY) 43648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return NULL; 43658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 43668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return &dev->info; 43678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } else { 43688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt do { 43698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt dev = dl_list_first(&dev->list, 43708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct p2p_device, 43718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt list); 43728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (&dev->list == &p2p->devices) 43738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return NULL; 43748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } while (dev->flags & P2P_DEV_PROBE_REQ_ONLY); 43758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 43768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } else { 43778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt dev = dl_list_first(&p2p->devices, struct p2p_device, list); 43788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (!dev) 43798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return NULL; 43808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt while (dev->flags & P2P_DEV_PROBE_REQ_ONLY) { 43818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt dev = dl_list_first(&dev->list, 43828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct p2p_device, 43838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt list); 43848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (&dev->list == &p2p->devices) 43858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return NULL; 43868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 43878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 43888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 43898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return &dev->info; 43908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 43911f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt 43921f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt#ifdef ANDROID_P2P 43931f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidtint p2p_search_in_progress(struct p2p_data *p2p) 43941f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt{ 43951f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt if (p2p == NULL) 43961f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt return 0; 43971f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt 43981f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt return p2p->state == P2P_SEARCH; 43991f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt} 44001f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt#endif 44011f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt 44021f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidtint p2p_in_progress(struct p2p_data *p2p) 44031f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt{ 44041f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt if (p2p == NULL) 44051f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt return 0; 440661d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt if (p2p->state == P2P_SEARCH || p2p->state == P2P_SEARCH_WHEN_READY || 440761d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt p2p->state == P2P_CONTINUE_SEARCH_WHEN_READY) 440861d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt return 2; 44091f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt return p2p->state != P2P_IDLE && p2p->state != P2P_PROVISIONING; 44101f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt} 441161d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt 441261d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt 441361d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidtvoid p2p_set_config_timeout(struct p2p_data *p2p, u8 go_timeout, 441461d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt u8 client_timeout) 441561d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt{ 441661d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt if (p2p) { 441761d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt p2p->go_timeout = go_timeout; 441861d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt p2p->client_timeout = client_timeout; 441961d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt } 442061d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt} 442161d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt 442261d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt 442361d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidtvoid p2p_increase_search_delay(struct p2p_data *p2p, unsigned int delay) 442461d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt{ 442561d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt if (p2p && p2p->search_delay < delay) 442661d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt p2p->search_delay = delay; 442761d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt} 442861d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt 442961d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt 443061d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt#ifdef CONFIG_WIFI_DISPLAY 443161d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt 443261d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidtstatic void p2p_update_wfd_ie_groups(struct p2p_data *p2p) 443361d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt{ 443461d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt size_t g; 443561d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt struct p2p_group *group; 443661d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt 443761d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt for (g = 0; g < p2p->num_groups; g++) { 443861d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt group = p2p->groups[g]; 443961d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt p2p_group_update_ies(group); 444061d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt } 444161d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt} 444261d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt 444361d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt 444461d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidtint p2p_set_wfd_ie_beacon(struct p2p_data *p2p, struct wpabuf *ie) 444561d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt{ 444661d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt wpabuf_free(p2p->wfd_ie_beacon); 444761d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt p2p->wfd_ie_beacon = ie; 444861d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt p2p_update_wfd_ie_groups(p2p); 444961d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt return 0; 445061d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt} 445161d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt 445261d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt 445361d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidtint p2p_set_wfd_ie_probe_req(struct p2p_data *p2p, struct wpabuf *ie) 445461d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt{ 445561d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt wpabuf_free(p2p->wfd_ie_probe_req); 445661d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt p2p->wfd_ie_probe_req = ie; 445761d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt return 0; 445861d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt} 445961d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt 446061d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt 446161d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidtint p2p_set_wfd_ie_probe_resp(struct p2p_data *p2p, struct wpabuf *ie) 446261d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt{ 446361d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt wpabuf_free(p2p->wfd_ie_probe_resp); 446461d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt p2p->wfd_ie_probe_resp = ie; 446561d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt p2p_update_wfd_ie_groups(p2p); 446661d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt return 0; 446761d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt} 446861d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt 446961d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt 447061d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidtint p2p_set_wfd_ie_assoc_req(struct p2p_data *p2p, struct wpabuf *ie) 447161d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt{ 447261d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt wpabuf_free(p2p->wfd_ie_assoc_req); 447361d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt p2p->wfd_ie_assoc_req = ie; 447461d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt return 0; 447561d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt} 447661d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt 447761d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt 447861d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidtint p2p_set_wfd_ie_invitation(struct p2p_data *p2p, struct wpabuf *ie) 447961d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt{ 448061d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt wpabuf_free(p2p->wfd_ie_invitation); 448161d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt p2p->wfd_ie_invitation = ie; 448261d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt return 0; 448361d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt} 448461d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt 448561d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt 448661d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidtint p2p_set_wfd_ie_prov_disc_req(struct p2p_data *p2p, struct wpabuf *ie) 448761d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt{ 448861d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt wpabuf_free(p2p->wfd_ie_prov_disc_req); 448961d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt p2p->wfd_ie_prov_disc_req = ie; 449061d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt return 0; 449161d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt} 449261d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt 449361d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt 449461d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidtint p2p_set_wfd_ie_prov_disc_resp(struct p2p_data *p2p, struct wpabuf *ie) 449561d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt{ 449661d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt wpabuf_free(p2p->wfd_ie_prov_disc_resp); 449761d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt p2p->wfd_ie_prov_disc_resp = ie; 449861d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt return 0; 449961d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt} 450061d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt 450161d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt 450261d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidtint p2p_set_wfd_ie_go_neg(struct p2p_data *p2p, struct wpabuf *ie) 450361d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt{ 450461d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt wpabuf_free(p2p->wfd_ie_go_neg); 450561d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt p2p->wfd_ie_go_neg = ie; 450661d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt return 0; 450761d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt} 450861d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt 450961d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt 451061d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidtint p2p_set_wfd_dev_info(struct p2p_data *p2p, const struct wpabuf *elem) 451161d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt{ 451261d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt wpabuf_free(p2p->wfd_dev_info); 451361d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt if (elem) { 451461d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt p2p->wfd_dev_info = wpabuf_dup(elem); 451561d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt if (p2p->wfd_dev_info == NULL) 451661d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt return -1; 451761d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt } else 451861d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt p2p->wfd_dev_info = NULL; 451961d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt 452061d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt return 0; 452161d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt} 452261d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt 452361d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt 452461d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidtint p2p_set_wfd_assoc_bssid(struct p2p_data *p2p, const struct wpabuf *elem) 452561d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt{ 452661d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt wpabuf_free(p2p->wfd_assoc_bssid); 452761d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt if (elem) { 452861d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt p2p->wfd_assoc_bssid = wpabuf_dup(elem); 452961d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt if (p2p->wfd_assoc_bssid == NULL) 453061d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt return -1; 453161d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt } else 453261d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt p2p->wfd_assoc_bssid = NULL; 453361d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt 453461d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt return 0; 453561d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt} 453661d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt 453761d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt 453861d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidtint p2p_set_wfd_coupled_sink_info(struct p2p_data *p2p, 453961d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt const struct wpabuf *elem) 454061d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt{ 454161d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt wpabuf_free(p2p->wfd_coupled_sink_info); 454261d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt if (elem) { 454361d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt p2p->wfd_coupled_sink_info = wpabuf_dup(elem); 454461d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt if (p2p->wfd_coupled_sink_info == NULL) 454561d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt return -1; 454661d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt } else 454761d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt p2p->wfd_coupled_sink_info = NULL; 454861d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt 454961d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt return 0; 455061d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt} 455161d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt 455261d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt#endif /* CONFIG_WIFI_DISPLAY */ 4553d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt 4554d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt 4555d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidtint p2p_set_disc_int(struct p2p_data *p2p, int min_disc_int, int max_disc_int, 4556d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt int max_disc_tu) 4557d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt{ 4558d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt if (min_disc_int > max_disc_int || min_disc_int < 0 || max_disc_int < 0) 4559d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt return -1; 4560d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt 4561d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt p2p->min_disc_int = min_disc_int; 4562d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt p2p->max_disc_int = max_disc_int; 4563d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt p2p->max_disc_tu = max_disc_tu; 4564d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG, "P2P: Set discoverable interval: " 4565d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt "min=%d max=%d max_tu=%d", min_disc_int, max_disc_int, 4566d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt max_disc_tu); 4567d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt 4568d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt return 0; 4569d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt} 4570