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" 158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include "wps/wps_i.h" 168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include "p2p_i.h" 178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include "p2p.h" 188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic void p2p_state_timeout(void *eloop_ctx, void *timeout_ctx); 218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic void p2p_device_free(struct p2p_data *p2p, struct p2p_device *dev); 228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic void p2p_process_presence_req(struct p2p_data *p2p, const u8 *da, 238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt const u8 *sa, const u8 *data, size_t len, 248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt int rx_freq); 258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic void p2p_process_presence_resp(struct p2p_data *p2p, const u8 *da, 268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt const u8 *sa, const u8 *data, 278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt size_t len); 288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic void p2p_ext_listen_timeout(void *eloop_ctx, void *timeout_ctx); 298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic void p2p_scan_timeout(void *eloop_ctx, void *timeout_ctx); 308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt/* 338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * p2p_scan recovery timeout 348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * 358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * Many drivers are using 30 second timeout on scan results. Allow a bit larger 368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * timeout for this to avoid hitting P2P timeout unnecessarily. 378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */ 388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#define P2P_SCAN_TIMEOUT 35 398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt/** 418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * P2P_PEER_EXPIRATION_AGE - Number of seconds after which inactive peer 428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * entries will be removed 438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */ 442fb777c379ad560c309c54b96c2c13291da23f54Dmitry Shmidt#ifdef ANDROID_P2P 452fb777c379ad560c309c54b96c2c13291da23f54Dmitry Shmidt#define P2P_PEER_EXPIRATION_AGE 30 462fb777c379ad560c309c54b96c2c13291da23f54Dmitry Shmidt#else 478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#define P2P_PEER_EXPIRATION_AGE 300 482fb777c379ad560c309c54b96c2c13291da23f54Dmitry Shmidt#endif 498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#define P2P_PEER_EXPIRATION_INTERVAL (P2P_PEER_EXPIRATION_AGE / 2) 518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 522fb777c379ad560c309c54b96c2c13291da23f54Dmitry Shmidt#ifdef ANDROID_P2P 532fb777c379ad560c309c54b96c2c13291da23f54Dmitry Shmidtint p2p_connection_in_progress(struct p2p_data *p2p) 542fb777c379ad560c309c54b96c2c13291da23f54Dmitry Shmidt{ 552fb777c379ad560c309c54b96c2c13291da23f54Dmitry Shmidt int ret = 0; 562fb777c379ad560c309c54b96c2c13291da23f54Dmitry Shmidt 572fb777c379ad560c309c54b96c2c13291da23f54Dmitry Shmidt switch (p2p->state) { 582fb777c379ad560c309c54b96c2c13291da23f54Dmitry Shmidt case P2P_CONNECT: 592fb777c379ad560c309c54b96c2c13291da23f54Dmitry Shmidt case P2P_CONNECT_LISTEN: 602fb777c379ad560c309c54b96c2c13291da23f54Dmitry Shmidt case P2P_GO_NEG: 612fb777c379ad560c309c54b96c2c13291da23f54Dmitry Shmidt case P2P_WAIT_PEER_CONNECT: 6298f9e76624da6bb96edc1982c423e4a119c5170aDmitry Shmidt case P2P_WAIT_PEER_IDLE: 632fb777c379ad560c309c54b96c2c13291da23f54Dmitry Shmidt case P2P_PROVISIONING: 642fb777c379ad560c309c54b96c2c13291da23f54Dmitry Shmidt case P2P_INVITE: 652fb777c379ad560c309c54b96c2c13291da23f54Dmitry Shmidt case P2P_INVITE_LISTEN: 662fb777c379ad560c309c54b96c2c13291da23f54Dmitry Shmidt ret = 1; 672fb777c379ad560c309c54b96c2c13291da23f54Dmitry Shmidt break; 682fb777c379ad560c309c54b96c2c13291da23f54Dmitry Shmidt 692fb777c379ad560c309c54b96c2c13291da23f54Dmitry Shmidt default: 7098f9e76624da6bb96edc1982c423e4a119c5170aDmitry Shmidt wpa_printf(MSG_DEBUG, "p2p_connection_in_progress state %d", p2p->state); 712fb777c379ad560c309c54b96c2c13291da23f54Dmitry Shmidt ret = 0; 722fb777c379ad560c309c54b96c2c13291da23f54Dmitry Shmidt } 732fb777c379ad560c309c54b96c2c13291da23f54Dmitry Shmidt 742fb777c379ad560c309c54b96c2c13291da23f54Dmitry Shmidt return ret; 752fb777c379ad560c309c54b96c2c13291da23f54Dmitry Shmidt} 762fb777c379ad560c309c54b96c2c13291da23f54Dmitry Shmidt#endif 772fb777c379ad560c309c54b96c2c13291da23f54Dmitry Shmidt 788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic void p2p_expire_peers(struct p2p_data *p2p) 798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct p2p_device *dev, *n; 818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct os_time now; 82c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt size_t i; 838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_get_time(&now); 858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt dl_list_for_each_safe(dev, n, &p2p->devices, struct p2p_device, list) { 868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (dev->last_seen.sec + P2P_PEER_EXPIRATION_AGE >= now.sec) 878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt continue; 88c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt 89c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt if (p2p->cfg->go_connected && 90c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt p2p->cfg->go_connected(p2p->cfg->cb_ctx, 91c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt dev->info.p2p_device_addr)) { 92c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt /* 93c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt * We are connected as a client to a group in which the 94c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt * peer is the GO, so do not expire the peer entry. 95c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt */ 96c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt os_get_time(&dev->last_seen); 97c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt continue; 98c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt } 99c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt 100c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt for (i = 0; i < p2p->num_groups; i++) { 101c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt if (p2p_group_is_client_connected( 102c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt p2p->groups[i], dev->info.p2p_device_addr)) 103c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt break; 104c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt } 105c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt if (i < p2p->num_groups) { 106c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt /* 107c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt * The peer is connected as a client in a group where 108c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt * we are the GO, so do not expire the peer entry. 109c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt */ 110c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt os_get_time(&dev->last_seen); 111c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt continue; 112c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt } 113c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt 1142fb777c379ad560c309c54b96c2c13291da23f54Dmitry Shmidt#ifdef ANDROID_P2P 1152fb777c379ad560c309c54b96c2c13291da23f54Dmitry Shmidt /* If Connection is in progress, don't expire the peer 1162fb777c379ad560c309c54b96c2c13291da23f54Dmitry Shmidt */ 1172fb777c379ad560c309c54b96c2c13291da23f54Dmitry Shmidt if (p2p_connection_in_progress(p2p)) 1182fb777c379ad560c309c54b96c2c13291da23f54Dmitry Shmidt continue; 1192fb777c379ad560c309c54b96c2c13291da23f54Dmitry Shmidt#endif 1202fb777c379ad560c309c54b96c2c13291da23f54Dmitry Shmidt 121b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt p2p_dbg(p2p, "Expiring old peer entry " MACSTR, 122b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt MAC2STR(dev->info.p2p_device_addr)); 123b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt 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 183b7b4d0ec07161a6d76c40ba7ef1306e82fbb7e15Dmitry Shmidtconst char * p2p_get_state_txt(struct p2p_data *p2p) 184b7b4d0ec07161a6d76c40ba7ef1306e82fbb7e15Dmitry Shmidt{ 185b7b4d0ec07161a6d76c40ba7ef1306e82fbb7e15Dmitry Shmidt return p2p_state_txt(p2p->state); 186b7b4d0ec07161a6d76c40ba7ef1306e82fbb7e15Dmitry Shmidt} 187b7b4d0ec07161a6d76c40ba7ef1306e82fbb7e15Dmitry Shmidt 188b7b4d0ec07161a6d76c40ba7ef1306e82fbb7e15Dmitry Shmidt 1891f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidtu16 p2p_get_provisioning_info(struct p2p_data *p2p, const u8 *addr) 1901f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt{ 1911f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt struct p2p_device *dev = NULL; 1921f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt 1931f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt if (!addr || !p2p) 1941f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt return 0; 1951f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt 1961f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt dev = p2p_get_device(p2p, addr); 1971f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt if (dev) 1981f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt return dev->wps_prov_info; 1991f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt else 2001f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt return 0; 2011f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt} 2021f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt 2031f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt 20404949598a23f501be6eec21697465fd46a28840aDmitry Shmidtvoid p2p_clear_provisioning_info(struct p2p_data *p2p, const u8 *addr) 2051f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt{ 2061f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt struct p2p_device *dev = NULL; 2071f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt 20804949598a23f501be6eec21697465fd46a28840aDmitry Shmidt if (!addr || !p2p) 2091f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt return; 2101f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt 21104949598a23f501be6eec21697465fd46a28840aDmitry Shmidt dev = p2p_get_device(p2p, addr); 2121f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt if (dev) 2131f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt dev->wps_prov_info = 0; 2141f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt} 2151f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt 2161f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt 2178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtvoid p2p_set_state(struct p2p_data *p2p, int new_state) 2188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 219b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt p2p_dbg(p2p, "State %s -> %s", 2208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_state_txt(p2p->state), p2p_state_txt(new_state)); 2218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p->state = new_state; 2228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 2238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtvoid p2p_set_timeout(struct p2p_data *p2p, unsigned int sec, unsigned int usec) 2268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 227b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt p2p_dbg(p2p, "Set timeout (state=%s): %u.%06u sec", 2288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_state_txt(p2p->state), sec, usec); 2298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt eloop_cancel_timeout(p2p_state_timeout, p2p, NULL); 2308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt eloop_register_timeout(sec, usec, p2p_state_timeout, p2p, NULL); 2318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 2328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtvoid p2p_clear_timeout(struct p2p_data *p2p) 2358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 236b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt p2p_dbg(p2p, "Clear timeout (state=%s)", p2p_state_txt(p2p->state)); 2378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt eloop_cancel_timeout(p2p_state_timeout, p2p, NULL); 2388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 2398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtvoid p2p_go_neg_failed(struct p2p_data *p2p, struct p2p_device *peer, 2428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt int status) 2438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 2448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct p2p_go_neg_results res; 2458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_clear_timeout(p2p); 2468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_set_state(p2p, P2P_IDLE); 2478c65289885e84727226d81b3d32856f79c31ee5fDmitry Shmidt if (p2p->go_neg_peer) { 2488c65289885e84727226d81b3d32856f79c31ee5fDmitry Shmidt p2p->go_neg_peer->flags &= ~P2P_DEV_PEER_WAITING_RESPONSE; 2491f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt p2p->go_neg_peer->wps_method = WPS_NOT_READY; 2508c65289885e84727226d81b3d32856f79c31ee5fDmitry Shmidt } 2518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p->go_neg_peer = NULL; 2528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memset(&res, 0, sizeof(res)); 2548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt res.status = status; 2558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (peer) { 2568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memcpy(res.peer_device_addr, peer->info.p2p_device_addr, 2578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ETH_ALEN); 2588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memcpy(res.peer_interface_addr, peer->intended_addr, 2598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ETH_ALEN); 2608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 2618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p->cfg->go_neg_completed(p2p->cfg->cb_ctx, &res); 2628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 2638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 265d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidtstatic void p2p_listen_in_find(struct p2p_data *p2p, int dev_disc) 2668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 2678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt unsigned int r, tu; 2688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt int freq; 2698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct wpabuf *ies; 2708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 271b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt p2p_dbg(p2p, "Starting short listen state (state=%s)", 2728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_state_txt(p2p->state)); 2738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2744b06059785b935dd1f4f09314e4e12c417d2c6a4Dmitry Shmidt freq = p2p_channel_to_freq(p2p->cfg->reg_class, p2p->cfg->channel); 2758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (freq < 0) { 276b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt p2p_dbg(p2p, "Unknown regulatory class/channel"); 2778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; 2788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 2798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_get_random((u8 *) &r, sizeof(r)); 2818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt tu = (r % ((p2p->max_disc_int - p2p->min_disc_int) + 1) + 2828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p->min_disc_int) * 100; 283d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt if (p2p->max_disc_tu >= 0 && tu > (unsigned int) p2p->max_disc_tu) 284d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt tu = p2p->max_disc_tu; 285d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt if (!dev_disc && tu < 100) 286d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt tu = 100; /* Need to wait in non-device discovery use cases */ 287d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt if (p2p->cfg->max_listen && 1024 * tu / 1000 > p2p->cfg->max_listen) 288d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt tu = p2p->cfg->max_listen * 1000 / 1024; 289d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt 290d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt if (tu == 0) { 291b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt p2p_dbg(p2p, "Skip listen state 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) { 306b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt p2p_dbg(p2p, "Failed to start listen mode"); 3078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p->pending_listen_freq = 0; 3088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 3098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpabuf_free(ies); 3108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 3118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 3128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 3138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtint p2p_listen(struct p2p_data *p2p, unsigned int timeout) 3148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 3158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt int freq; 3168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct wpabuf *ies; 3178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 318b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt p2p_dbg(p2p, "Going to listen(only) state"); 3198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 3204b06059785b935dd1f4f09314e4e12c417d2c6a4Dmitry Shmidt freq = p2p_channel_to_freq(p2p->cfg->reg_class, p2p->cfg->channel); 3218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (freq < 0) { 322b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt p2p_dbg(p2p, "Unknown regulatory class/channel"); 3238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 3248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 3258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 3268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p->pending_listen_freq = freq; 3278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p->pending_listen_sec = timeout / 1000; 3288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p->pending_listen_usec = (timeout % 1000) * 1000; 3298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 3308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (p2p->p2p_scan_running) { 33104949598a23f501be6eec21697465fd46a28840aDmitry Shmidt if (p2p->start_after_scan == P2P_AFTER_SCAN_CONNECT) { 332b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt p2p_dbg(p2p, "p2p_scan running - connect is already pending - skip listen"); 3331f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt return 0; 3341f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt } 335b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt p2p_dbg(p2p, "p2p_scan running - delay start of listen state"); 3368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p->start_after_scan = P2P_AFTER_SCAN_LISTEN; 3378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 3388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 3398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 3408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ies = p2p_build_probe_resp_ies(p2p); 3418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (ies == NULL) 3428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 3438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 3448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (p2p->cfg->start_listen(p2p->cfg->cb_ctx, freq, timeout, ies) < 0) { 345b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt p2p_dbg(p2p, "Failed to start listen mode"); 3468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p->pending_listen_freq = 0; 3478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpabuf_free(ies); 3488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 3498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 3508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpabuf_free(ies); 3518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 3528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_set_state(p2p, P2P_LISTEN_ONLY); 3538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 3548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 3558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 3568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 3578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 3588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic void p2p_device_clear_reported(struct p2p_data *p2p) 3598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 3608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct p2p_device *dev; 3618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt dl_list_for_each(dev, &p2p->devices, struct p2p_device, list) 3628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt dev->flags &= ~P2P_DEV_REPORTED; 3638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 3648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 3658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 3668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt/** 3678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * p2p_get_device - Fetch a peer entry 3688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @p2p: P2P module context from p2p_init() 3698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @addr: P2P Device Address of the peer 3708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * Returns: Pointer to the device entry or %NULL if not found 3718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */ 3728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstruct p2p_device * p2p_get_device(struct p2p_data *p2p, const u8 *addr) 3738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 3748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct p2p_device *dev; 3758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt dl_list_for_each(dev, &p2p->devices, struct p2p_device, list) { 3768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (os_memcmp(dev->info.p2p_device_addr, addr, ETH_ALEN) == 0) 3778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return dev; 3788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 3798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return NULL; 3808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 3818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 3828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 3838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt/** 3848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * p2p_get_device_interface - Fetch a peer entry based on P2P Interface Address 3858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @p2p: P2P module context from p2p_init() 3868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @addr: P2P Interface Address of the peer 3878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * Returns: Pointer to the device entry or %NULL if not found 3888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */ 3898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstruct p2p_device * p2p_get_device_interface(struct p2p_data *p2p, 3908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt const u8 *addr) 3918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 3928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct p2p_device *dev; 3938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt dl_list_for_each(dev, &p2p->devices, struct p2p_device, list) { 3948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (os_memcmp(dev->interface_addr, addr, ETH_ALEN) == 0) 3958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return dev; 3968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 3978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return NULL; 3988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 3998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 4008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 4018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt/** 4028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * p2p_create_device - Create a peer entry 4038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @p2p: P2P module context from p2p_init() 4048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @addr: P2P Device Address of the peer 4058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * Returns: Pointer to the device entry or %NULL on failure 4068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * 4078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * If there is already an entry for the peer, it will be returned instead of 4088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * creating a new one. 4098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */ 4108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic struct p2p_device * p2p_create_device(struct p2p_data *p2p, 4118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt const u8 *addr) 4128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 4138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct p2p_device *dev, *oldest = NULL; 4148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt size_t count = 0; 4158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 4168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt dev = p2p_get_device(p2p, addr); 4178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (dev) 4188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return dev; 4198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 4208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt dl_list_for_each(dev, &p2p->devices, struct p2p_device, list) { 4218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt count++; 4228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (oldest == NULL || 4238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_time_before(&dev->last_seen, &oldest->last_seen)) 4248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt oldest = dev; 4258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 4268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (count + 1 > p2p->cfg->max_peers && oldest) { 427b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt p2p_dbg(p2p, "Remove oldest peer entry to make room for a new peer"); 428f44b9c4a18d17fbd39901f76a014c32006570fb8Irfan Sheriff#ifdef ANDROID_P2P 429f44b9c4a18d17fbd39901f76a014c32006570fb8Irfan Sheriff /* SD_FAIR_POLICY: Update the current sd_dev_list pointer to next device */ 430f44b9c4a18d17fbd39901f76a014c32006570fb8Irfan Sheriff if(&oldest->list == p2p->sd_dev_list) 431f44b9c4a18d17fbd39901f76a014c32006570fb8Irfan Sheriff p2p->sd_dev_list = oldest->list.next; 432f44b9c4a18d17fbd39901f76a014c32006570fb8Irfan Sheriff#endif 4338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt dl_list_del(&oldest->list); 4348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_device_free(p2p, oldest); 4358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 4368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 4378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt dev = os_zalloc(sizeof(*dev)); 4388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (dev == NULL) 4398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return NULL; 4408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt dl_list_add(&p2p->devices, &dev->list); 4418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memcpy(dev->info.p2p_device_addr, addr, ETH_ALEN); 4428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 4438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return dev; 4448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 4458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 4468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 4478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic void p2p_copy_client_info(struct p2p_device *dev, 4488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct p2p_client_info *cli) 4498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 4508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memcpy(dev->info.device_name, cli->dev_name, cli->dev_name_len); 4518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt dev->info.device_name[cli->dev_name_len] = '\0'; 4528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt dev->info.dev_capab = cli->dev_capab; 4538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt dev->info.config_methods = cli->config_methods; 4548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memcpy(dev->info.pri_dev_type, cli->pri_dev_type, 8); 4558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt dev->info.wps_sec_dev_type_list_len = 8 * cli->num_sec_dev_types; 4568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memcpy(dev->info.wps_sec_dev_type_list, cli->sec_dev_types, 4578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt dev->info.wps_sec_dev_type_list_len); 4588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 4598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 4608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 4618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic int p2p_add_group_clients(struct p2p_data *p2p, const u8 *go_dev_addr, 4628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt const u8 *go_interface_addr, int freq, 4638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt const u8 *gi, size_t gi_len) 4648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 4658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct p2p_group_info info; 4668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt size_t c; 4678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct p2p_device *dev; 4688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 4698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (gi == NULL) 4708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 4718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 4728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (p2p_group_info_parse(gi, gi_len, &info) < 0) 4738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 4748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 4758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* 4768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * Clear old data for this group; if the devices are still in the 4778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * group, the information will be restored in the loop following this. 4788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */ 4798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt dl_list_for_each(dev, &p2p->devices, struct p2p_device, list) { 4801f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt if (os_memcmp(dev->member_in_go_iface, go_interface_addr, 4818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ETH_ALEN) == 0) { 4828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memset(dev->member_in_go_iface, 0, ETH_ALEN); 4838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memset(dev->member_in_go_dev, 0, ETH_ALEN); 4848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 4858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 4868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 4878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt for (c = 0; c < info.num_clients; c++) { 4888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct p2p_client_info *cli = &info.client[c]; 4891f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt if (os_memcmp(cli->p2p_device_addr, p2p->cfg->dev_addr, 4901f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt ETH_ALEN) == 0) 4911f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt continue; /* ignore our own entry */ 4928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt dev = p2p_get_device(p2p, cli->p2p_device_addr); 4938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (dev) { 4948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (dev->flags & (P2P_DEV_GROUP_CLIENT_ONLY | 49504949598a23f501be6eec21697465fd46a28840aDmitry Shmidt P2P_DEV_PROBE_REQ_ONLY)) { 49604949598a23f501be6eec21697465fd46a28840aDmitry Shmidt /* 49704949598a23f501be6eec21697465fd46a28840aDmitry Shmidt * Update information since we have not 49804949598a23f501be6eec21697465fd46a28840aDmitry Shmidt * received this directly from the client. 49904949598a23f501be6eec21697465fd46a28840aDmitry Shmidt */ 5008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_copy_client_info(dev, cli); 50104949598a23f501be6eec21697465fd46a28840aDmitry Shmidt } else { 50204949598a23f501be6eec21697465fd46a28840aDmitry Shmidt /* 50304949598a23f501be6eec21697465fd46a28840aDmitry Shmidt * Need to update P2P Client Discoverability 50404949598a23f501be6eec21697465fd46a28840aDmitry Shmidt * flag since it is valid only in P2P Group 50504949598a23f501be6eec21697465fd46a28840aDmitry Shmidt * Info attribute. 50604949598a23f501be6eec21697465fd46a28840aDmitry Shmidt */ 50704949598a23f501be6eec21697465fd46a28840aDmitry Shmidt dev->info.dev_capab &= 50804949598a23f501be6eec21697465fd46a28840aDmitry Shmidt ~P2P_DEV_CAPAB_CLIENT_DISCOVERABILITY; 50904949598a23f501be6eec21697465fd46a28840aDmitry Shmidt dev->info.dev_capab |= 51004949598a23f501be6eec21697465fd46a28840aDmitry Shmidt cli->dev_capab & 51104949598a23f501be6eec21697465fd46a28840aDmitry Shmidt P2P_DEV_CAPAB_CLIENT_DISCOVERABILITY; 51204949598a23f501be6eec21697465fd46a28840aDmitry Shmidt } 5138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (dev->flags & P2P_DEV_PROBE_REQ_ONLY) { 5148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt dev->flags &= ~P2P_DEV_PROBE_REQ_ONLY; 5158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 5168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } else { 5178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt dev = p2p_create_device(p2p, cli->p2p_device_addr); 5188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (dev == NULL) 5198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt continue; 5208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt dev->flags |= P2P_DEV_GROUP_CLIENT_ONLY; 5218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_copy_client_info(dev, cli); 5228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt dev->oper_freq = freq; 5238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p->cfg->dev_found(p2p->cfg->cb_ctx, 5248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt dev->info.p2p_device_addr, 5258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt &dev->info, 1); 5268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt dev->flags |= P2P_DEV_REPORTED | P2P_DEV_REPORTED_ONCE; 5278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 5288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 5298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memcpy(dev->interface_addr, cli->p2p_interface_addr, 5308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ETH_ALEN); 5318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_get_time(&dev->last_seen); 5328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memcpy(dev->member_in_go_dev, go_dev_addr, ETH_ALEN); 5338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memcpy(dev->member_in_go_iface, go_interface_addr, 5348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ETH_ALEN); 5358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 5368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 5378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 5388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 5398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 5408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 541b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidtstatic void p2p_copy_wps_info(struct p2p_data *p2p, struct p2p_device *dev, 542b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt int probe_req, const struct p2p_message *msg) 5438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 5448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memcpy(dev->info.device_name, msg->device_name, 5458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sizeof(dev->info.device_name)); 5468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 5478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (msg->manufacturer && 5488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt msg->manufacturer_len < sizeof(dev->info.manufacturer)) { 5498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memset(dev->info.manufacturer, 0, 5508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sizeof(dev->info.manufacturer)); 5518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memcpy(dev->info.manufacturer, msg->manufacturer, 5528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt msg->manufacturer_len); 5538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 5548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 5558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (msg->model_name && 5568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt msg->model_name_len < sizeof(dev->info.model_name)) { 5578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memset(dev->info.model_name, 0, 5588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sizeof(dev->info.model_name)); 5598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memcpy(dev->info.model_name, msg->model_name, 5608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt msg->model_name_len); 5618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 5628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 5638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (msg->model_number && 5648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt msg->model_number_len < sizeof(dev->info.model_number)) { 5658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memset(dev->info.model_number, 0, 5668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sizeof(dev->info.model_number)); 5678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memcpy(dev->info.model_number, msg->model_number, 5688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt msg->model_number_len); 5698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 5708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 5718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (msg->serial_number && 5728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt msg->serial_number_len < sizeof(dev->info.serial_number)) { 5738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memset(dev->info.serial_number, 0, 5748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sizeof(dev->info.serial_number)); 5758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memcpy(dev->info.serial_number, msg->serial_number, 5768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt msg->serial_number_len); 5778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 5788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 5798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (msg->pri_dev_type) 5808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memcpy(dev->info.pri_dev_type, msg->pri_dev_type, 5818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sizeof(dev->info.pri_dev_type)); 5828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt else if (msg->wps_pri_dev_type) 5838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memcpy(dev->info.pri_dev_type, msg->wps_pri_dev_type, 5848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sizeof(dev->info.pri_dev_type)); 5858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 5868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (msg->wps_sec_dev_type_list) { 5878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memcpy(dev->info.wps_sec_dev_type_list, 5888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt msg->wps_sec_dev_type_list, 5898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt msg->wps_sec_dev_type_list_len); 5908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt dev->info.wps_sec_dev_type_list_len = 5918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt msg->wps_sec_dev_type_list_len; 5928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 5938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 5948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (msg->capability) { 59504949598a23f501be6eec21697465fd46a28840aDmitry Shmidt /* 59604949598a23f501be6eec21697465fd46a28840aDmitry Shmidt * P2P Client Discoverability bit is reserved in all frames 59704949598a23f501be6eec21697465fd46a28840aDmitry Shmidt * that use this function, so do not change its value here. 59804949598a23f501be6eec21697465fd46a28840aDmitry Shmidt */ 59904949598a23f501be6eec21697465fd46a28840aDmitry Shmidt dev->info.dev_capab &= P2P_DEV_CAPAB_CLIENT_DISCOVERABILITY; 60004949598a23f501be6eec21697465fd46a28840aDmitry Shmidt dev->info.dev_capab |= msg->capability[0] & 60104949598a23f501be6eec21697465fd46a28840aDmitry Shmidt ~P2P_DEV_CAPAB_CLIENT_DISCOVERABILITY; 6028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt dev->info.group_capab = msg->capability[1]; 6038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 6048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 6058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (msg->ext_listen_timing) { 6068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt dev->ext_listen_period = WPA_GET_LE16(msg->ext_listen_timing); 6078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt dev->ext_listen_interval = 6088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt WPA_GET_LE16(msg->ext_listen_timing + 2); 6098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 61004949598a23f501be6eec21697465fd46a28840aDmitry Shmidt 6118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (!probe_req) { 612f86232838cf712377867cb42417c1613ab5dc425Dmitry Shmidt u16 new_config_methods; 613f86232838cf712377867cb42417c1613ab5dc425Dmitry Shmidt new_config_methods = msg->config_methods ? 6148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt msg->config_methods : msg->wps_config_methods; 615f86232838cf712377867cb42417c1613ab5dc425Dmitry Shmidt if (new_config_methods && 616f86232838cf712377867cb42417c1613ab5dc425Dmitry Shmidt dev->info.config_methods != new_config_methods) { 617b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt p2p_dbg(p2p, "Update peer " MACSTR 618b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt " config_methods 0x%x -> 0x%x", 619b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt MAC2STR(dev->info.p2p_device_addr), 620b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt dev->info.config_methods, 621b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt new_config_methods); 622f86232838cf712377867cb42417c1613ab5dc425Dmitry Shmidt dev->info.config_methods = new_config_methods; 623f86232838cf712377867cb42417c1613ab5dc425Dmitry Shmidt } 6248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 6258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 6268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 6278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 6288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt/** 62904949598a23f501be6eec21697465fd46a28840aDmitry Shmidt * p2p_add_device - Add peer entries based on scan results or P2P frames 6308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @p2p: P2P module context from p2p_init() 6318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @addr: Source address of Beacon or Probe Response frame (may be either 6328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * P2P Device Address or P2P Interface Address) 6338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @level: Signal level (signal strength of the received frame from the peer) 6348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @freq: Frequency on which the Beacon or Probe Response frame was received 635f86232838cf712377867cb42417c1613ab5dc425Dmitry Shmidt * @rx_time: Time when the result was received 6368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @ies: IEs from the Beacon or Probe Response frame 6378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @ies_len: Length of ies buffer in octets 63804949598a23f501be6eec21697465fd46a28840aDmitry Shmidt * @scan_res: Whether this was based on scan results 6398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * Returns: 0 on success, -1 on failure 6408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * 6418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * If the scan result is for a GO, the clients in the group will also be added 6428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * to the peer table. This function can also be used with some other frames 6438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * like Provision Discovery Request that contains P2P Capability and P2P Device 6448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * Info attributes. 6458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */ 646a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidtint p2p_add_device(struct p2p_data *p2p, const u8 *addr, int freq, 647f86232838cf712377867cb42417c1613ab5dc425Dmitry Shmidt struct os_time *rx_time, int level, const u8 *ies, 648a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt size_t ies_len, int scan_res) 6498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 6508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct p2p_device *dev; 6518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct p2p_message msg; 6528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt const u8 *p2p_dev_addr; 6538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt int i; 654f86232838cf712377867cb42417c1613ab5dc425Dmitry Shmidt struct os_time time_now; 6558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 6568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memset(&msg, 0, sizeof(msg)); 6578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (p2p_parse_ies(ies, ies_len, &msg)) { 658b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt p2p_dbg(p2p, "Failed to parse P2P IE for a device entry"); 6598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_parse_free(&msg); 6608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 6618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 6628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 6638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (msg.p2p_device_addr) 6648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_dev_addr = msg.p2p_device_addr; 6658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt else if (msg.device_id) 6668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_dev_addr = msg.device_id; 6678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt else { 668b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt p2p_dbg(p2p, "Ignore scan data without P2P Device Info or P2P Device Id"); 6698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_parse_free(&msg); 6708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 6718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 6728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 6738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (!is_zero_ether_addr(p2p->peer_filter) && 6748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memcmp(p2p_dev_addr, p2p->peer_filter, ETH_ALEN) != 0) { 675b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt p2p_dbg(p2p, "Do not add peer filter for " MACSTR 676b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt " due to peer filter", MAC2STR(p2p_dev_addr)); 677a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt p2p_parse_free(&msg); 6788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 6798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 6808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 6818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt dev = p2p_create_device(p2p, p2p_dev_addr); 6828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (dev == NULL) { 6838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_parse_free(&msg); 6848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 6858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 686a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt 687f86232838cf712377867cb42417c1613ab5dc425Dmitry Shmidt if (rx_time == NULL) { 688f86232838cf712377867cb42417c1613ab5dc425Dmitry Shmidt os_get_time(&time_now); 689f86232838cf712377867cb42417c1613ab5dc425Dmitry Shmidt rx_time = &time_now; 690f86232838cf712377867cb42417c1613ab5dc425Dmitry Shmidt } 691a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt 692a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt /* 693a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt * Update the device entry only if the new peer 694a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt * entry is newer than the one previously stored. 695a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt */ 696f86232838cf712377867cb42417c1613ab5dc425Dmitry Shmidt if (dev->last_seen.sec > 0 && 697f86232838cf712377867cb42417c1613ab5dc425Dmitry Shmidt os_time_before(rx_time, &dev->last_seen)) { 698b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt p2p_dbg(p2p, "Do not update peer entry based on old frame (rx_time=%u.%06u last_seen=%u.%06u)", 699f86232838cf712377867cb42417c1613ab5dc425Dmitry Shmidt (unsigned int) rx_time->sec, 700f86232838cf712377867cb42417c1613ab5dc425Dmitry Shmidt (unsigned int) rx_time->usec, 701f86232838cf712377867cb42417c1613ab5dc425Dmitry Shmidt (unsigned int) dev->last_seen.sec, 702f86232838cf712377867cb42417c1613ab5dc425Dmitry Shmidt (unsigned int) dev->last_seen.usec); 703a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt p2p_parse_free(&msg); 704a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt return -1; 705a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt } 706a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt 707f86232838cf712377867cb42417c1613ab5dc425Dmitry Shmidt os_memcpy(&dev->last_seen, rx_time, sizeof(struct os_time)); 708a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt 7098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt dev->flags &= ~(P2P_DEV_PROBE_REQ_ONLY | P2P_DEV_GROUP_CLIENT_ONLY); 7108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 7118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (os_memcmp(addr, p2p_dev_addr, ETH_ALEN) != 0) 7128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memcpy(dev->interface_addr, addr, ETH_ALEN); 7138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (msg.ssid && 7148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt (msg.ssid[1] != P2P_WILDCARD_SSID_LEN || 7158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memcmp(msg.ssid + 2, P2P_WILDCARD_SSID, P2P_WILDCARD_SSID_LEN) 7168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt != 0)) { 7178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memcpy(dev->oper_ssid, msg.ssid + 2, msg.ssid[1]); 7188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt dev->oper_ssid_len = msg.ssid[1]; 7198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 7208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 7218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (freq >= 2412 && freq <= 2484 && msg.ds_params && 7228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt *msg.ds_params >= 1 && *msg.ds_params <= 14) { 7238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt int ds_freq; 7248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (*msg.ds_params == 14) 7258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ds_freq = 2484; 7268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt else 7278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ds_freq = 2407 + *msg.ds_params * 5; 7288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (freq != ds_freq) { 729b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt p2p_dbg(p2p, "Update Listen frequency based on DS Parameter Set IE: %d -> %d MHz", 7308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt freq, ds_freq); 7318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt freq = ds_freq; 7328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 7338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 7348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 73504949598a23f501be6eec21697465fd46a28840aDmitry Shmidt if (dev->listen_freq && dev->listen_freq != freq && scan_res) { 736b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt p2p_dbg(p2p, "Update Listen frequency based on scan results (" 737b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt MACSTR " %d -> %d MHz (DS param %d)", 7388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt MAC2STR(dev->info.p2p_device_addr), dev->listen_freq, 7398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt freq, msg.ds_params ? *msg.ds_params : -1); 7408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 74104949598a23f501be6eec21697465fd46a28840aDmitry Shmidt if (scan_res) { 74204949598a23f501be6eec21697465fd46a28840aDmitry Shmidt dev->listen_freq = freq; 74304949598a23f501be6eec21697465fd46a28840aDmitry Shmidt if (msg.group_info) 74404949598a23f501be6eec21697465fd46a28840aDmitry Shmidt dev->oper_freq = freq; 74504949598a23f501be6eec21697465fd46a28840aDmitry Shmidt } 74675ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen dev->info.level = level; 7478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 748b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt p2p_copy_wps_info(p2p, dev, 0, &msg); 7498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 7508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt for (i = 0; i < P2P_MAX_WPS_VENDOR_EXT; i++) { 7518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpabuf_free(dev->info.wps_vendor_ext[i]); 7528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt dev->info.wps_vendor_ext[i] = NULL; 7538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 7548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 7558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt for (i = 0; i < P2P_MAX_WPS_VENDOR_EXT; i++) { 7568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (msg.wps_vendor_ext[i] == NULL) 7578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 7588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt dev->info.wps_vendor_ext[i] = wpabuf_alloc_copy( 7598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt msg.wps_vendor_ext[i], msg.wps_vendor_ext_len[i]); 7608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (dev->info.wps_vendor_ext[i] == NULL) 7618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 7628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 7638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 76461d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt if (msg.wfd_subelems) { 76561d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt wpabuf_free(dev->info.wfd_subelems); 76661d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt dev->info.wfd_subelems = wpabuf_dup(msg.wfd_subelems); 76761d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt } 76861d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt 76904949598a23f501be6eec21697465fd46a28840aDmitry Shmidt if (scan_res) { 77004949598a23f501be6eec21697465fd46a28840aDmitry Shmidt p2p_add_group_clients(p2p, p2p_dev_addr, addr, freq, 77104949598a23f501be6eec21697465fd46a28840aDmitry Shmidt msg.group_info, msg.group_info_len); 77204949598a23f501be6eec21697465fd46a28840aDmitry Shmidt } 7738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 7748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_parse_free(&msg); 7758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 7768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (p2p_pending_sd_req(p2p, dev)) 7778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt dev->flags |= P2P_DEV_SD_SCHEDULE; 7788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 7798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (dev->flags & P2P_DEV_REPORTED) 7808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 7818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 782b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt p2p_dbg(p2p, "Peer found with Listen frequency %d MHz (rx_time=%u.%06u)", 783b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt freq, (unsigned int) rx_time->sec, 784f86232838cf712377867cb42417c1613ab5dc425Dmitry Shmidt (unsigned int) rx_time->usec); 7858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (dev->flags & P2P_DEV_USER_REJECTED) { 786b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt p2p_dbg(p2p, "Do not report rejected device"); 7878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 7888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 7898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 790f86232838cf712377867cb42417c1613ab5dc425Dmitry Shmidt if (dev->info.config_methods == 0 && 791f86232838cf712377867cb42417c1613ab5dc425Dmitry Shmidt (freq == 2412 || freq == 2437 || freq == 2462)) { 792f86232838cf712377867cb42417c1613ab5dc425Dmitry Shmidt /* 793f86232838cf712377867cb42417c1613ab5dc425Dmitry Shmidt * If we have only seen a Beacon frame from a GO, we do not yet 794f86232838cf712377867cb42417c1613ab5dc425Dmitry Shmidt * know what WPS config methods it supports. Since some 795f86232838cf712377867cb42417c1613ab5dc425Dmitry Shmidt * applications use config_methods value from P2P-DEVICE-FOUND 796f86232838cf712377867cb42417c1613ab5dc425Dmitry Shmidt * events, postpone reporting this peer until we've fully 797f86232838cf712377867cb42417c1613ab5dc425Dmitry Shmidt * discovered its capabilities. 798f86232838cf712377867cb42417c1613ab5dc425Dmitry Shmidt * 799f86232838cf712377867cb42417c1613ab5dc425Dmitry Shmidt * At least for now, do this only if the peer was detected on 800f86232838cf712377867cb42417c1613ab5dc425Dmitry Shmidt * one of the social channels since that peer can be easily be 801f86232838cf712377867cb42417c1613ab5dc425Dmitry Shmidt * found again and there are no limitations of having to use 802f86232838cf712377867cb42417c1613ab5dc425Dmitry Shmidt * passive scan on this channels, so this can be done through 803f86232838cf712377867cb42417c1613ab5dc425Dmitry Shmidt * Probe Response frame that includes the config_methods 804f86232838cf712377867cb42417c1613ab5dc425Dmitry Shmidt * information. 805f86232838cf712377867cb42417c1613ab5dc425Dmitry Shmidt */ 806b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt p2p_dbg(p2p, "Do not report peer " MACSTR 807b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt " with unknown config methods", MAC2STR(addr)); 808f86232838cf712377867cb42417c1613ab5dc425Dmitry Shmidt return 0; 809f86232838cf712377867cb42417c1613ab5dc425Dmitry Shmidt } 810f86232838cf712377867cb42417c1613ab5dc425Dmitry Shmidt 8118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p->cfg->dev_found(p2p->cfg->cb_ctx, addr, &dev->info, 8128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt !(dev->flags & P2P_DEV_REPORTED_ONCE)); 8138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt dev->flags |= P2P_DEV_REPORTED | P2P_DEV_REPORTED_ONCE; 8148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 8158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 8168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 8178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 8188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 8198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic void p2p_device_free(struct p2p_data *p2p, struct p2p_device *dev) 8208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 8218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt int i; 8228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 823497c1d5e50162d6b3c1cce5dbd9c5fd9da69aaefDmitry Shmidt if (p2p->go_neg_peer == dev) { 8241f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt /* 8251f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt * If GO Negotiation is in progress, report that it has failed. 8261f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt */ 827497c1d5e50162d6b3c1cce5dbd9c5fd9da69aaefDmitry Shmidt p2p_go_neg_failed(p2p, dev, -1); 8288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p->go_neg_peer = NULL; 829497c1d5e50162d6b3c1cce5dbd9c5fd9da69aaefDmitry Shmidt } 8308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (p2p->invite_peer == dev) 8318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p->invite_peer = NULL; 8328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (p2p->sd_peer == dev) 8338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p->sd_peer = NULL; 8348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (p2p->pending_client_disc_go == dev) 8358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p->pending_client_disc_go = NULL; 8368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 837c55524ad84d13014e8019491c2b17e5dcf13545aDmitry Shmidt /* dev_lost() device, but only if it was previously dev_found() */ 838c55524ad84d13014e8019491c2b17e5dcf13545aDmitry Shmidt if (dev->flags & P2P_DEV_REPORTED_ONCE) 839c55524ad84d13014e8019491c2b17e5dcf13545aDmitry Shmidt p2p->cfg->dev_lost(p2p->cfg->cb_ctx, 840c55524ad84d13014e8019491c2b17e5dcf13545aDmitry Shmidt dev->info.p2p_device_addr); 8418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 8428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt for (i = 0; i < P2P_MAX_WPS_VENDOR_EXT; i++) { 8438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpabuf_free(dev->info.wps_vendor_ext[i]); 8448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt dev->info.wps_vendor_ext[i] = NULL; 8458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 8468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 84761d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt wpabuf_free(dev->info.wfd_subelems); 84861d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt 8498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_free(dev); 8508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 8518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 8528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 8538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic int p2p_get_next_prog_freq(struct p2p_data *p2p) 8548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 8558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct p2p_channels *c; 8568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct p2p_reg_class *cla; 8578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt size_t cl, ch; 8588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt int found = 0; 8598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt u8 reg_class; 8608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt u8 channel; 8618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt int freq; 8628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 8638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt c = &p2p->cfg->channels; 8648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt for (cl = 0; cl < c->reg_classes; cl++) { 8658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt cla = &c->reg_class[cl]; 8668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (cla->reg_class != p2p->last_prog_scan_class) 8678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt continue; 8688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt for (ch = 0; ch < cla->channels; ch++) { 8698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (cla->channel[ch] == p2p->last_prog_scan_chan) { 8708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt found = 1; 8718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 8728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 8738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 8748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (found) 8758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 8768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 8778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 8788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (!found) { 8798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* Start from beginning */ 8808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt reg_class = c->reg_class[0].reg_class; 8818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt channel = c->reg_class[0].channel[0]; 8828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } else { 8838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* Pick the next channel */ 8848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ch++; 8858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (ch == cla->channels) { 8868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt cl++; 8878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (cl == c->reg_classes) 8888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt cl = 0; 8898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ch = 0; 8908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 8918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt reg_class = c->reg_class[cl].reg_class; 8928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt channel = c->reg_class[cl].channel[ch]; 8938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 8948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 8954b06059785b935dd1f4f09314e4e12c417d2c6a4Dmitry Shmidt freq = p2p_channel_to_freq(reg_class, channel); 896b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt p2p_dbg(p2p, "Next progressive search channel: reg_class %u channel %u -> %d MHz", 8978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt reg_class, channel, freq); 8988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p->last_prog_scan_class = reg_class; 8998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p->last_prog_scan_chan = channel; 9008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 9018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (freq == 2412 || freq == 2437 || freq == 2462) 9028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; /* No need to add social channels */ 9038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return freq; 9048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 9058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 9068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 9078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic void p2p_search(struct p2p_data *p2p) 9088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 9098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt int freq = 0; 9108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt enum p2p_scan_type type; 91104949598a23f501be6eec21697465fd46a28840aDmitry Shmidt u16 pw_id = DEV_PW_DEFAULT; 91261d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt int res; 9138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 9148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (p2p->drv_in_listen) { 915b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt p2p_dbg(p2p, "Driver is still in Listen state - wait for it to end before continuing"); 9168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; 9178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 9188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p->cfg->stop_listen(p2p->cfg->cb_ctx); 9198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 92004949598a23f501be6eec21697465fd46a28840aDmitry Shmidt if (p2p->find_type == P2P_FIND_PROGRESSIVE && 92104949598a23f501be6eec21697465fd46a28840aDmitry Shmidt (freq = p2p_get_next_prog_freq(p2p)) > 0) { 9228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt type = P2P_SCAN_SOCIAL_PLUS_ONE; 923b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt p2p_dbg(p2p, "Starting search (+ freq %u)", freq); 9248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } else { 9258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt type = P2P_SCAN_SOCIAL; 926b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt p2p_dbg(p2p, "Starting search"); 9278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 9288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 92961d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt res = p2p->cfg->p2p_scan(p2p->cfg->cb_ctx, type, freq, 93061d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt p2p->num_req_dev_types, p2p->req_dev_types, 93161d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt p2p->find_dev_id, pw_id); 93261d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt if (res < 0) { 933b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt p2p_dbg(p2p, "Scan request failed"); 9348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_continue_find(p2p); 93561d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt } else if (res == 1) { 936b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt p2p_dbg(p2p, "Could not start p2p_scan at this point - will try again after previous scan completes"); 93761d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt p2p_set_state(p2p, P2P_CONTINUE_SEARCH_WHEN_READY); 9388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } else { 939b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt p2p_dbg(p2p, "Running p2p_scan"); 9408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p->p2p_scan_running = 1; 9418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt eloop_cancel_timeout(p2p_scan_timeout, p2p, NULL); 9428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt eloop_register_timeout(P2P_SCAN_TIMEOUT, 0, p2p_scan_timeout, 9438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p, NULL); 9448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 9458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 9468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 9478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 9488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic void p2p_find_timeout(void *eloop_ctx, void *timeout_ctx) 9498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 9508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct p2p_data *p2p = eloop_ctx; 951b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt p2p_dbg(p2p, "Find timeout -> stop"); 9528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_stop_find(p2p); 9538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 9548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 9558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 9568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic int p2p_run_after_scan(struct p2p_data *p2p) 9578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 9588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct p2p_device *dev; 9598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt enum p2p_after_scan op; 9608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 9618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (p2p->after_scan_tx) { 9628da800a193fb6f8832218715f82a7b4e2d2ad338Dmitry Shmidt p2p->after_scan_tx_in_progress = 1; 963b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt p2p_dbg(p2p, "Send pending Action frame at p2p_scan completion"); 9641f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt p2p->cfg->send_action(p2p->cfg->cb_ctx, 9651f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt p2p->after_scan_tx->freq, 9661f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt p2p->after_scan_tx->dst, 9671f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt p2p->after_scan_tx->src, 9681f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt p2p->after_scan_tx->bssid, 9691f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt (u8 *) (p2p->after_scan_tx + 1), 9701f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt p2p->after_scan_tx->len, 9711f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt p2p->after_scan_tx->wait_time); 9728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_free(p2p->after_scan_tx); 9738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p->after_scan_tx = NULL; 974f44b9c4a18d17fbd39901f76a014c32006570fb8Irfan Sheriff#ifdef ANDROID_P2P 975f44b9c4a18d17fbd39901f76a014c32006570fb8Irfan Sheriff /* For SD frames, there is a scenario, where we can receive a SD request frame during p2p_scan. 976f44b9c4a18d17fbd39901f76a014c32006570fb8Irfan Sheriff * At that moment, we will send the SD response from this context. After sending the SD response, 977f44b9c4a18d17fbd39901f76a014c32006570fb8Irfan Sheriff * we need to continue p2p_find. But if we return 1 from here, p2p_find is going to be stopped. 978f44b9c4a18d17fbd39901f76a014c32006570fb8Irfan Sheriff */ 979f44b9c4a18d17fbd39901f76a014c32006570fb8Irfan Sheriff return 0; 980f44b9c4a18d17fbd39901f76a014c32006570fb8Irfan Sheriff#else 9818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 1; 982f44b9c4a18d17fbd39901f76a014c32006570fb8Irfan Sheriff#endif 9838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 9848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 9858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt op = p2p->start_after_scan; 9868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p->start_after_scan = P2P_AFTER_SCAN_NOTHING; 9878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt switch (op) { 9888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case P2P_AFTER_SCAN_NOTHING: 9898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 9908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case P2P_AFTER_SCAN_LISTEN: 991b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt p2p_dbg(p2p, "Start previously requested Listen state"); 9928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_listen(p2p, p2p->pending_listen_sec * 1000 + 9938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p->pending_listen_usec / 1000); 9948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 1; 9958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case P2P_AFTER_SCAN_CONNECT: 996b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt p2p_dbg(p2p, "Start previously requested connect with " MACSTR, 9978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt MAC2STR(p2p->after_scan_peer)); 9988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt dev = p2p_get_device(p2p, p2p->after_scan_peer); 9998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (dev == NULL) { 1000b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt p2p_dbg(p2p, "Peer not known anymore"); 10018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 10028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 10038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_connect_send(p2p, dev); 10048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 1; 10058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 10068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 10078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 10088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 10098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 10108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 10118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic void p2p_scan_timeout(void *eloop_ctx, void *timeout_ctx) 10128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 10138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct p2p_data *p2p = eloop_ctx; 10148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt int running; 1015b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt p2p_dbg(p2p, "p2p_scan timeout (running=%d)", p2p->p2p_scan_running); 10168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt running = p2p->p2p_scan_running; 10178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* Make sure we recover from missed scan results callback */ 10188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p->p2p_scan_running = 0; 10198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 10208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (running) 10218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_run_after_scan(p2p); 10228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 10238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 10248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 10258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic void p2p_free_req_dev_types(struct p2p_data *p2p) 10268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 10278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p->num_req_dev_types = 0; 10288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_free(p2p->req_dev_types); 10298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p->req_dev_types = NULL; 10308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 10318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 10328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 10338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtint p2p_find(struct p2p_data *p2p, unsigned int timeout, 10348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt enum p2p_discovery_type type, 1035c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt unsigned int num_req_dev_types, const u8 *req_dev_types, 103661d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt const u8 *dev_id, unsigned int search_delay) 10378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 10388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt int res; 10398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1040b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt p2p_dbg(p2p, "Starting find (type=%d)", type); 1041f86232838cf712377867cb42417c1613ab5dc425Dmitry Shmidt os_get_time(&p2p->find_start); 10428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (p2p->p2p_scan_running) { 1043b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt p2p_dbg(p2p, "p2p_scan is already running"); 10448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 10458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 10468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_free_req_dev_types(p2p); 10478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (req_dev_types && num_req_dev_types) { 10488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p->req_dev_types = os_malloc(num_req_dev_types * 10498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt WPS_DEV_TYPE_LEN); 10508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (p2p->req_dev_types == NULL) 10518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 10528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memcpy(p2p->req_dev_types, req_dev_types, 10538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt num_req_dev_types * WPS_DEV_TYPE_LEN); 10548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p->num_req_dev_types = num_req_dev_types; 10558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 10568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1057c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt if (dev_id) { 1058c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt os_memcpy(p2p->find_dev_id_buf, dev_id, ETH_ALEN); 1059c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt p2p->find_dev_id = p2p->find_dev_id_buf; 1060c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt } else 1061c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt p2p->find_dev_id = NULL; 1062c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt 10638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p->start_after_scan = P2P_AFTER_SCAN_NOTHING; 10648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_clear_timeout(p2p); 10658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p->cfg->stop_listen(p2p->cfg->cb_ctx); 10668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p->find_type = type; 10678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_device_clear_reported(p2p); 10688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_set_state(p2p, P2P_SEARCH); 106961d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt p2p->search_delay = search_delay; 107061d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt p2p->in_search_delay = 0; 10718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt eloop_cancel_timeout(p2p_find_timeout, p2p, NULL); 10721f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt p2p->last_p2p_find_timeout = timeout; 10738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (timeout) 10748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt eloop_register_timeout(timeout, 0, p2p_find_timeout, 10758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p, NULL); 10768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt switch (type) { 10778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case P2P_FIND_START_WITH_FULL: 10788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case P2P_FIND_PROGRESSIVE: 10798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt res = p2p->cfg->p2p_scan(p2p->cfg->cb_ctx, P2P_SCAN_FULL, 0, 10808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p->num_req_dev_types, 108104949598a23f501be6eec21697465fd46a28840aDmitry Shmidt p2p->req_dev_types, dev_id, 108204949598a23f501be6eec21697465fd46a28840aDmitry Shmidt DEV_PW_DEFAULT); 10838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 10848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case P2P_FIND_ONLY_SOCIAL: 10858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt res = p2p->cfg->p2p_scan(p2p->cfg->cb_ctx, P2P_SCAN_SOCIAL, 0, 10868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p->num_req_dev_types, 108704949598a23f501be6eec21697465fd46a28840aDmitry Shmidt p2p->req_dev_types, dev_id, 108804949598a23f501be6eec21697465fd46a28840aDmitry Shmidt DEV_PW_DEFAULT); 10898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 10908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt default: 10918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 10928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 10938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 10948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (res == 0) { 1095b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt p2p_dbg(p2p, "Running p2p_scan"); 10968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p->p2p_scan_running = 1; 10978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt eloop_cancel_timeout(p2p_scan_timeout, p2p, NULL); 10988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt eloop_register_timeout(P2P_SCAN_TIMEOUT, 0, p2p_scan_timeout, 10998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p, NULL); 11001f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt } else if (res == 1) { 1101b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt p2p_dbg(p2p, "Could not start p2p_scan at this point - will try again after previous scan completes"); 11021f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt res = 0; 11031f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt p2p_set_state(p2p, P2P_SEARCH_WHEN_READY); 11041f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt eloop_cancel_timeout(p2p_find_timeout, p2p, NULL); 11058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } else { 1106b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt p2p_dbg(p2p, "Failed to start p2p_scan"); 11071f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt p2p_set_state(p2p, P2P_IDLE); 11081f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt eloop_cancel_timeout(p2p_find_timeout, p2p, NULL); 11098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 11108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 11118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return res; 11128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 11138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 11142fb777c379ad560c309c54b96c2c13291da23f54Dmitry Shmidt#ifdef ANDROID_P2P 11152fb777c379ad560c309c54b96c2c13291da23f54Dmitry Shmidtint p2p_search_pending(struct p2p_data *p2p) 11162fb777c379ad560c309c54b96c2c13291da23f54Dmitry Shmidt{ 11172fb777c379ad560c309c54b96c2c13291da23f54Dmitry Shmidt if(p2p == NULL) 11182fb777c379ad560c309c54b96c2c13291da23f54Dmitry Shmidt return 0; 11192fb777c379ad560c309c54b96c2c13291da23f54Dmitry Shmidt 11202fb777c379ad560c309c54b96c2c13291da23f54Dmitry Shmidt if(p2p->state == P2P_SEARCH_WHEN_READY) 11212fb777c379ad560c309c54b96c2c13291da23f54Dmitry Shmidt return 1; 11222fb777c379ad560c309c54b96c2c13291da23f54Dmitry Shmidt 11232fb777c379ad560c309c54b96c2c13291da23f54Dmitry Shmidt return 0; 11242fb777c379ad560c309c54b96c2c13291da23f54Dmitry Shmidt} 11252fb777c379ad560c309c54b96c2c13291da23f54Dmitry Shmidt#endif 11268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 11271f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidtint p2p_other_scan_completed(struct p2p_data *p2p) 11281f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt{ 112961d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt if (p2p->state == P2P_CONTINUE_SEARCH_WHEN_READY) { 113061d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt p2p_set_state(p2p, P2P_SEARCH); 113161d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt p2p_search(p2p); 113261d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt return 1; 113361d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt } 11341f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt if (p2p->state != P2P_SEARCH_WHEN_READY) 11351f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt return 0; 1136b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt p2p_dbg(p2p, "Starting pending P2P find now that previous scan was completed"); 11371f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt if (p2p_find(p2p, p2p->last_p2p_find_timeout, p2p->find_type, 1138c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt p2p->num_req_dev_types, p2p->req_dev_types, 1139f86232838cf712377867cb42417c1613ab5dc425Dmitry Shmidt p2p->find_dev_id, p2p->search_delay) < 0) { 1140b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt p2p->cfg->find_stopped(p2p->cfg->cb_ctx); 11411f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt return 0; 1142f86232838cf712377867cb42417c1613ab5dc425Dmitry Shmidt } 11431f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt return 1; 11441f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt} 11451f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt 11461f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt 11478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtvoid p2p_stop_find_for_freq(struct p2p_data *p2p, int freq) 11488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 1149b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt p2p_dbg(p2p, "Stopping find"); 11508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt eloop_cancel_timeout(p2p_find_timeout, p2p, NULL); 11518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_clear_timeout(p2p); 1152a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt if (p2p->state == P2P_SEARCH || 1153a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt p2p->state == P2P_CONTINUE_SEARCH_WHEN_READY || 1154a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt p2p->state == P2P_SEARCH_WHEN_READY) 1155b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt p2p->cfg->find_stopped(p2p->cfg->cb_ctx); 11568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_set_state(p2p, P2P_IDLE); 11578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_free_req_dev_types(p2p); 11588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p->start_after_scan = P2P_AFTER_SCAN_NOTHING; 11598c65289885e84727226d81b3d32856f79c31ee5fDmitry Shmidt if (p2p->go_neg_peer) 11608c65289885e84727226d81b3d32856f79c31ee5fDmitry Shmidt p2p->go_neg_peer->flags &= ~P2P_DEV_PEER_WAITING_RESPONSE; 11618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p->go_neg_peer = NULL; 11628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p->sd_peer = NULL; 11638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p->invite_peer = NULL; 116404949598a23f501be6eec21697465fd46a28840aDmitry Shmidt p2p_stop_listen_for_freq(p2p, freq); 116504949598a23f501be6eec21697465fd46a28840aDmitry Shmidt} 116604949598a23f501be6eec21697465fd46a28840aDmitry Shmidt 116704949598a23f501be6eec21697465fd46a28840aDmitry Shmidt 116804949598a23f501be6eec21697465fd46a28840aDmitry Shmidtvoid p2p_stop_listen_for_freq(struct p2p_data *p2p, int freq) 116904949598a23f501be6eec21697465fd46a28840aDmitry Shmidt{ 11708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (freq > 0 && p2p->drv_in_listen == freq && p2p->in_listen) { 1171b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt p2p_dbg(p2p, "Skip stop_listen since we are on correct channel for response"); 11728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; 11738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 117404949598a23f501be6eec21697465fd46a28840aDmitry Shmidt if (p2p->in_listen) { 117504949598a23f501be6eec21697465fd46a28840aDmitry Shmidt p2p->in_listen = 0; 117604949598a23f501be6eec21697465fd46a28840aDmitry Shmidt p2p_clear_timeout(p2p); 117704949598a23f501be6eec21697465fd46a28840aDmitry Shmidt } 11781f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt if (p2p->drv_in_listen) { 11791f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt /* 11801f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt * The driver may not deliver callback to p2p_listen_end() 11811f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt * when the operation gets canceled, so clear the internal 11821f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt * variable that is tracking driver state. 11831f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt */ 1184b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt p2p_dbg(p2p, "Clear drv_in_listen (%d)", p2p->drv_in_listen); 11851f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt p2p->drv_in_listen = 0; 11861f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt } 11878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p->cfg->stop_listen(p2p->cfg->cb_ctx); 11888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 11898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 11908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1191391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidtvoid p2p_stop_listen(struct p2p_data *p2p) 1192391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt{ 1193391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt if (p2p->state != P2P_LISTEN_ONLY) { 1194391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt p2p_dbg(p2p, "Skip stop_listen since not in listen_only state."); 1195391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt return; 1196391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt } 1197391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt 1198391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt p2p_stop_listen_for_freq(p2p, 0); 1199391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt p2p_set_state(p2p, P2P_IDLE); 1200391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt} 1201391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt 1202391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt 12038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtvoid p2p_stop_find(struct p2p_data *p2p) 12048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 12058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_stop_find_for_freq(p2p, 0); 12068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 12078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 12088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1209a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidtstatic int p2p_prepare_channel_pref(struct p2p_data *p2p, 1210a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt unsigned int force_freq, 1211a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt unsigned int pref_freq) 12128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 1213a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt u8 op_class, op_channel; 1214a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt unsigned int freq = force_freq ? force_freq : pref_freq; 12158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1216b7b4d0ec07161a6d76c40ba7ef1306e82fbb7e15Dmitry Shmidt p2p_dbg(p2p, "Prepare channel pref - force_freq=%u pref_freq=%u", 1217b7b4d0ec07161a6d76c40ba7ef1306e82fbb7e15Dmitry Shmidt force_freq, pref_freq); 12184b06059785b935dd1f4f09314e4e12c417d2c6a4Dmitry Shmidt if (p2p_freq_to_channel(freq, &op_class, &op_channel) < 0) { 1219b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt p2p_dbg(p2p, "Unsupported frequency %u MHz", freq); 1220a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt return -1; 1221a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt } 1222a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt 1223a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt if (!p2p_channels_includes(&p2p->cfg->channels, op_class, op_channel)) { 1224b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt p2p_dbg(p2p, "Frequency %u MHz (oper_class %u channel %u) not allowed for P2P", 1225b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt freq, op_class, op_channel); 1226a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt return -1; 1227a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt } 1228a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt 1229a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt p2p->op_reg_class = op_class; 1230a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt p2p->op_channel = op_channel; 12318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1232a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt if (force_freq) { 1233a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt p2p->channels.reg_classes = 1; 1234a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt p2p->channels.reg_class[0].channels = 1; 1235a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt p2p->channels.reg_class[0].reg_class = p2p->op_reg_class; 1236a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt p2p->channels.reg_class[0].channel[0] = p2p->op_channel; 1237a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt } else { 12388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memcpy(&p2p->channels, &p2p->cfg->channels, 12398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sizeof(struct p2p_channels)); 12408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 1241a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt 1242a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt return 0; 1243a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt} 1244a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt 1245a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt 1246a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidtstatic void p2p_prepare_channel_best(struct p2p_data *p2p) 1247a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt{ 1248a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt u8 op_class, op_channel; 1249a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt 1250b7b4d0ec07161a6d76c40ba7ef1306e82fbb7e15Dmitry Shmidt p2p_dbg(p2p, "Prepare channel best"); 1251b7b4d0ec07161a6d76c40ba7ef1306e82fbb7e15Dmitry Shmidt 1252a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt if (!p2p->cfg->cfg_op_channel && p2p->best_freq_overall > 0 && 1253a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt p2p_supported_freq(p2p, p2p->best_freq_overall) && 12544b06059785b935dd1f4f09314e4e12c417d2c6a4Dmitry Shmidt p2p_freq_to_channel(p2p->best_freq_overall, &op_class, &op_channel) 12554b06059785b935dd1f4f09314e4e12c417d2c6a4Dmitry Shmidt == 0) { 1256b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt p2p_dbg(p2p, "Select best overall channel as operating channel preference"); 1257a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt p2p->op_reg_class = op_class; 1258a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt p2p->op_channel = op_channel; 1259a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt } else if (!p2p->cfg->cfg_op_channel && p2p->best_freq_5 > 0 && 1260a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt p2p_supported_freq(p2p, p2p->best_freq_5) && 12614b06059785b935dd1f4f09314e4e12c417d2c6a4Dmitry Shmidt p2p_freq_to_channel(p2p->best_freq_5, &op_class, &op_channel) 12624b06059785b935dd1f4f09314e4e12c417d2c6a4Dmitry Shmidt == 0) { 1263b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt p2p_dbg(p2p, "Select best 5 GHz channel as operating channel preference"); 1264a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt p2p->op_reg_class = op_class; 1265a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt p2p->op_channel = op_channel; 1266a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt } else if (!p2p->cfg->cfg_op_channel && p2p->best_freq_24 > 0 && 1267a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt p2p_supported_freq(p2p, p2p->best_freq_24) && 12684b06059785b935dd1f4f09314e4e12c417d2c6a4Dmitry Shmidt p2p_freq_to_channel(p2p->best_freq_24, &op_class, 12694b06059785b935dd1f4f09314e4e12c417d2c6a4Dmitry Shmidt &op_channel) == 0) { 1270b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt p2p_dbg(p2p, "Select best 2.4 GHz channel as operating channel preference"); 1271a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt p2p->op_reg_class = op_class; 1272a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt p2p->op_channel = op_channel; 1273b7b4d0ec07161a6d76c40ba7ef1306e82fbb7e15Dmitry Shmidt } else if (p2p->cfg->num_pref_chan > 0 && 1274b7b4d0ec07161a6d76c40ba7ef1306e82fbb7e15Dmitry Shmidt p2p_channels_includes(&p2p->cfg->channels, 1275b7b4d0ec07161a6d76c40ba7ef1306e82fbb7e15Dmitry Shmidt p2p->cfg->pref_chan[0].op_class, 1276b7b4d0ec07161a6d76c40ba7ef1306e82fbb7e15Dmitry Shmidt p2p->cfg->pref_chan[0].chan)) { 1277b7b4d0ec07161a6d76c40ba7ef1306e82fbb7e15Dmitry Shmidt p2p_dbg(p2p, "Select first pref_chan entry as operating channel preference"); 1278b7b4d0ec07161a6d76c40ba7ef1306e82fbb7e15Dmitry Shmidt p2p->op_reg_class = p2p->cfg->pref_chan[0].op_class; 1279b7b4d0ec07161a6d76c40ba7ef1306e82fbb7e15Dmitry Shmidt p2p->op_channel = p2p->cfg->pref_chan[0].chan; 1280a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt } else { 1281b7b4d0ec07161a6d76c40ba7ef1306e82fbb7e15Dmitry Shmidt p2p_dbg(p2p, "Select pre-configured channel as operating channel preference"); 1282a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt p2p->op_reg_class = p2p->cfg->op_reg_class; 1283a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt p2p->op_channel = p2p->cfg->op_channel; 1284a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt } 1285a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt 1286a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt os_memcpy(&p2p->channels, &p2p->cfg->channels, 1287a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt sizeof(struct p2p_channels)); 1288a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt} 1289a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt 1290a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt 1291a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt/** 1292a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt * p2p_prepare_channel - Select operating channel for GO Negotiation 1293a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt * @p2p: P2P module context from p2p_init() 1294a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt * @dev: Selected peer device 1295a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt * @force_freq: Forced frequency in MHz or 0 if not forced 1296a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt * @pref_freq: Preferred frequency in MHz or 0 if no preference 1297a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt * Returns: 0 on success, -1 on failure (channel not supported for P2P) 1298a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt * 1299a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt * This function is used to do initial operating channel selection for GO 1300a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt * Negotiation prior to having received peer information. The selected channel 1301a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt * may be further optimized in p2p_reselect_channel() once the peer information 1302a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt * is available. 1303a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt */ 13047a5e50a0554bee77a9da492ea3d86f46147f1671Dmitry Shmidtint p2p_prepare_channel(struct p2p_data *p2p, struct p2p_device *dev, 13057a5e50a0554bee77a9da492ea3d86f46147f1671Dmitry Shmidt unsigned int force_freq, unsigned int pref_freq) 1306a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt{ 1307b7b4d0ec07161a6d76c40ba7ef1306e82fbb7e15Dmitry Shmidt p2p_dbg(p2p, "Prepare channel - force_freq=%u pref_freq=%u", 1308b7b4d0ec07161a6d76c40ba7ef1306e82fbb7e15Dmitry Shmidt force_freq, pref_freq); 1309a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt if (force_freq || pref_freq) { 1310a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt if (p2p_prepare_channel_pref(p2p, force_freq, pref_freq) < 0) 1311a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt return -1; 1312a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt } else { 1313a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt p2p_prepare_channel_best(p2p); 1314a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt } 1315b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt p2p_dbg(p2p, "Own preference for operation channel: Operating Class %u Channel %u%s", 13168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p->op_reg_class, p2p->op_channel, 13178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt force_freq ? " (forced)" : ""); 13188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1319a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt if (force_freq) 1320a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt dev->flags |= P2P_DEV_FORCE_FREQ; 1321a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt else 1322a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt dev->flags &= ~P2P_DEV_FORCE_FREQ; 1323a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt 13248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 13258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 13268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 13278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 13281f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidtstatic void p2p_set_dev_persistent(struct p2p_device *dev, 13291f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt int persistent_group) 13301f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt{ 13311f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt switch (persistent_group) { 13321f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt case 0: 13331f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt dev->flags &= ~(P2P_DEV_PREFER_PERSISTENT_GROUP | 13341f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt P2P_DEV_PREFER_PERSISTENT_RECONN); 13351f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt break; 13361f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt case 1: 13371f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt dev->flags |= P2P_DEV_PREFER_PERSISTENT_GROUP; 13381f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt dev->flags &= ~P2P_DEV_PREFER_PERSISTENT_RECONN; 13391f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt break; 13401f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt case 2: 13411f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt dev->flags |= P2P_DEV_PREFER_PERSISTENT_GROUP | 13421f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt P2P_DEV_PREFER_PERSISTENT_RECONN; 13431f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt break; 13441f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt } 13451f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt} 13461f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt 13471f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt 13488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtint p2p_connect(struct p2p_data *p2p, const u8 *peer_addr, 13498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt enum p2p_wps_method wps_method, 13508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt int go_intent, const u8 *own_interface_addr, 135104949598a23f501be6eec21697465fd46a28840aDmitry Shmidt unsigned int force_freq, int persistent_group, 135204949598a23f501be6eec21697465fd46a28840aDmitry Shmidt const u8 *force_ssid, size_t force_ssid_len, 1353d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt int pd_before_go_neg, unsigned int pref_freq) 13548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 13558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct p2p_device *dev; 13568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1357b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt p2p_dbg(p2p, "Request to start group negotiation - peer=" MACSTR 13588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt " GO Intent=%d Intended Interface Address=" MACSTR 1359d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt " wps_method=%d persistent_group=%d pd_before_go_neg=%d", 13608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt MAC2STR(peer_addr), go_intent, MAC2STR(own_interface_addr), 1361d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt wps_method, persistent_group, pd_before_go_neg); 13628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 13638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt dev = p2p_get_device(p2p, peer_addr); 13648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (dev == NULL || (dev->flags & P2P_DEV_PROBE_REQ_ONLY)) { 1365b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt p2p_dbg(p2p, "Cannot connect to unknown P2P Device " MACSTR, 13668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt MAC2STR(peer_addr)); 13678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 13688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 13698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1370a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt if (p2p_prepare_channel(p2p, dev, force_freq, pref_freq) < 0) 1371a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt return -1; 1372a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt 13738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (dev->flags & P2P_DEV_GROUP_CLIENT_ONLY) { 13748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (!(dev->info.dev_capab & 13758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt P2P_DEV_CAPAB_CLIENT_DISCOVERABILITY)) { 1376b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt p2p_dbg(p2p, "Cannot connect to P2P Device " MACSTR 13778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt " that is in a group and is not discoverable", 13788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt MAC2STR(peer_addr)); 13798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 13808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 13818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (dev->oper_freq <= 0) { 1382b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt p2p_dbg(p2p, "Cannot connect to P2P Device " MACSTR 13838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt " with incomplete information", 13848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt MAC2STR(peer_addr)); 13858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 13868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 13878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 13888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* 13898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * First, try to connect directly. If the peer does not 13908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * acknowledge frames, assume it is sleeping and use device 13918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * discoverability via the GO at that point. 13928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */ 13938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 13948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 139504949598a23f501be6eec21697465fd46a28840aDmitry Shmidt p2p->ssid_set = 0; 139604949598a23f501be6eec21697465fd46a28840aDmitry Shmidt if (force_ssid) { 139704949598a23f501be6eec21697465fd46a28840aDmitry Shmidt wpa_hexdump_ascii(MSG_DEBUG, "P2P: Forced SSID", 139804949598a23f501be6eec21697465fd46a28840aDmitry Shmidt force_ssid, force_ssid_len); 139904949598a23f501be6eec21697465fd46a28840aDmitry Shmidt os_memcpy(p2p->ssid, force_ssid, force_ssid_len); 140004949598a23f501be6eec21697465fd46a28840aDmitry Shmidt p2p->ssid_len = force_ssid_len; 140104949598a23f501be6eec21697465fd46a28840aDmitry Shmidt p2p->ssid_set = 1; 140204949598a23f501be6eec21697465fd46a28840aDmitry Shmidt } 140304949598a23f501be6eec21697465fd46a28840aDmitry Shmidt 14048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt dev->flags &= ~P2P_DEV_NOT_YET_READY; 14058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt dev->flags &= ~P2P_DEV_USER_REJECTED; 14068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt dev->flags &= ~P2P_DEV_WAIT_GO_NEG_RESPONSE; 14078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt dev->flags &= ~P2P_DEV_WAIT_GO_NEG_CONFIRM; 140804949598a23f501be6eec21697465fd46a28840aDmitry Shmidt if (pd_before_go_neg) 140904949598a23f501be6eec21697465fd46a28840aDmitry Shmidt dev->flags |= P2P_DEV_PD_BEFORE_GO_NEG; 1410a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt else { 141104949598a23f501be6eec21697465fd46a28840aDmitry Shmidt dev->flags &= ~P2P_DEV_PD_BEFORE_GO_NEG; 1412a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt /* 14139cdf1b905fae57dea42506a1af67f6ece544b261Dmitry Shmidt * Assign dialog token and tie breaker here to use the same 14149cdf1b905fae57dea42506a1af67f6ece544b261Dmitry Shmidt * values in each retry within the same GO Negotiation exchange. 1415a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt */ 1416a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt dev->dialog_token++; 1417a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt if (dev->dialog_token == 0) 1418a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt dev->dialog_token = 1; 14199cdf1b905fae57dea42506a1af67f6ece544b261Dmitry Shmidt dev->tie_breaker = p2p->next_tie_breaker; 14209cdf1b905fae57dea42506a1af67f6ece544b261Dmitry Shmidt p2p->next_tie_breaker = !p2p->next_tie_breaker; 1421a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt } 14228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt dev->connect_reqs = 0; 14238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt dev->go_neg_req_sent = 0; 14248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt dev->go_state = UNKNOWN_GO; 14251f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt p2p_set_dev_persistent(dev, persistent_group); 14268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p->go_intent = go_intent; 14278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memcpy(p2p->intended_addr, own_interface_addr, ETH_ALEN); 14288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 14298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (p2p->state != P2P_IDLE) 14308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_stop_find(p2p); 14318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 14328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (p2p->after_scan_tx) { 14338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* 14348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * We need to drop the pending frame to avoid issues with the 14358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * new GO Negotiation, e.g., when the pending frame was from a 14368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * previous attempt at starting a GO Negotiation. 14378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */ 1438b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt p2p_dbg(p2p, "Dropped previous pending Action frame TX that was waiting for p2p_scan completion"); 14398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_free(p2p->after_scan_tx); 14408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p->after_scan_tx = NULL; 14418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 14428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 14438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt dev->wps_method = wps_method; 14448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt dev->status = P2P_SC_SUCCESS; 14458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 14468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (p2p->p2p_scan_running) { 1447b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt p2p_dbg(p2p, "p2p_scan running - delay connect send"); 14488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p->start_after_scan = P2P_AFTER_SCAN_CONNECT; 14498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memcpy(p2p->after_scan_peer, peer_addr, ETH_ALEN); 14508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 14518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 14528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p->start_after_scan = P2P_AFTER_SCAN_NOTHING; 14538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 14548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return p2p_connect_send(p2p, dev); 14558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 14568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 14578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 14588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtint p2p_authorize(struct p2p_data *p2p, const u8 *peer_addr, 14598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt enum p2p_wps_method wps_method, 14608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt int go_intent, const u8 *own_interface_addr, 146104949598a23f501be6eec21697465fd46a28840aDmitry Shmidt unsigned int force_freq, int persistent_group, 1462d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt const u8 *force_ssid, size_t force_ssid_len, 1463d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt unsigned int pref_freq) 14648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 14658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct p2p_device *dev; 14668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1467b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt p2p_dbg(p2p, "Request to authorize group negotiation - peer=" MACSTR 14688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt " GO Intent=%d Intended Interface Address=" MACSTR 14698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt " wps_method=%d persistent_group=%d", 14708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt MAC2STR(peer_addr), go_intent, MAC2STR(own_interface_addr), 14718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wps_method, persistent_group); 14728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 14738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt dev = p2p_get_device(p2p, peer_addr); 14748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (dev == NULL) { 1475b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt p2p_dbg(p2p, "Cannot authorize unknown P2P Device " MACSTR, 14768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt MAC2STR(peer_addr)); 14778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 14788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 14798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1480a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt if (p2p_prepare_channel(p2p, dev, force_freq, pref_freq) < 0) 1481a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt return -1; 1482a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt 148304949598a23f501be6eec21697465fd46a28840aDmitry Shmidt p2p->ssid_set = 0; 148404949598a23f501be6eec21697465fd46a28840aDmitry Shmidt if (force_ssid) { 148504949598a23f501be6eec21697465fd46a28840aDmitry Shmidt wpa_hexdump_ascii(MSG_DEBUG, "P2P: Forced SSID", 148604949598a23f501be6eec21697465fd46a28840aDmitry Shmidt force_ssid, force_ssid_len); 148704949598a23f501be6eec21697465fd46a28840aDmitry Shmidt os_memcpy(p2p->ssid, force_ssid, force_ssid_len); 148804949598a23f501be6eec21697465fd46a28840aDmitry Shmidt p2p->ssid_len = force_ssid_len; 148904949598a23f501be6eec21697465fd46a28840aDmitry Shmidt p2p->ssid_set = 1; 149004949598a23f501be6eec21697465fd46a28840aDmitry Shmidt } 149104949598a23f501be6eec21697465fd46a28840aDmitry Shmidt 14928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt dev->flags &= ~P2P_DEV_NOT_YET_READY; 14938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt dev->flags &= ~P2P_DEV_USER_REJECTED; 14948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt dev->go_neg_req_sent = 0; 14958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt dev->go_state = UNKNOWN_GO; 14961f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt p2p_set_dev_persistent(dev, persistent_group); 14978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p->go_intent = go_intent; 14988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memcpy(p2p->intended_addr, own_interface_addr, ETH_ALEN); 14998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 15008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt dev->wps_method = wps_method; 15018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt dev->status = P2P_SC_SUCCESS; 15028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 15038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 15048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 15058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 15068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 15078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtvoid p2p_add_dev_info(struct p2p_data *p2p, const u8 *addr, 15088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct p2p_device *dev, struct p2p_message *msg) 15098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 15108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_get_time(&dev->last_seen); 15118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1512b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt p2p_copy_wps_info(p2p, dev, 0, msg); 15138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 15148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (msg->listen_channel) { 15158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt int freq; 15164b06059785b935dd1f4f09314e4e12c417d2c6a4Dmitry Shmidt freq = p2p_channel_to_freq(msg->listen_channel[3], 15178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt msg->listen_channel[4]); 15188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (freq < 0) { 1519b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt p2p_dbg(p2p, "Unknown peer Listen channel: " 15208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "country=%c%c(0x%02x) reg_class=%u channel=%u", 15218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt msg->listen_channel[0], 15228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt msg->listen_channel[1], 15238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt msg->listen_channel[2], 15248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt msg->listen_channel[3], 15258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt msg->listen_channel[4]); 15268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } else { 1527b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt p2p_dbg(p2p, "Update peer " MACSTR 1528b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt " Listen channel: %u -> %u MHz", 15298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt MAC2STR(dev->info.p2p_device_addr), 15308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt dev->listen_freq, freq); 15318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt dev->listen_freq = freq; 15328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 15338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 15348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 153561d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt if (msg->wfd_subelems) { 153661d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt wpabuf_free(dev->info.wfd_subelems); 153761d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt dev->info.wfd_subelems = wpabuf_dup(msg->wfd_subelems); 153861d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt } 153961d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt 15408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (dev->flags & P2P_DEV_PROBE_REQ_ONLY) { 15418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt dev->flags &= ~P2P_DEV_PROBE_REQ_ONLY; 1542b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt p2p_dbg(p2p, "Completed device entry based on data from GO Negotiation Request"); 15438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } else { 1544b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt p2p_dbg(p2p, "Created device entry based on GO Neg Req: " 15458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt MACSTR " dev_capab=0x%x group_capab=0x%x name='%s' " 15468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "listen_freq=%d", 15478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt MAC2STR(dev->info.p2p_device_addr), 15488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt dev->info.dev_capab, dev->info.group_capab, 15498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt dev->info.device_name, dev->listen_freq); 15508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 15518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 15528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt dev->flags &= ~P2P_DEV_GROUP_CLIENT_ONLY; 15538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 15548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (dev->flags & P2P_DEV_USER_REJECTED) { 1555b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt p2p_dbg(p2p, "Do not report rejected device"); 15568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; 15578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 15588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 15598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p->cfg->dev_found(p2p->cfg->cb_ctx, addr, &dev->info, 15608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt !(dev->flags & P2P_DEV_REPORTED_ONCE)); 15618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt dev->flags |= P2P_DEV_REPORTED | P2P_DEV_REPORTED_ONCE; 15628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 15638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 15648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 15658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtvoid p2p_build_ssid(struct p2p_data *p2p, u8 *ssid, size_t *ssid_len) 15668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 15678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memcpy(ssid, P2P_WILDCARD_SSID, P2P_WILDCARD_SSID_LEN); 15688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_random((char *) &ssid[P2P_WILDCARD_SSID_LEN], 2); 15698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memcpy(&ssid[P2P_WILDCARD_SSID_LEN + 2], 15708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p->cfg->ssid_postfix, p2p->cfg->ssid_postfix_len); 15718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt *ssid_len = P2P_WILDCARD_SSID_LEN + 2 + p2p->cfg->ssid_postfix_len; 15728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 15738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 15748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 15758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtint p2p_go_params(struct p2p_data *p2p, struct p2p_go_neg_results *params) 15768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 15778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_build_ssid(p2p, params->ssid, ¶ms->ssid_len); 15788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_random(params->passphrase, 8); 15798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 15808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 15818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 15828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 15838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtvoid p2p_go_complete(struct p2p_data *p2p, struct p2p_device *peer) 15848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 15858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct p2p_go_neg_results res; 15868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt int go = peer->go_state == LOCAL_GO; 15878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct p2p_channels intersection; 15888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt int freqs; 15898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt size_t i, j; 15908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1591b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt p2p_dbg(p2p, "GO Negotiation with " MACSTR " completed (%s will be GO)", 1592b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt MAC2STR(peer->info.p2p_device_addr), go ? "local end" : "peer"); 15938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 15948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memset(&res, 0, sizeof(res)); 15958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt res.role_go = go; 15968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memcpy(res.peer_device_addr, peer->info.p2p_device_addr, ETH_ALEN); 15978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memcpy(res.peer_interface_addr, peer->intended_addr, ETH_ALEN); 15988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt res.wps_method = peer->wps_method; 15991f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt if (peer->flags & P2P_DEV_PREFER_PERSISTENT_GROUP) { 16001f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt if (peer->flags & P2P_DEV_PREFER_PERSISTENT_RECONN) 16011f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt res.persistent_group = 2; 16021f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt else 16031f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt res.persistent_group = 1; 16041f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt } 16058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 16068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (go) { 16078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* Setup AP mode for WPS provisioning */ 16084b06059785b935dd1f4f09314e4e12c417d2c6a4Dmitry Shmidt res.freq = p2p_channel_to_freq(p2p->op_reg_class, 16098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p->op_channel); 16108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memcpy(res.ssid, p2p->ssid, p2p->ssid_len); 16118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt res.ssid_len = p2p->ssid_len; 16128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_random(res.passphrase, 8); 16138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } else { 16148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt res.freq = peer->oper_freq; 16158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (p2p->ssid_len) { 16168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memcpy(res.ssid, p2p->ssid, p2p->ssid_len); 16178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt res.ssid_len = p2p->ssid_len; 16188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 16198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 16208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 16218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_channels_intersect(&p2p->channels, &peer->channels, 16228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt &intersection); 16238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt freqs = 0; 16248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt for (i = 0; i < intersection.reg_classes; i++) { 16258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct p2p_reg_class *c = &intersection.reg_class[i]; 16268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (freqs + 1 == P2P_MAX_CHANNELS) 16278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 16288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt for (j = 0; j < c->channels; j++) { 16298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt int freq; 16308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (freqs + 1 == P2P_MAX_CHANNELS) 16318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 16324b06059785b935dd1f4f09314e4e12c417d2c6a4Dmitry Shmidt freq = p2p_channel_to_freq(c->reg_class, c->channel[j]); 16338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (freq < 0) 16348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt continue; 16358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt res.freq_list[freqs++] = freq; 16368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 16378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 16388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 16398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt res.peer_config_timeout = go ? peer->client_timeout : peer->go_timeout; 16408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 16418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_clear_timeout(p2p); 16421f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt p2p->ssid_set = 0; 16438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt peer->go_neg_req_sent = 0; 16448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt peer->wps_method = WPS_NOT_READY; 16458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 16468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_set_state(p2p, P2P_PROVISIONING); 16478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p->cfg->go_neg_completed(p2p->cfg->cb_ctx, &res); 16488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 16498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 16508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 16518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic void p2p_rx_p2p_action(struct p2p_data *p2p, const u8 *sa, 16528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt const u8 *data, size_t len, int rx_freq) 16538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 1654b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt p2p_dbg(p2p, "RX P2P Public Action from " MACSTR, MAC2STR(sa)); 16558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_hexdump(MSG_MSGDUMP, "P2P: P2P Public Action contents", data, len); 16568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 16578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (len < 1) 16588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; 16598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 16608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt switch (data[0]) { 16618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case P2P_GO_NEG_REQ: 16628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_process_go_neg_req(p2p, sa, data + 1, len - 1, rx_freq); 16638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 16648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case P2P_GO_NEG_RESP: 16658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_process_go_neg_resp(p2p, sa, data + 1, len - 1, rx_freq); 16668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 16678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case P2P_GO_NEG_CONF: 16688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_process_go_neg_conf(p2p, sa, data + 1, len - 1); 16698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 16708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case P2P_INVITATION_REQ: 16718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_process_invitation_req(p2p, sa, data + 1, len - 1, 16728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt rx_freq); 16738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 16748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case P2P_INVITATION_RESP: 16758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_process_invitation_resp(p2p, sa, data + 1, len - 1); 16768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 16778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case P2P_PROV_DISC_REQ: 16788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_process_prov_disc_req(p2p, sa, data + 1, len - 1, rx_freq); 16798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 16808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case P2P_PROV_DISC_RESP: 16818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_process_prov_disc_resp(p2p, sa, data + 1, len - 1); 16828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 16838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case P2P_DEV_DISC_REQ: 16848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_process_dev_disc_req(p2p, sa, data + 1, len - 1, rx_freq); 16858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 16868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case P2P_DEV_DISC_RESP: 16878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_process_dev_disc_resp(p2p, sa, data + 1, len - 1); 16888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 16898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt default: 1690b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt p2p_dbg(p2p, "Unsupported P2P Public Action frame type %d", 16918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt data[0]); 16928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 16938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 16948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 16958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 16968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 16971f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidtstatic void p2p_rx_action_public(struct p2p_data *p2p, const u8 *da, 16981f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt const u8 *sa, const u8 *bssid, const u8 *data, 16991f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt size_t len, int freq) 17008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 17018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (len < 1) 17028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; 17038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 17048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt switch (data[0]) { 17058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case WLAN_PA_VENDOR_SPECIFIC: 17068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt data++; 17078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt len--; 17088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (len < 3) 17098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; 17108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (WPA_GET_BE24(data) != OUI_WFA) 17118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; 17128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 17138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt data += 3; 17148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt len -= 3; 17158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (len < 1) 17168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; 17178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 17188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (*data != P2P_OUI_TYPE) 17198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; 17208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 17218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_rx_p2p_action(p2p, sa, data + 1, len - 1, freq); 17228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 17238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case WLAN_PA_GAS_INITIAL_REQ: 17248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_rx_gas_initial_req(p2p, sa, data + 1, len - 1, freq); 17258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 17268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case WLAN_PA_GAS_INITIAL_RESP: 17278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_rx_gas_initial_resp(p2p, sa, data + 1, len - 1, freq); 17288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 17298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case WLAN_PA_GAS_COMEBACK_REQ: 17308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_rx_gas_comeback_req(p2p, sa, data + 1, len - 1, freq); 17318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 17328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case WLAN_PA_GAS_COMEBACK_RESP: 17338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_rx_gas_comeback_resp(p2p, sa, data + 1, len - 1, freq); 17348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 17358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 17368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 17378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 17388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 17398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtvoid p2p_rx_action(struct p2p_data *p2p, const u8 *da, const u8 *sa, 17408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt const u8 *bssid, u8 category, 17418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt const u8 *data, size_t len, int freq) 17428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 17438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (category == WLAN_ACTION_PUBLIC) { 17448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_rx_action_public(p2p, da, sa, bssid, data, len, freq); 17458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; 17468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 17478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 17488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (category != WLAN_ACTION_VENDOR_SPECIFIC) 17498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; 17508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 17518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (len < 4) 17528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; 17538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 17548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (WPA_GET_BE24(data) != OUI_WFA) 17558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; 17568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt data += 3; 17578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt len -= 3; 17588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 17598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (*data != P2P_OUI_TYPE) 17608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; 17618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt data++; 17628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt len--; 17638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 17648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* P2P action frame */ 1765b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt p2p_dbg(p2p, "RX P2P Action from " MACSTR, MAC2STR(sa)); 17668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_hexdump(MSG_MSGDUMP, "P2P: P2P Action contents", data, len); 17678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 17688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (len < 1) 17698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; 17708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt switch (data[0]) { 17718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case P2P_NOA: 1772b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt p2p_dbg(p2p, "Received P2P Action - Notice of Absence"); 17738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* TODO */ 17748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 17758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case P2P_PRESENCE_REQ: 17768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_process_presence_req(p2p, da, sa, data + 1, len - 1, freq); 17778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 17788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case P2P_PRESENCE_RESP: 17798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_process_presence_resp(p2p, da, sa, data + 1, len - 1); 17808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 17818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case P2P_GO_DISC_REQ: 17828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_process_go_disc_req(p2p, da, sa, data + 1, len - 1, freq); 17838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 17848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt default: 1785b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt p2p_dbg(p2p, "Received P2P Action - unknown type %u", data[0]); 17868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 17878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 17888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 17898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 17908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 17918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic void p2p_go_neg_start(void *eloop_ctx, void *timeout_ctx) 17928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 17938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct p2p_data *p2p = eloop_ctx; 17948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (p2p->go_neg_peer == NULL) 17958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; 17968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p->cfg->stop_listen(p2p->cfg->cb_ctx); 17978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p->go_neg_peer->status = P2P_SC_SUCCESS; 17988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_connect_send(p2p, p2p->go_neg_peer); 17998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 18008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 18018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 18028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic void p2p_invite_start(void *eloop_ctx, void *timeout_ctx) 18038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 18048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct p2p_data *p2p = eloop_ctx; 18058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (p2p->invite_peer == NULL) 18068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; 18078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p->cfg->stop_listen(p2p->cfg->cb_ctx); 18088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_invite_send(p2p, p2p->invite_peer, p2p->invite_go_dev_addr); 18098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 18108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 18118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 18128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic void p2p_add_dev_from_probe_req(struct p2p_data *p2p, const u8 *addr, 18138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt const u8 *ie, size_t ie_len) 18148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 18158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct p2p_message msg; 18168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct p2p_device *dev; 18178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 18188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memset(&msg, 0, sizeof(msg)); 18198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (p2p_parse_ies(ie, ie_len, &msg) < 0 || msg.p2p_attributes == NULL) 18208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt { 18218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_parse_free(&msg); 18228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; /* not a P2P probe */ 18238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 18248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 18258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (msg.ssid == NULL || msg.ssid[1] != P2P_WILDCARD_SSID_LEN || 18268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memcmp(msg.ssid + 2, P2P_WILDCARD_SSID, P2P_WILDCARD_SSID_LEN) 18278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt != 0) { 18288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* The Probe Request is not part of P2P Device Discovery. It is 18298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * not known whether the source address of the frame is the P2P 18308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * Device Address or P2P Interface Address. Do not add a new 18318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * peer entry based on this frames. 18328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */ 18338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_parse_free(&msg); 18348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; 18358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 18368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 18378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt dev = p2p_get_device(p2p, addr); 18388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (dev) { 18398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (dev->country[0] == 0 && msg.listen_channel) 18408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memcpy(dev->country, msg.listen_channel, 3); 18411f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt os_get_time(&dev->last_seen); 18428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_parse_free(&msg); 18438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; /* already known */ 18448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 18458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 18468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt dev = p2p_create_device(p2p, addr); 18478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (dev == NULL) { 18488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_parse_free(&msg); 18498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; 18508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 18518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 18528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_get_time(&dev->last_seen); 18538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt dev->flags |= P2P_DEV_PROBE_REQ_ONLY; 18548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 18558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (msg.listen_channel) { 18568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memcpy(dev->country, msg.listen_channel, 3); 18574b06059785b935dd1f4f09314e4e12c417d2c6a4Dmitry Shmidt dev->listen_freq = p2p_channel_to_freq(msg.listen_channel[3], 18588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt msg.listen_channel[4]); 18598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 18608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1861b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt p2p_copy_wps_info(p2p, dev, 1, &msg); 18628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 186361d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt if (msg.wfd_subelems) { 186461d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt wpabuf_free(dev->info.wfd_subelems); 186561d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt dev->info.wfd_subelems = wpabuf_dup(msg.wfd_subelems); 186661d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt } 186761d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt 18688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_parse_free(&msg); 18698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1870b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt p2p_dbg(p2p, "Created device entry based on Probe Req: " MACSTR 18718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt " dev_capab=0x%x group_capab=0x%x name='%s' listen_freq=%d", 18728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt MAC2STR(dev->info.p2p_device_addr), dev->info.dev_capab, 18738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt dev->info.group_capab, dev->info.device_name, 18748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt dev->listen_freq); 18758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 18768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 18778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 18788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstruct p2p_device * p2p_add_dev_from_go_neg_req(struct p2p_data *p2p, 18798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt const u8 *addr, 18808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct p2p_message *msg) 18818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 18828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct p2p_device *dev; 18838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 18848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt dev = p2p_get_device(p2p, addr); 18858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (dev) { 18868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_get_time(&dev->last_seen); 18878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return dev; /* already known */ 18888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 18898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 18908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt dev = p2p_create_device(p2p, addr); 18918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (dev == NULL) 18928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return NULL; 18938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 18948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_add_dev_info(p2p, addr, dev, msg); 18958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 18968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return dev; 18978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 18988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 18998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 19008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic int dev_type_match(const u8 *dev_type, const u8 *req_dev_type) 19018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 19028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (os_memcmp(dev_type, req_dev_type, WPS_DEV_TYPE_LEN) == 0) 19038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 1; 19048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (os_memcmp(dev_type, req_dev_type, 2) == 0 && 19058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt WPA_GET_BE32(&req_dev_type[2]) == 0 && 19068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt WPA_GET_BE16(&req_dev_type[6]) == 0) 19078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 1; /* Category match with wildcard OUI/sub-category */ 19088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 19098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 19108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 19118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 19128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtint dev_type_list_match(const u8 *dev_type, const u8 *req_dev_type[], 19138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt size_t num_req_dev_type) 19148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 19158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt size_t i; 19168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt for (i = 0; i < num_req_dev_type; i++) { 19178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (dev_type_match(dev_type, req_dev_type[i])) 19188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 1; 19198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 19208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 19218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 19228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 19238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 19248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt/** 19258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * p2p_match_dev_type - Match local device type with requested type 19268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @p2p: P2P module context from p2p_init() 19278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @wps: WPS TLVs from Probe Request frame (concatenated WPS IEs) 19288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * Returns: 1 on match, 0 on mismatch 19298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * 19308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * This function can be used to match the Requested Device Type attribute in 19318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * WPS IE with the local device types for deciding whether to reply to a Probe 19328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * Request frame. 19338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */ 19348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtint p2p_match_dev_type(struct p2p_data *p2p, struct wpabuf *wps) 19358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 19368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct wps_parse_attr attr; 19378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt size_t i; 19388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 19398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (wps_parse_msg(wps, &attr)) 19408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 1; /* assume no Requested Device Type attributes */ 19418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 19428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (attr.num_req_dev_type == 0) 19438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 1; /* no Requested Device Type attributes -> match */ 19448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 19458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (dev_type_list_match(p2p->cfg->pri_dev_type, attr.req_dev_type, 19468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt attr.num_req_dev_type)) 19478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 1; /* Own Primary Device Type matches */ 19488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 19498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt for (i = 0; i < p2p->cfg->num_sec_dev_types; i++) 19508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (dev_type_list_match(p2p->cfg->sec_dev_type[i], 19518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt attr.req_dev_type, 19528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt attr.num_req_dev_type)) 19538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 1; /* Own Secondary Device Type matches */ 19548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 19558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* No matching device type found */ 19568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 19578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 19588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 19598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 19608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstruct wpabuf * p2p_build_probe_resp_ies(struct p2p_data *p2p) 19618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 19628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct wpabuf *buf; 19638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt u8 *len; 196404949598a23f501be6eec21697465fd46a28840aDmitry Shmidt int pw_id = -1; 196561d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt size_t extra = 0; 196661d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt 196761d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt#ifdef CONFIG_WIFI_DISPLAY 196861d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt if (p2p->wfd_ie_probe_resp) 196961d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt extra = wpabuf_len(p2p->wfd_ie_probe_resp); 197061d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt#endif /* CONFIG_WIFI_DISPLAY */ 19718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 197261d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt buf = wpabuf_alloc(1000 + extra); 19738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (buf == NULL) 19748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return NULL; 19758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 197604949598a23f501be6eec21697465fd46a28840aDmitry Shmidt if (p2p->go_neg_peer) { 197704949598a23f501be6eec21697465fd46a28840aDmitry Shmidt /* Advertise immediate availability of WPS credential */ 197804949598a23f501be6eec21697465fd46a28840aDmitry Shmidt pw_id = p2p_wps_method_pw_id(p2p->go_neg_peer->wps_method); 197904949598a23f501be6eec21697465fd46a28840aDmitry Shmidt } 198004949598a23f501be6eec21697465fd46a28840aDmitry Shmidt 198104949598a23f501be6eec21697465fd46a28840aDmitry Shmidt p2p_build_wps_ie(p2p, buf, pw_id, 1); 19828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 198361d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt#ifdef CONFIG_WIFI_DISPLAY 198461d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt if (p2p->wfd_ie_probe_resp) 198561d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt wpabuf_put_buf(buf, p2p->wfd_ie_probe_resp); 198661d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt#endif /* CONFIG_WIFI_DISPLAY */ 198761d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt 19888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* P2P IE */ 19898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt len = p2p_buf_add_ie_hdr(buf); 199004949598a23f501be6eec21697465fd46a28840aDmitry Shmidt p2p_buf_add_capability(buf, p2p->dev_capab & 199104949598a23f501be6eec21697465fd46a28840aDmitry Shmidt ~P2P_DEV_CAPAB_CLIENT_DISCOVERABILITY, 0); 19928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (p2p->ext_listen_interval) 19938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_buf_add_ext_listen_timing(buf, p2p->ext_listen_period, 19948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p->ext_listen_interval); 19958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_buf_add_device_info(buf, p2p, NULL); 19968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_buf_update_ie_hdr(buf, len); 19978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 19988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return buf; 19998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 20008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 20018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 200204949598a23f501be6eec21697465fd46a28840aDmitry Shmidtstatic enum p2p_probe_req_status 200304949598a23f501be6eec21697465fd46a28840aDmitry Shmidtp2p_reply_probe(struct p2p_data *p2p, const u8 *addr, const u8 *dst, 200404949598a23f501be6eec21697465fd46a28840aDmitry Shmidt const u8 *bssid, const u8 *ie, size_t ie_len) 20058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 20068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct ieee802_11_elems elems; 20078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct wpabuf *buf; 20088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct ieee80211_mgmt *resp; 20091f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt struct p2p_message msg; 20108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct wpabuf *ies; 20118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 20128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (!p2p->in_listen || !p2p->drv_in_listen) { 20138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* not in Listen state - ignore Probe Request */ 201404949598a23f501be6eec21697465fd46a28840aDmitry Shmidt return P2P_PREQ_NOT_LISTEN; 20158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 20168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 20178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (ieee802_11_parse_elems((u8 *) ie, ie_len, &elems, 0) == 20188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ParseFailed) { 20198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* Ignore invalid Probe Request frames */ 202004949598a23f501be6eec21697465fd46a28840aDmitry Shmidt return P2P_PREQ_MALFORMED; 20218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 20228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 20238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (elems.p2p == NULL) { 20248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* not a P2P probe - ignore it */ 202504949598a23f501be6eec21697465fd46a28840aDmitry Shmidt return P2P_PREQ_NOT_P2P; 20268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 20278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 20281f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt if (dst && !is_broadcast_ether_addr(dst) && 20291f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt os_memcmp(dst, p2p->cfg->dev_addr, ETH_ALEN) != 0) { 20301f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt /* Not sent to the broadcast address or our P2P Device Address 20311f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt */ 203204949598a23f501be6eec21697465fd46a28840aDmitry Shmidt return P2P_PREQ_NOT_PROCESSED; 20331f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt } 20341f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt 20351f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt if (bssid && !is_broadcast_ether_addr(bssid)) { 20361f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt /* Not sent to the Wildcard BSSID */ 203704949598a23f501be6eec21697465fd46a28840aDmitry Shmidt return P2P_PREQ_NOT_PROCESSED; 20381f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt } 20391f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt 20408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (elems.ssid == NULL || elems.ssid_len != P2P_WILDCARD_SSID_LEN || 20418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memcmp(elems.ssid, P2P_WILDCARD_SSID, P2P_WILDCARD_SSID_LEN) != 20428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 0) { 20438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* not using P2P Wildcard SSID - ignore */ 204404949598a23f501be6eec21697465fd46a28840aDmitry Shmidt return P2P_PREQ_NOT_PROCESSED; 20458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 20468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 20471f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt if (supp_rates_11b_only(&elems)) { 20481f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt /* Indicates support for 11b rates only */ 204904949598a23f501be6eec21697465fd46a28840aDmitry Shmidt return P2P_PREQ_NOT_P2P; 20501f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt } 20511f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt 20521f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt os_memset(&msg, 0, sizeof(msg)); 20531f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt if (p2p_parse_ies(ie, ie_len, &msg) < 0) { 20541f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt /* Could not parse P2P attributes */ 205504949598a23f501be6eec21697465fd46a28840aDmitry Shmidt return P2P_PREQ_NOT_P2P; 20561f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt } 20571f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt 20581f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt if (msg.device_id && 205904949598a23f501be6eec21697465fd46a28840aDmitry Shmidt os_memcmp(msg.device_id, p2p->cfg->dev_addr, ETH_ALEN) != 0) { 20601f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt /* Device ID did not match */ 20611f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt p2p_parse_free(&msg); 206204949598a23f501be6eec21697465fd46a28840aDmitry Shmidt return P2P_PREQ_NOT_PROCESSED; 20631f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt } 20641f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt 20658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* Check Requested Device Type match */ 20661f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt if (msg.wps_attributes && 20671f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt !p2p_match_dev_type(p2p, msg.wps_attributes)) { 20688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* No match with Requested Device Type */ 20691f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt p2p_parse_free(&msg); 207004949598a23f501be6eec21697465fd46a28840aDmitry Shmidt return P2P_PREQ_NOT_PROCESSED; 20718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 20721f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt p2p_parse_free(&msg); 20738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 207404949598a23f501be6eec21697465fd46a28840aDmitry Shmidt if (!p2p->cfg->send_probe_resp) { 207504949598a23f501be6eec21697465fd46a28840aDmitry Shmidt /* Response generated elsewhere */ 207604949598a23f501be6eec21697465fd46a28840aDmitry Shmidt return P2P_PREQ_NOT_PROCESSED; 207704949598a23f501be6eec21697465fd46a28840aDmitry Shmidt } 20788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2079b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt p2p_dbg(p2p, "Reply to P2P Probe Request in Listen state"); 20808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 20818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* 20828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * We do not really have a specific BSS that this frame is advertising, 20838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * so build a frame that has some information in valid format. This is 20848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * really only used for discovery purposes, not to learn exact BSS 20858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * parameters. 20868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */ 20878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ies = p2p_build_probe_resp_ies(p2p); 20888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (ies == NULL) 208904949598a23f501be6eec21697465fd46a28840aDmitry Shmidt return P2P_PREQ_NOT_PROCESSED; 20908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 20918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt buf = wpabuf_alloc(200 + wpabuf_len(ies)); 20928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (buf == NULL) { 20938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpabuf_free(ies); 209404949598a23f501be6eec21697465fd46a28840aDmitry Shmidt return P2P_PREQ_NOT_PROCESSED; 20958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 20968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 20978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt resp = NULL; 20988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt resp = wpabuf_put(buf, resp->u.probe_resp.variable - (u8 *) resp); 20998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 21008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt resp->frame_control = host_to_le16((WLAN_FC_TYPE_MGMT << 2) | 21018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt (WLAN_FC_STYPE_PROBE_RESP << 4)); 21028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memcpy(resp->da, addr, ETH_ALEN); 21038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memcpy(resp->sa, p2p->cfg->dev_addr, ETH_ALEN); 21048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memcpy(resp->bssid, p2p->cfg->dev_addr, ETH_ALEN); 21058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt resp->u.probe_resp.beacon_int = host_to_le16(100); 21068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* hardware or low-level driver will setup seq_ctrl and timestamp */ 21078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt resp->u.probe_resp.capab_info = 21088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt host_to_le16(WLAN_CAPABILITY_SHORT_PREAMBLE | 21098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt WLAN_CAPABILITY_PRIVACY | 21108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt WLAN_CAPABILITY_SHORT_SLOT_TIME); 21118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 21128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpabuf_put_u8(buf, WLAN_EID_SSID); 21138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpabuf_put_u8(buf, P2P_WILDCARD_SSID_LEN); 21148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpabuf_put_data(buf, P2P_WILDCARD_SSID, P2P_WILDCARD_SSID_LEN); 21158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 21168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpabuf_put_u8(buf, WLAN_EID_SUPP_RATES); 21178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpabuf_put_u8(buf, 8); 21188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpabuf_put_u8(buf, (60 / 5) | 0x80); 21198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpabuf_put_u8(buf, 90 / 5); 21208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpabuf_put_u8(buf, (120 / 5) | 0x80); 21218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpabuf_put_u8(buf, 180 / 5); 21228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpabuf_put_u8(buf, (240 / 5) | 0x80); 21238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpabuf_put_u8(buf, 360 / 5); 21248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpabuf_put_u8(buf, 480 / 5); 21258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpabuf_put_u8(buf, 540 / 5); 21268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 21278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpabuf_put_u8(buf, WLAN_EID_DS_PARAMS); 21288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpabuf_put_u8(buf, 1); 21298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpabuf_put_u8(buf, p2p->cfg->channel); 21308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 21318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpabuf_put_buf(buf, ies); 21328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpabuf_free(ies); 21338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 21348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p->cfg->send_probe_resp(p2p->cfg->cb_ctx, buf); 21358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 21368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpabuf_free(buf); 213704949598a23f501be6eec21697465fd46a28840aDmitry Shmidt 213804949598a23f501be6eec21697465fd46a28840aDmitry Shmidt return P2P_PREQ_NOT_PROCESSED; 21398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 21408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 21418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 214204949598a23f501be6eec21697465fd46a28840aDmitry Shmidtenum p2p_probe_req_status 214304949598a23f501be6eec21697465fd46a28840aDmitry Shmidtp2p_probe_req_rx(struct p2p_data *p2p, const u8 *addr, const u8 *dst, 214404949598a23f501be6eec21697465fd46a28840aDmitry Shmidt const u8 *bssid, const u8 *ie, size_t ie_len) 21458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 214604949598a23f501be6eec21697465fd46a28840aDmitry Shmidt enum p2p_probe_req_status res; 214704949598a23f501be6eec21697465fd46a28840aDmitry Shmidt 21488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_add_dev_from_probe_req(p2p, addr, ie, ie_len); 21498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 215004949598a23f501be6eec21697465fd46a28840aDmitry Shmidt res = p2p_reply_probe(p2p, addr, dst, bssid, ie, ie_len); 21518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 21528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if ((p2p->state == P2P_CONNECT || p2p->state == P2P_CONNECT_LISTEN) && 21538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p->go_neg_peer && 21548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memcmp(addr, p2p->go_neg_peer->info.p2p_device_addr, ETH_ALEN) 21559cdf1b905fae57dea42506a1af67f6ece544b261Dmitry Shmidt == 0 && 21569cdf1b905fae57dea42506a1af67f6ece544b261Dmitry Shmidt !(p2p->go_neg_peer->flags & P2P_DEV_WAIT_GO_NEG_CONFIRM)) { 21578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* Received a Probe Request from GO Negotiation peer */ 2158b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt p2p_dbg(p2p, "Found GO Negotiation peer - try to start GO negotiation from timeout"); 21599cdf1b905fae57dea42506a1af67f6ece544b261Dmitry Shmidt eloop_cancel_timeout(p2p_go_neg_start, p2p, NULL); 21608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt eloop_register_timeout(0, 0, p2p_go_neg_start, p2p, NULL); 216104949598a23f501be6eec21697465fd46a28840aDmitry Shmidt return P2P_PREQ_PROCESSED; 21628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 21638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 21648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if ((p2p->state == P2P_INVITE || p2p->state == P2P_INVITE_LISTEN) && 21658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p->invite_peer && 21668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memcmp(addr, p2p->invite_peer->info.p2p_device_addr, ETH_ALEN) 21678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt == 0) { 21688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* Received a Probe Request from Invite peer */ 2169b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt p2p_dbg(p2p, "Found Invite peer - try to start Invite from timeout"); 21708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt eloop_register_timeout(0, 0, p2p_invite_start, p2p, NULL); 217104949598a23f501be6eec21697465fd46a28840aDmitry Shmidt return P2P_PREQ_PROCESSED; 21728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 21738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 217404949598a23f501be6eec21697465fd46a28840aDmitry Shmidt return res; 21758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 21768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 21778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 21788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic int p2p_assoc_req_ie_wlan_ap(struct p2p_data *p2p, const u8 *bssid, 21798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt u8 *buf, size_t len, struct wpabuf *p2p_ie) 21808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 21818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct wpabuf *tmp; 21828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt u8 *lpos; 21838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt size_t tmplen; 21848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt int res; 21858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt u8 group_capab; 21868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 21878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (p2p_ie == NULL) 21888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; /* WLAN AP is not a P2P manager */ 21898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 21908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* 21918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * (Re)Association Request - P2P IE 21928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * P2P Capability attribute (shall be present) 21938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * P2P Interface attribute (present if concurrent device and 21948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * P2P Management is enabled) 21958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */ 21968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt tmp = wpabuf_alloc(200); 21978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (tmp == NULL) 21988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 21998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 22008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt lpos = p2p_buf_add_ie_hdr(tmp); 22018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt group_capab = 0; 22028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (p2p->num_groups > 0) { 22038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt group_capab |= P2P_GROUP_CAPAB_GROUP_OWNER; 22048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if ((p2p->dev_capab & P2P_DEV_CAPAB_CONCURRENT_OPER) && 22058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt (p2p->dev_capab & P2P_DEV_CAPAB_INFRA_MANAGED) && 22068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p->cross_connect) 22078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt group_capab |= P2P_GROUP_CAPAB_CROSS_CONN; 22088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 22098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_buf_add_capability(tmp, p2p->dev_capab, group_capab); 22108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if ((p2p->dev_capab & P2P_DEV_CAPAB_CONCURRENT_OPER) && 22118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt (p2p->dev_capab & P2P_DEV_CAPAB_INFRA_MANAGED)) 22128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_buf_add_p2p_interface(tmp, p2p); 22138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_buf_update_ie_hdr(tmp, lpos); 22148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 22158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt tmplen = wpabuf_len(tmp); 22168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (tmplen > len) 22178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt res = -1; 22188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt else { 22198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memcpy(buf, wpabuf_head(tmp), tmplen); 22208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt res = tmplen; 22218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 22228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpabuf_free(tmp); 22238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 22248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return res; 22258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 22268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 22278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 22288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtint p2p_assoc_req_ie(struct p2p_data *p2p, const u8 *bssid, u8 *buf, 22298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt size_t len, int p2p_group, struct wpabuf *p2p_ie) 22308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 22318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct wpabuf *tmp; 22328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt u8 *lpos; 22338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct p2p_device *peer; 22348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt size_t tmplen; 22358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt int res; 223661d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt size_t extra = 0; 22378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 22388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (!p2p_group) 22398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return p2p_assoc_req_ie_wlan_ap(p2p, bssid, buf, len, p2p_ie); 22408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 224161d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt#ifdef CONFIG_WIFI_DISPLAY 224261d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt if (p2p->wfd_ie_assoc_req) 224361d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt extra = wpabuf_len(p2p->wfd_ie_assoc_req); 224461d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt#endif /* CONFIG_WIFI_DISPLAY */ 224561d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt 22468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* 22478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * (Re)Association Request - P2P IE 22488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * P2P Capability attribute (shall be present) 22498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * Extended Listen Timing (may be present) 22508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * P2P Device Info attribute (shall be present) 22518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */ 225261d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt tmp = wpabuf_alloc(200 + extra); 22538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (tmp == NULL) 22548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 22558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 225661d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt#ifdef CONFIG_WIFI_DISPLAY 225761d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt if (p2p->wfd_ie_assoc_req) 225861d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt wpabuf_put_buf(tmp, p2p->wfd_ie_assoc_req); 225961d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt#endif /* CONFIG_WIFI_DISPLAY */ 226061d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt 22618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt peer = bssid ? p2p_get_device(p2p, bssid) : NULL; 22628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 22638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt lpos = p2p_buf_add_ie_hdr(tmp); 22648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_buf_add_capability(tmp, p2p->dev_capab, 0); 22658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (p2p->ext_listen_interval) 22668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_buf_add_ext_listen_timing(tmp, p2p->ext_listen_period, 22678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p->ext_listen_interval); 22688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_buf_add_device_info(tmp, p2p, peer); 22698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_buf_update_ie_hdr(tmp, lpos); 22708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 22718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt tmplen = wpabuf_len(tmp); 22728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (tmplen > len) 22738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt res = -1; 22748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt else { 22758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memcpy(buf, wpabuf_head(tmp), tmplen); 22768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt res = tmplen; 22778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 22788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpabuf_free(tmp); 22798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 22808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return res; 22818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 22828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 22838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 22848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtint p2p_scan_result_text(const u8 *ies, size_t ies_len, char *buf, char *end) 22858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 22868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct wpabuf *p2p_ie; 22878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt int ret; 22888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 22898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_ie = ieee802_11_vendor_ie_concat(ies, ies_len, P2P_IE_VENDOR_TYPE); 22908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (p2p_ie == NULL) 22918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 22928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 22938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ret = p2p_attr_text(p2p_ie, buf, end); 22948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpabuf_free(p2p_ie); 22958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return ret; 22968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 22978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 22988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 229904949598a23f501be6eec21697465fd46a28840aDmitry Shmidtint p2p_parse_dev_addr_in_p2p_ie(struct wpabuf *p2p_ie, u8 *dev_addr) 2300c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt{ 2301c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt struct p2p_message msg; 2302c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt 2303c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt os_memset(&msg, 0, sizeof(msg)); 230404949598a23f501be6eec21697465fd46a28840aDmitry Shmidt if (p2p_parse_p2p_ie(p2p_ie, &msg)) 2305c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt return -1; 2306c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt 230704949598a23f501be6eec21697465fd46a28840aDmitry Shmidt if (msg.p2p_device_addr) { 230804949598a23f501be6eec21697465fd46a28840aDmitry Shmidt os_memcpy(dev_addr, msg.p2p_device_addr, ETH_ALEN); 230904949598a23f501be6eec21697465fd46a28840aDmitry Shmidt return 0; 231004949598a23f501be6eec21697465fd46a28840aDmitry Shmidt } else if (msg.device_id) { 231104949598a23f501be6eec21697465fd46a28840aDmitry Shmidt os_memcpy(dev_addr, msg.device_id, ETH_ALEN); 231204949598a23f501be6eec21697465fd46a28840aDmitry Shmidt return 0; 2313c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt } 231404949598a23f501be6eec21697465fd46a28840aDmitry Shmidt return -1; 231504949598a23f501be6eec21697465fd46a28840aDmitry Shmidt} 2316c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt 231704949598a23f501be6eec21697465fd46a28840aDmitry Shmidt 231804949598a23f501be6eec21697465fd46a28840aDmitry Shmidtint p2p_parse_dev_addr(const u8 *ies, size_t ies_len, u8 *dev_addr) 231904949598a23f501be6eec21697465fd46a28840aDmitry Shmidt{ 232004949598a23f501be6eec21697465fd46a28840aDmitry Shmidt struct wpabuf *p2p_ie; 232104949598a23f501be6eec21697465fd46a28840aDmitry Shmidt int ret; 232204949598a23f501be6eec21697465fd46a28840aDmitry Shmidt 232304949598a23f501be6eec21697465fd46a28840aDmitry Shmidt p2p_ie = ieee802_11_vendor_ie_concat(ies, ies_len, 232404949598a23f501be6eec21697465fd46a28840aDmitry Shmidt P2P_IE_VENDOR_TYPE); 232504949598a23f501be6eec21697465fd46a28840aDmitry Shmidt if (p2p_ie == NULL) 232604949598a23f501be6eec21697465fd46a28840aDmitry Shmidt return -1; 232704949598a23f501be6eec21697465fd46a28840aDmitry Shmidt ret = p2p_parse_dev_addr_in_p2p_ie(p2p_ie, dev_addr); 2328c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt wpabuf_free(p2p_ie); 232904949598a23f501be6eec21697465fd46a28840aDmitry Shmidt return ret; 2330c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt} 2331c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt 2332c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt 23338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic void p2p_clear_go_neg(struct p2p_data *p2p) 23348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 23358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p->go_neg_peer = NULL; 23368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_clear_timeout(p2p); 23378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_set_state(p2p, P2P_IDLE); 23388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 23398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 23408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 23418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtvoid p2p_wps_success_cb(struct p2p_data *p2p, const u8 *mac_addr) 23428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 23438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (p2p->go_neg_peer == NULL) { 2344b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt p2p_dbg(p2p, "No pending Group Formation - ignore WPS registration success notification"); 23458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; /* No pending Group Formation */ 23468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 23478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 23488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (os_memcmp(mac_addr, p2p->go_neg_peer->intended_addr, ETH_ALEN) != 23498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 0) { 2350b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt p2p_dbg(p2p, "Ignore WPS registration success notification for " 2351b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt MACSTR " (GO Negotiation peer " MACSTR ")", 23528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt MAC2STR(mac_addr), 23538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt MAC2STR(p2p->go_neg_peer->intended_addr)); 23548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; /* Ignore unexpected peer address */ 23558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 23568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2357b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt p2p_dbg(p2p, "Group Formation completed successfully with " MACSTR, 23588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt MAC2STR(mac_addr)); 23598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 23608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_clear_go_neg(p2p); 23618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 23628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 23638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 23648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtvoid p2p_group_formation_failed(struct p2p_data *p2p) 23658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 23668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (p2p->go_neg_peer == NULL) { 2367b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt p2p_dbg(p2p, "No pending Group Formation - ignore group formation failure notification"); 23688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; /* No pending Group Formation */ 23698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 23708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2371b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt p2p_dbg(p2p, "Group Formation failed with " MACSTR, 23728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt MAC2STR(p2p->go_neg_peer->intended_addr)); 23738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 23748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_clear_go_neg(p2p); 23758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 23768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 23778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 23788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstruct p2p_data * p2p_init(const struct p2p_config *cfg) 23798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 23808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct p2p_data *p2p; 23818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 23828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (cfg->max_peers < 1) 23838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return NULL; 23848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 23858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p = os_zalloc(sizeof(*p2p) + sizeof(*cfg)); 23868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (p2p == NULL) 23878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return NULL; 23888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p->cfg = (struct p2p_config *) (p2p + 1); 23898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memcpy(p2p->cfg, cfg, sizeof(*cfg)); 23908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (cfg->dev_name) 23918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p->cfg->dev_name = os_strdup(cfg->dev_name); 23928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (cfg->manufacturer) 23938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p->cfg->manufacturer = os_strdup(cfg->manufacturer); 23948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (cfg->model_name) 23958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p->cfg->model_name = os_strdup(cfg->model_name); 23968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (cfg->model_number) 23978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p->cfg->model_number = os_strdup(cfg->model_number); 23988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (cfg->serial_number) 23998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p->cfg->serial_number = os_strdup(cfg->serial_number); 240004949598a23f501be6eec21697465fd46a28840aDmitry Shmidt if (cfg->pref_chan) { 240104949598a23f501be6eec21697465fd46a28840aDmitry Shmidt p2p->cfg->pref_chan = os_malloc(cfg->num_pref_chan * 240204949598a23f501be6eec21697465fd46a28840aDmitry Shmidt sizeof(struct p2p_channel)); 240304949598a23f501be6eec21697465fd46a28840aDmitry Shmidt if (p2p->cfg->pref_chan) { 240404949598a23f501be6eec21697465fd46a28840aDmitry Shmidt os_memcpy(p2p->cfg->pref_chan, cfg->pref_chan, 240504949598a23f501be6eec21697465fd46a28840aDmitry Shmidt cfg->num_pref_chan * 240604949598a23f501be6eec21697465fd46a28840aDmitry Shmidt sizeof(struct p2p_channel)); 240704949598a23f501be6eec21697465fd46a28840aDmitry Shmidt } else 240804949598a23f501be6eec21697465fd46a28840aDmitry Shmidt p2p->cfg->num_pref_chan = 0; 240904949598a23f501be6eec21697465fd46a28840aDmitry Shmidt } 241004949598a23f501be6eec21697465fd46a28840aDmitry Shmidt 2411f44b9c4a18d17fbd39901f76a014c32006570fb8Irfan Sheriff#ifdef ANDROID_P2P 2412f44b9c4a18d17fbd39901f76a014c32006570fb8Irfan Sheriff /* 100ms listen time is too less to receive the response frames in some scenarios 2413f44b9c4a18d17fbd39901f76a014c32006570fb8Irfan Sheriff * increasing min listen time to 200ms. 2414f44b9c4a18d17fbd39901f76a014c32006570fb8Irfan Sheriff */ 2415f44b9c4a18d17fbd39901f76a014c32006570fb8Irfan Sheriff p2p->min_disc_int = 2; 2416f44b9c4a18d17fbd39901f76a014c32006570fb8Irfan Sheriff /* SD_FAIR_POLICY: Initializing the SD current serviced pointer to NULL */ 2417f44b9c4a18d17fbd39901f76a014c32006570fb8Irfan Sheriff p2p->sd_dev_list = NULL; 2418f44b9c4a18d17fbd39901f76a014c32006570fb8Irfan Sheriff#else 24198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p->min_disc_int = 1; 2420f44b9c4a18d17fbd39901f76a014c32006570fb8Irfan Sheriff#endif 24218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p->max_disc_int = 3; 2422d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt p2p->max_disc_tu = -1; 24238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 24248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_get_random(&p2p->next_tie_breaker, 1); 24258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p->next_tie_breaker &= 0x01; 24268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (cfg->sd_request) 24278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p->dev_capab |= P2P_DEV_CAPAB_SERVICE_DISCOVERY; 24288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p->dev_capab |= P2P_DEV_CAPAB_INVITATION_PROCEDURE; 24298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (cfg->concurrent_operations) 24308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p->dev_capab |= P2P_DEV_CAPAB_CONCURRENT_OPER; 24318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p->dev_capab |= P2P_DEV_CAPAB_CLIENT_DISCOVERABILITY; 24328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 24338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt dl_list_init(&p2p->devices); 24348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 24358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt eloop_register_timeout(P2P_PEER_EXPIRATION_INTERVAL, 0, 24368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_expiration_timeout, p2p, NULL); 24378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 243861d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt p2p->go_timeout = 100; 243961d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt p2p->client_timeout = 20; 244061d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt 24418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return p2p; 24428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 24438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 24448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 24458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtvoid p2p_deinit(struct p2p_data *p2p) 24468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 244761d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt#ifdef CONFIG_WIFI_DISPLAY 244861d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt wpabuf_free(p2p->wfd_ie_beacon); 244961d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt wpabuf_free(p2p->wfd_ie_probe_req); 245061d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt wpabuf_free(p2p->wfd_ie_probe_resp); 245161d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt wpabuf_free(p2p->wfd_ie_assoc_req); 245261d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt wpabuf_free(p2p->wfd_ie_invitation); 245361d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt wpabuf_free(p2p->wfd_ie_prov_disc_req); 245461d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt wpabuf_free(p2p->wfd_ie_prov_disc_resp); 245561d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt wpabuf_free(p2p->wfd_ie_go_neg); 245661d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt wpabuf_free(p2p->wfd_dev_info); 245761d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt wpabuf_free(p2p->wfd_assoc_bssid); 245861d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt wpabuf_free(p2p->wfd_coupled_sink_info); 245961d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt#endif /* CONFIG_WIFI_DISPLAY */ 246061d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt 24618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt eloop_cancel_timeout(p2p_expiration_timeout, p2p, NULL); 24628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt eloop_cancel_timeout(p2p_ext_listen_timeout, p2p, NULL); 24638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt eloop_cancel_timeout(p2p_scan_timeout, p2p, NULL); 24649cdf1b905fae57dea42506a1af67f6ece544b261Dmitry Shmidt eloop_cancel_timeout(p2p_go_neg_start, p2p, NULL); 24658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_flush(p2p); 24668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_free_req_dev_types(p2p); 24678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_free(p2p->cfg->dev_name); 24688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_free(p2p->cfg->manufacturer); 24698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_free(p2p->cfg->model_name); 24708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_free(p2p->cfg->model_number); 24718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_free(p2p->cfg->serial_number); 247204949598a23f501be6eec21697465fd46a28840aDmitry Shmidt os_free(p2p->cfg->pref_chan); 24738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_free(p2p->groups); 24748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpabuf_free(p2p->sd_resp); 24758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_free(p2p->after_scan_tx); 24768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_remove_wps_vendor_extensions(p2p); 24778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_free(p2p); 24788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 24798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 24808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 24818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtvoid p2p_flush(struct p2p_data *p2p) 24828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 24838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct p2p_device *dev, *prev; 248404949598a23f501be6eec21697465fd46a28840aDmitry Shmidt p2p_stop_find(p2p); 24858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt dl_list_for_each_safe(dev, prev, &p2p->devices, struct p2p_device, 24868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt list) { 24878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt dl_list_del(&dev->list); 24888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_device_free(p2p, dev); 24898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 2490f44b9c4a18d17fbd39901f76a014c32006570fb8Irfan Sheriff#ifdef ANDROID_P2P 2491f44b9c4a18d17fbd39901f76a014c32006570fb8Irfan Sheriff /* SD_FAIR_POLICY: Initializing the SD current serviced pointer to NULL */ 2492f44b9c4a18d17fbd39901f76a014c32006570fb8Irfan Sheriff p2p->sd_dev_list = NULL; 2493f44b9c4a18d17fbd39901f76a014c32006570fb8Irfan Sheriff#endif 24948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_free_sd_queries(p2p); 24958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_free(p2p->after_scan_tx); 24968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p->after_scan_tx = NULL; 24978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 24988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 24998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 25008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtint p2p_unauthorize(struct p2p_data *p2p, const u8 *addr) 25018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 25028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct p2p_device *dev; 25038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 25048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt dev = p2p_get_device(p2p, addr); 25058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (dev == NULL) 25068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 25078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2508b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt p2p_dbg(p2p, "Unauthorizing " MACSTR, MAC2STR(addr)); 25098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 25108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (p2p->go_neg_peer == dev) 25118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p->go_neg_peer = NULL; 25128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 25138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt dev->wps_method = WPS_NOT_READY; 25148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt dev->flags &= ~P2P_DEV_WAIT_GO_NEG_RESPONSE; 25158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt dev->flags &= ~P2P_DEV_WAIT_GO_NEG_CONFIRM; 25168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 25178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* Check if after_scan_tx is for this peer. If so free it */ 25188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (p2p->after_scan_tx && 25198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memcmp(addr, p2p->after_scan_tx->dst, ETH_ALEN) == 0) { 25208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_free(p2p->after_scan_tx); 25218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p->after_scan_tx = NULL; 25228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 25238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 25248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 25258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 25268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 25278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 25288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtint p2p_set_dev_name(struct p2p_data *p2p, const char *dev_name) 25298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 25308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_free(p2p->cfg->dev_name); 25318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (dev_name) { 25328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p->cfg->dev_name = os_strdup(dev_name); 25338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (p2p->cfg->dev_name == NULL) 25348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 25358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } else 25368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p->cfg->dev_name = NULL; 25378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 25388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 25398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 25408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 25418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtint p2p_set_manufacturer(struct p2p_data *p2p, const char *manufacturer) 25428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 25438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_free(p2p->cfg->manufacturer); 25448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p->cfg->manufacturer = NULL; 25458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (manufacturer) { 25468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p->cfg->manufacturer = os_strdup(manufacturer); 25478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (p2p->cfg->manufacturer == NULL) 25488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 25498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 25508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 25518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 25528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 25538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 25548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 25558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtint p2p_set_model_name(struct p2p_data *p2p, const char *model_name) 25568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 25578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_free(p2p->cfg->model_name); 25588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p->cfg->model_name = NULL; 25598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (model_name) { 25608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p->cfg->model_name = os_strdup(model_name); 25618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (p2p->cfg->model_name == NULL) 25628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 25638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 25648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 25658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 25668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 25678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 25688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 25698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtint p2p_set_model_number(struct p2p_data *p2p, const char *model_number) 25708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 25718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_free(p2p->cfg->model_number); 25728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p->cfg->model_number = NULL; 25738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (model_number) { 25748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p->cfg->model_number = os_strdup(model_number); 25758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (p2p->cfg->model_number == NULL) 25768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 25778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 25788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 25798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 25808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 25818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 25828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 25838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtint p2p_set_serial_number(struct p2p_data *p2p, const char *serial_number) 25848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 25858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_free(p2p->cfg->serial_number); 25868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p->cfg->serial_number = NULL; 25878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (serial_number) { 25888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p->cfg->serial_number = os_strdup(serial_number); 25898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (p2p->cfg->serial_number == NULL) 25908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 25918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 25928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 25938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 25948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 25958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 25968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 25978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtvoid p2p_set_config_methods(struct p2p_data *p2p, u16 config_methods) 25988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 25998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p->cfg->config_methods = config_methods; 26008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 26018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 26028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 26038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtvoid p2p_set_uuid(struct p2p_data *p2p, const u8 *uuid) 26048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 26058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memcpy(p2p->cfg->uuid, uuid, 16); 26068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 26078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 26088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 26098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtint p2p_set_pri_dev_type(struct p2p_data *p2p, const u8 *pri_dev_type) 26108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 26118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memcpy(p2p->cfg->pri_dev_type, pri_dev_type, 8); 26128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 26138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 26148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 26158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 26168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtint p2p_set_sec_dev_types(struct p2p_data *p2p, const u8 dev_types[][8], 26178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt size_t num_dev_types) 26188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 26198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (num_dev_types > P2P_SEC_DEVICE_TYPES) 26208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt num_dev_types = P2P_SEC_DEVICE_TYPES; 26218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p->cfg->num_sec_dev_types = num_dev_types; 26228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memcpy(p2p->cfg->sec_dev_type, dev_types, num_dev_types * 8); 26238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 26248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 26258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 26268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 26278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtvoid p2p_remove_wps_vendor_extensions(struct p2p_data *p2p) 26288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 26298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt int i; 26308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 26318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt for (i = 0; i < P2P_MAX_WPS_VENDOR_EXT; i++) { 26328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpabuf_free(p2p->wps_vendor_ext[i]); 26338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p->wps_vendor_ext[i] = NULL; 26348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 26358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 26368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 26378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 26388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtint p2p_add_wps_vendor_extension(struct p2p_data *p2p, 26398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt const struct wpabuf *vendor_ext) 26408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 26418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt int i; 26428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 26438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (vendor_ext == NULL) 26448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 26458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 26468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt for (i = 0; i < P2P_MAX_WPS_VENDOR_EXT; i++) { 26478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (p2p->wps_vendor_ext[i] == NULL) 26488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 26498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 26508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (i >= P2P_MAX_WPS_VENDOR_EXT) 26518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 26528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 26538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p->wps_vendor_ext[i] = wpabuf_dup(vendor_ext); 26548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (p2p->wps_vendor_ext[i] == NULL) 26558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 26568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 26578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 26588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 26598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 26608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 26618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtint p2p_set_country(struct p2p_data *p2p, const char *country) 26628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 26638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memcpy(p2p->cfg->country, country, 3); 26648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 26658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 26668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 26678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 26688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtvoid p2p_continue_find(struct p2p_data *p2p) 26698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 26708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct p2p_device *dev; 2671f44b9c4a18d17fbd39901f76a014c32006570fb8Irfan Sheriff#ifdef ANDROID_P2P 2672f44b9c4a18d17fbd39901f76a014c32006570fb8Irfan Sheriff int skip=1; 2673f44b9c4a18d17fbd39901f76a014c32006570fb8Irfan Sheriff#endif 26748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_set_state(p2p, P2P_SEARCH); 26758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt dl_list_for_each(dev, &p2p->devices, struct p2p_device, list) { 2676f44b9c4a18d17fbd39901f76a014c32006570fb8Irfan Sheriff#ifdef ANDROID_P2P 2677f44b9c4a18d17fbd39901f76a014c32006570fb8Irfan Sheriff /* SD_FAIR_POLICY: We need to give chance to all devices in the device list 2678f44b9c4a18d17fbd39901f76a014c32006570fb8Irfan Sheriff * There may be a scenario, where a particular peer device have 2679f44b9c4a18d17fbd39901f76a014c32006570fb8Irfan Sheriff * not registered any query response. When we send a SD request to such device, 2680f44b9c4a18d17fbd39901f76a014c32006570fb8Irfan Sheriff * no response will be received. And if we continue to get probe responses from that device, 2681f44b9c4a18d17fbd39901f76a014c32006570fb8Irfan Sheriff * and if that device happens to be on top in our device list, 2682f44b9c4a18d17fbd39901f76a014c32006570fb8Irfan Sheriff * we will always continue to send SD requests always to that peer only. 2683f44b9c4a18d17fbd39901f76a014c32006570fb8Irfan Sheriff * We will not be able to send SD requests to other devices in that case. 2684f44b9c4a18d17fbd39901f76a014c32006570fb8Irfan Sheriff * This implementation keeps track of last serviced peer device. 2685f44b9c4a18d17fbd39901f76a014c32006570fb8Irfan Sheriff * And then takes the next one from the device list, in the next iteration. 2686f44b9c4a18d17fbd39901f76a014c32006570fb8Irfan Sheriff */ 2687f44b9c4a18d17fbd39901f76a014c32006570fb8Irfan Sheriff if (p2p->sd_dev_list && p2p->sd_dev_list != &p2p->devices) { 2688f44b9c4a18d17fbd39901f76a014c32006570fb8Irfan Sheriff if(skip) { 2689f44b9c4a18d17fbd39901f76a014c32006570fb8Irfan Sheriff if ((&dev->list == p2p->sd_dev_list) ) { 2690f44b9c4a18d17fbd39901f76a014c32006570fb8Irfan Sheriff skip = 0; 2691f44b9c4a18d17fbd39901f76a014c32006570fb8Irfan Sheriff if (dev->list.next == &p2p->devices) 2692f44b9c4a18d17fbd39901f76a014c32006570fb8Irfan Sheriff p2p->sd_dev_list = NULL; 2693f44b9c4a18d17fbd39901f76a014c32006570fb8Irfan Sheriff } 2694f44b9c4a18d17fbd39901f76a014c32006570fb8Irfan Sheriff continue; 2695f44b9c4a18d17fbd39901f76a014c32006570fb8Irfan Sheriff } 2696f44b9c4a18d17fbd39901f76a014c32006570fb8Irfan Sheriff } 2697f44b9c4a18d17fbd39901f76a014c32006570fb8Irfan Sheriff p2p->sd_dev_list = &dev->list; 2698f44b9c4a18d17fbd39901f76a014c32006570fb8Irfan Sheriff wpa_printf(MSG_DEBUG, "P2P: ### Servicing %p dev->flags 0x%x SD schedule %s devaddr " MACSTR, 2699f44b9c4a18d17fbd39901f76a014c32006570fb8Irfan Sheriff p2p->sd_dev_list, dev->flags, dev->flags & P2P_DEV_SD_SCHEDULE ? "TRUE": "FALSE", 2700f44b9c4a18d17fbd39901f76a014c32006570fb8Irfan Sheriff MAC2STR(dev->info.p2p_device_addr)); 2701f44b9c4a18d17fbd39901f76a014c32006570fb8Irfan Sheriff#endif 27028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (dev->flags & P2P_DEV_SD_SCHEDULE) { 27038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (p2p_start_sd(p2p, dev) == 0) 27048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; 27058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt else 27068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 27078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } else if (dev->req_config_methods && 27088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt !(dev->flags & P2P_DEV_PD_FOR_JOIN)) { 2709b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt p2p_dbg(p2p, "Send pending Provision Discovery Request to " 27108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt MACSTR " (config methods 0x%x)", 27118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt MAC2STR(dev->info.p2p_device_addr), 27128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt dev->req_config_methods); 27131f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt if (p2p_send_prov_disc_req(p2p, dev, 0, 0) == 0) 27148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; 27158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 27168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 27178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2718d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt p2p_listen_in_find(p2p, 1); 27198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 27208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 27218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 27228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic void p2p_sd_cb(struct p2p_data *p2p, int success) 27238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 2724b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt p2p_dbg(p2p, "Service Discovery Query TX callback: success=%d", 27258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt success); 27268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p->pending_action_state = P2P_NO_PENDING_ACTION; 27278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 27288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (!success) { 27298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (p2p->sd_peer) { 27308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p->sd_peer->flags &= ~P2P_DEV_SD_SCHEDULE; 27318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p->sd_peer = NULL; 27328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 27338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_continue_find(p2p); 27348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; 27358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 27368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 27378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (p2p->sd_peer == NULL) { 2738b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt p2p_dbg(p2p, "No SD peer entry known"); 27398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_continue_find(p2p); 27408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; 27418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 27428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 27438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* Wait for response from the peer */ 27448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_set_state(p2p, P2P_SD_DURING_FIND); 27458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_set_timeout(p2p, 0, 200000); 27468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 27478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 274875ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen 274975ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen/** 275075ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen * p2p_retry_pd - Retry any pending provision disc requests in IDLE state 275175ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen * @p2p: P2P module context from p2p_init() 275275ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen */ 27531f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidtstatic void p2p_retry_pd(struct p2p_data *p2p) 275475ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen{ 275575ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen struct p2p_device *dev; 275675ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen 275775ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen if (p2p->state != P2P_IDLE) 275875ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen return; 275975ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen 276075ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen /* 276175ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen * Retry the prov disc req attempt only for the peer that the user had 2762d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt * requested. 276375ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen */ 276475ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen 276575ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen dl_list_for_each(dev, &p2p->devices, struct p2p_device, list) { 276675ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen if (os_memcmp(p2p->pending_pd_devaddr, 276775ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen dev->info.p2p_device_addr, ETH_ALEN) != 0) 276875ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen continue; 276975ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen if (!dev->req_config_methods) 277075ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen continue; 277175ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen 2772b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt p2p_dbg(p2p, "Send pending Provision Discovery Request to " 277375ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen MACSTR " (config methods 0x%x)", 277475ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen MAC2STR(dev->info.p2p_device_addr), 277575ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen dev->req_config_methods); 2776d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt p2p_send_prov_disc_req(p2p, dev, 2777d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt dev->flags & P2P_DEV_PD_FOR_JOIN, 0); 277875ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen return; 277975ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen } 278075ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen} 278175ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen 278275ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen 27838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic void p2p_prov_disc_cb(struct p2p_data *p2p, int success) 27848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 2785b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt p2p_dbg(p2p, "Provision Discovery Request TX callback: success=%d", 27868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt success); 278775ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen 278875ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen /* 278975ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen * Postpone resetting the pending action state till after we actually 279075ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen * time out. This allows us to take some action like notifying any 279175ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen * interested parties about no response to the request. 279275ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen * 279375ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen * When the timer (below) goes off we check in IDLE, SEARCH, or 279475ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen * LISTEN_ONLY state, which are the only allowed states to issue a PD 279575ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen * requests in, if this was still pending and then raise notification. 279675ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen */ 27978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 27988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (!success) { 279975ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen p2p->pending_action_state = P2P_NO_PENDING_ACTION; 280075ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen 280161d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt if (p2p->user_initiated_pd && 280261d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt (p2p->state == P2P_SEARCH || p2p->state == P2P_LISTEN_ONLY)) 280361d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt { 280461d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt /* Retry request from timeout to avoid busy loops */ 280561d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt p2p->pending_action_state = P2P_PENDING_PD; 280661d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt p2p_set_timeout(p2p, 0, 50000); 280761d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt } else if (p2p->state != P2P_IDLE) 28088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_continue_find(p2p); 280975ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen else if (p2p->user_initiated_pd) { 281075ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen p2p->pending_action_state = P2P_PENDING_PD; 28111a2ce111ade9563d99ed7bb8156d6148ffd6c3a3Irfan Sheriff#ifdef ANDROID_P2P 28121a2ce111ade9563d99ed7bb8156d6148ffd6c3a3Irfan Sheriff p2p_set_timeout(p2p, 0, 350000); 28131a2ce111ade9563d99ed7bb8156d6148ffd6c3a3Irfan Sheriff#else 281475ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen p2p_set_timeout(p2p, 0, 300000); 28151a2ce111ade9563d99ed7bb8156d6148ffd6c3a3Irfan Sheriff#endif 281675ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen } 28178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; 28188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 28198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 282075ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen /* 282175ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen * This postponing, of resetting pending_action_state, needs to be 282275ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen * done only for user initiated PD requests and not internal ones. 282375ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen */ 282475ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen if (p2p->user_initiated_pd) 282575ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen p2p->pending_action_state = P2P_PENDING_PD; 282675ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen else 282775ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen p2p->pending_action_state = P2P_NO_PENDING_ACTION; 282875ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen 28298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* Wait for response from the peer */ 28308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (p2p->state == P2P_SEARCH) 28318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_set_state(p2p, P2P_PD_DURING_FIND); 28321a2ce111ade9563d99ed7bb8156d6148ffd6c3a3Irfan Sheriff#ifdef ANDROID_P2P 28331a2ce111ade9563d99ed7bb8156d6148ffd6c3a3Irfan Sheriff p2p_set_timeout(p2p, 0, 350000); 28341a2ce111ade9563d99ed7bb8156d6148ffd6c3a3Irfan Sheriff#else 28358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_set_timeout(p2p, 0, 200000); 28361a2ce111ade9563d99ed7bb8156d6148ffd6c3a3Irfan Sheriff#endif 28378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 28388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 28398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 28408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtint p2p_scan_res_handler(struct p2p_data *p2p, const u8 *bssid, int freq, 2841f86232838cf712377867cb42417c1613ab5dc425Dmitry Shmidt struct os_time *rx_time, int level, const u8 *ies, 2842a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt size_t ies_len) 28438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 2844f86232838cf712377867cb42417c1613ab5dc425Dmitry Shmidt if (os_time_before(rx_time, &p2p->find_start)) { 2845f86232838cf712377867cb42417c1613ab5dc425Dmitry Shmidt /* 2846f86232838cf712377867cb42417c1613ab5dc425Dmitry Shmidt * The driver may have cached (e.g., in cfg80211 BSS table) the 2847f86232838cf712377867cb42417c1613ab5dc425Dmitry Shmidt * scan results for relatively long time. To avoid reporting 2848f86232838cf712377867cb42417c1613ab5dc425Dmitry Shmidt * stale information, update P2P peers only based on results 2849f86232838cf712377867cb42417c1613ab5dc425Dmitry Shmidt * that have based on frames received after the last p2p_find 2850f86232838cf712377867cb42417c1613ab5dc425Dmitry Shmidt * operation was started. 2851f86232838cf712377867cb42417c1613ab5dc425Dmitry Shmidt */ 2852b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt p2p_dbg(p2p, "Ignore old scan result for " MACSTR 2853b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt " (rx_time=%u.%06u)", 2854f86232838cf712377867cb42417c1613ab5dc425Dmitry Shmidt MAC2STR(bssid), (unsigned int) rx_time->sec, 2855f86232838cf712377867cb42417c1613ab5dc425Dmitry Shmidt (unsigned int) rx_time->usec); 2856f86232838cf712377867cb42417c1613ab5dc425Dmitry Shmidt return 0; 2857f86232838cf712377867cb42417c1613ab5dc425Dmitry Shmidt } 2858f86232838cf712377867cb42417c1613ab5dc425Dmitry Shmidt 2859f86232838cf712377867cb42417c1613ab5dc425Dmitry Shmidt p2p_add_device(p2p, bssid, freq, rx_time, level, ies, ies_len, 1); 28608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 28618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 28628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 28638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 28648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 28658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtvoid p2p_scan_res_handled(struct p2p_data *p2p) 28668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 28678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (!p2p->p2p_scan_running) { 2868b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt p2p_dbg(p2p, "p2p_scan was not running, but scan results received"); 28698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 28708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p->p2p_scan_running = 0; 28718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt eloop_cancel_timeout(p2p_scan_timeout, p2p, NULL); 28728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 28738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (p2p_run_after_scan(p2p)) 28748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; 28758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (p2p->state == P2P_SEARCH) 28768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_continue_find(p2p); 28778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 28788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 28798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2880c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidtvoid p2p_scan_ie(struct p2p_data *p2p, struct wpabuf *ies, const u8 *dev_id) 28818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 288261d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt u8 *len; 288361d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt 288461d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt#ifdef CONFIG_WIFI_DISPLAY 288561d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt if (p2p->wfd_ie_probe_req) 288661d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt wpabuf_put_buf(ies, p2p->wfd_ie_probe_req); 288761d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt#endif /* CONFIG_WIFI_DISPLAY */ 288861d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt 288961d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt len = p2p_buf_add_ie_hdr(ies); 289004949598a23f501be6eec21697465fd46a28840aDmitry Shmidt p2p_buf_add_capability(ies, p2p->dev_capab & 289104949598a23f501be6eec21697465fd46a28840aDmitry Shmidt ~P2P_DEV_CAPAB_CLIENT_DISCOVERABILITY, 0); 2892c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt if (dev_id) 2893c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt p2p_buf_add_device_id(ies, dev_id); 28948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (p2p->cfg->reg_class && p2p->cfg->channel) 28958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_buf_add_listen_channel(ies, p2p->cfg->country, 28968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p->cfg->reg_class, 28978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p->cfg->channel); 28988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (p2p->ext_listen_interval) 28998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_buf_add_ext_listen_timing(ies, p2p->ext_listen_period, 29008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p->ext_listen_interval); 29018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* TODO: p2p_buf_add_operating_channel() if GO */ 29028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_buf_update_ie_hdr(ies, len); 29038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 29048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 29058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 29061f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidtsize_t p2p_scan_ie_buf_len(struct p2p_data *p2p) 29071f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt{ 290861d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt size_t len = 100; 290961d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt 291061d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt#ifdef CONFIG_WIFI_DISPLAY 291161d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt if (p2p && p2p->wfd_ie_probe_req) 291261d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt len += wpabuf_len(p2p->wfd_ie_probe_req); 291361d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt#endif /* CONFIG_WIFI_DISPLAY */ 291461d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt 291561d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt return len; 29161f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt} 29171f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt 29181f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt 29198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtint p2p_ie_text(struct wpabuf *p2p_ie, char *buf, char *end) 29208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 29218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return p2p_attr_text(p2p_ie, buf, end); 29228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 29238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 29248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 29258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic void p2p_go_neg_req_cb(struct p2p_data *p2p, int success) 29268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 29278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct p2p_device *dev = p2p->go_neg_peer; 29288c65289885e84727226d81b3d32856f79c31ee5fDmitry Shmidt int timeout; 29298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2930b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt p2p_dbg(p2p, "GO Negotiation Request TX callback: success=%d", success); 29318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 29328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (dev == NULL) { 2933b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt p2p_dbg(p2p, "No pending GO Negotiation"); 29348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; 29358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 29368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 29378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (success) { 29388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (dev->flags & P2P_DEV_USER_REJECTED) { 29398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_set_state(p2p, P2P_IDLE); 29408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; 29418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 294204949598a23f501be6eec21697465fd46a28840aDmitry Shmidt } else if (dev->go_neg_req_sent) { 294304949598a23f501be6eec21697465fd46a28840aDmitry Shmidt /* Cancel the increment from p2p_connect_send() on failure */ 294498f9e76624da6bb96edc1982c423e4a119c5170aDmitry Shmidt dev->go_neg_req_sent--; 294598f9e76624da6bb96edc1982c423e4a119c5170aDmitry Shmidt } 29468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 29478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (!success && 29488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt (dev->info.dev_capab & P2P_DEV_CAPAB_CLIENT_DISCOVERABILITY) && 29498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt !is_zero_ether_addr(dev->member_in_go_dev)) { 2950b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt p2p_dbg(p2p, "Peer " MACSTR " did not acknowledge request - try to use device discoverability through its GO", 29518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt MAC2STR(dev->info.p2p_device_addr)); 29528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p->cfg->send_action_done(p2p->cfg->cb_ctx); 29538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_send_dev_disc_req(p2p, dev); 29548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; 29558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 29568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 29578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* 29588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * Use P2P find, if needed, to find the other device from its listen 29598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * channel. 29608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */ 29618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_set_state(p2p, P2P_CONNECT); 29628c65289885e84727226d81b3d32856f79c31ee5fDmitry Shmidt timeout = success ? 500000 : 100000; 29638c65289885e84727226d81b3d32856f79c31ee5fDmitry Shmidt if (!success && p2p->go_neg_peer && 29648c65289885e84727226d81b3d32856f79c31ee5fDmitry Shmidt (p2p->go_neg_peer->flags & P2P_DEV_PEER_WAITING_RESPONSE)) { 29658c65289885e84727226d81b3d32856f79c31ee5fDmitry Shmidt unsigned int r; 29668c65289885e84727226d81b3d32856f79c31ee5fDmitry Shmidt /* 29678c65289885e84727226d81b3d32856f79c31ee5fDmitry Shmidt * Peer is expected to wait our response and we will skip the 29688c65289885e84727226d81b3d32856f79c31ee5fDmitry Shmidt * listen phase. Add some randomness to the wait time here to 29698c65289885e84727226d81b3d32856f79c31ee5fDmitry Shmidt * make it less likely to hit cases where we could end up in 29708c65289885e84727226d81b3d32856f79c31ee5fDmitry Shmidt * sync with peer not listening. 29718c65289885e84727226d81b3d32856f79c31ee5fDmitry Shmidt */ 29728c65289885e84727226d81b3d32856f79c31ee5fDmitry Shmidt os_get_random((u8 *) &r, sizeof(r)); 29738c65289885e84727226d81b3d32856f79c31ee5fDmitry Shmidt timeout += r % 100000; 29748c65289885e84727226d81b3d32856f79c31ee5fDmitry Shmidt } 29758c65289885e84727226d81b3d32856f79c31ee5fDmitry Shmidt p2p_set_timeout(p2p, 0, timeout); 29768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 29778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 29788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 29798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic void p2p_go_neg_resp_cb(struct p2p_data *p2p, int success) 29808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 2981b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt p2p_dbg(p2p, "GO Negotiation Response TX callback: success=%d", 29828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt success); 29838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (!p2p->go_neg_peer && p2p->state == P2P_PROVISIONING) { 2984b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt p2p_dbg(p2p, "Ignore TX callback event - GO Negotiation is not running anymore"); 29858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; 29868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 29878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_set_state(p2p, P2P_CONNECT); 29888c65289885e84727226d81b3d32856f79c31ee5fDmitry Shmidt p2p_set_timeout(p2p, 0, 500000); 29898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 29908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 29918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 29924b06059785b935dd1f4f09314e4e12c417d2c6a4Dmitry Shmidtstatic void p2p_go_neg_resp_failure_cb(struct p2p_data *p2p, int success, 29934b06059785b935dd1f4f09314e4e12c417d2c6a4Dmitry Shmidt const u8 *addr) 29948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 2995b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt p2p_dbg(p2p, "GO Negotiation Response (failure) TX callback: success=%d", success); 29968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (p2p->go_neg_peer && p2p->go_neg_peer->status != P2P_SC_SUCCESS) { 29978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_go_neg_failed(p2p, p2p->go_neg_peer, 29988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p->go_neg_peer->status); 29994b06059785b935dd1f4f09314e4e12c417d2c6a4Dmitry Shmidt } else if (success) { 30004b06059785b935dd1f4f09314e4e12c417d2c6a4Dmitry Shmidt struct p2p_device *dev; 30014b06059785b935dd1f4f09314e4e12c417d2c6a4Dmitry Shmidt dev = p2p_get_device(p2p, addr); 30024b06059785b935dd1f4f09314e4e12c417d2c6a4Dmitry Shmidt if (dev && 30034b06059785b935dd1f4f09314e4e12c417d2c6a4Dmitry Shmidt dev->status == P2P_SC_FAIL_INFO_CURRENTLY_UNAVAILABLE) 30044b06059785b935dd1f4f09314e4e12c417d2c6a4Dmitry Shmidt dev->flags |= P2P_DEV_PEER_WAITING_RESPONSE; 30058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 30068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 30078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 30088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 30098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic void p2p_go_neg_conf_cb(struct p2p_data *p2p, 30108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt enum p2p_send_action_result result) 30118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 30128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct p2p_device *dev; 30138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 3014b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt p2p_dbg(p2p, "GO Negotiation Confirm TX callback: result=%d", result); 30158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p->cfg->send_action_done(p2p->cfg->cb_ctx); 30168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (result == P2P_SEND_ACTION_FAILED) { 30178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_go_neg_failed(p2p, p2p->go_neg_peer, -1); 30188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; 30198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 30208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (result == P2P_SEND_ACTION_NO_ACK) { 30218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* 30228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * It looks like the TX status for GO Negotiation Confirm is 30238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * often showing failure even when the peer has actually 30248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * received the frame. Since the peer may change channels 30258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * immediately after having received the frame, we may not see 30268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * an Ack for retries, so just dropping a single frame may 30278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * trigger this. To allow the group formation to succeed if the 30288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * peer did indeed receive the frame, continue regardless of 30298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * the TX status. 30308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */ 3031b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt p2p_dbg(p2p, "Assume GO Negotiation Confirm TX was actually received by the peer even though Ack was not reported"); 30328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 30338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 30348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt dev = p2p->go_neg_peer; 30358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (dev == NULL) 30368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; 30378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 30388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_go_complete(p2p, dev); 30398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 30408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 30418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 30428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtvoid p2p_send_action_cb(struct p2p_data *p2p, unsigned int freq, const u8 *dst, 30438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt const u8 *src, const u8 *bssid, 30448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt enum p2p_send_action_result result) 30458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 30468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt enum p2p_pending_action_state state; 30478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt int success; 30488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 3049b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt p2p_dbg(p2p, "Action frame TX callback (state=%d freq=%u dst=" MACSTR 30508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt " src=" MACSTR " bssid=" MACSTR " result=%d", 30518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p->pending_action_state, freq, MAC2STR(dst), MAC2STR(src), 30528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt MAC2STR(bssid), result); 30538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt success = result == P2P_SEND_ACTION_SUCCESS; 30548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt state = p2p->pending_action_state; 30558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p->pending_action_state = P2P_NO_PENDING_ACTION; 30568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt switch (state) { 30578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case P2P_NO_PENDING_ACTION: 30588da800a193fb6f8832218715f82a7b4e2d2ad338Dmitry Shmidt if (p2p->after_scan_tx_in_progress) { 30598da800a193fb6f8832218715f82a7b4e2d2ad338Dmitry Shmidt p2p->after_scan_tx_in_progress = 0; 30608da800a193fb6f8832218715f82a7b4e2d2ad338Dmitry Shmidt if (p2p->start_after_scan != P2P_AFTER_SCAN_NOTHING && 30618da800a193fb6f8832218715f82a7b4e2d2ad338Dmitry Shmidt p2p_run_after_scan(p2p)) 30628da800a193fb6f8832218715f82a7b4e2d2ad338Dmitry Shmidt break; 30638da800a193fb6f8832218715f82a7b4e2d2ad338Dmitry Shmidt if (p2p->state == P2P_SEARCH) { 3064b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt p2p_dbg(p2p, "Continue find after after_scan_tx completion"); 30658da800a193fb6f8832218715f82a7b4e2d2ad338Dmitry Shmidt p2p_continue_find(p2p); 30668da800a193fb6f8832218715f82a7b4e2d2ad338Dmitry Shmidt } 30678da800a193fb6f8832218715f82a7b4e2d2ad338Dmitry Shmidt } 30688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 30698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case P2P_PENDING_GO_NEG_REQUEST: 30708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_go_neg_req_cb(p2p, success); 30718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 30728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case P2P_PENDING_GO_NEG_RESPONSE: 30738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_go_neg_resp_cb(p2p, success); 30748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 30758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case P2P_PENDING_GO_NEG_RESPONSE_FAILURE: 30764b06059785b935dd1f4f09314e4e12c417d2c6a4Dmitry Shmidt p2p_go_neg_resp_failure_cb(p2p, success, dst); 30778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 30788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case P2P_PENDING_GO_NEG_CONFIRM: 30798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_go_neg_conf_cb(p2p, result); 30808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 30818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case P2P_PENDING_SD: 30828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_sd_cb(p2p, success); 30838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 30848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case P2P_PENDING_PD: 30858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_prov_disc_cb(p2p, success); 30868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 30878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case P2P_PENDING_INVITATION_REQUEST: 30888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_invitation_req_cb(p2p, success); 30898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 30908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case P2P_PENDING_INVITATION_RESPONSE: 30918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_invitation_resp_cb(p2p, success); 30928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 30938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case P2P_PENDING_DEV_DISC_REQUEST: 30948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_dev_disc_req_cb(p2p, success); 30958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 30968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case P2P_PENDING_DEV_DISC_RESPONSE: 30978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_dev_disc_resp_cb(p2p, success); 30988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 30998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case P2P_PENDING_GO_DISC_REQ: 31008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_go_disc_req_cb(p2p, success); 31018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 31028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 31038da800a193fb6f8832218715f82a7b4e2d2ad338Dmitry Shmidt 31048da800a193fb6f8832218715f82a7b4e2d2ad338Dmitry Shmidt p2p->after_scan_tx_in_progress = 0; 31058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 31068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 31078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 31088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtvoid p2p_listen_cb(struct p2p_data *p2p, unsigned int freq, 31098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt unsigned int duration) 31108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 31118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (freq == p2p->pending_client_disc_freq) { 3112b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt p2p_dbg(p2p, "Client discoverability remain-awake completed"); 31138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p->pending_client_disc_freq = 0; 31148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; 31158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 31168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 31178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (freq != p2p->pending_listen_freq) { 3118b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt p2p_dbg(p2p, "Unexpected listen callback for freq=%u duration=%u (pending_listen_freq=%u)", 31198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt freq, duration, p2p->pending_listen_freq); 31208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; 31218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 31228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 3123b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt p2p_dbg(p2p, "Starting Listen timeout(%u,%u) on freq=%u based on callback", 31248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p->pending_listen_sec, p2p->pending_listen_usec, 31258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p->pending_listen_freq); 31268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p->in_listen = 1; 31278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p->drv_in_listen = freq; 31288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (p2p->pending_listen_sec || p2p->pending_listen_usec) { 31298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* 31308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * Add 20 msec extra wait to avoid race condition with driver 31318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * remain-on-channel end event, i.e., give driver more time to 31328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * complete the operation before our timeout expires. 31338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */ 31348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_set_timeout(p2p, p2p->pending_listen_sec, 31358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p->pending_listen_usec + 20000); 31368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 31378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 31388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p->pending_listen_freq = 0; 31398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 31408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 31418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 31428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtint p2p_listen_end(struct p2p_data *p2p, unsigned int freq) 31438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 3144b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt p2p_dbg(p2p, "Driver ended Listen state (freq=%u)", freq); 31458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p->drv_in_listen = 0; 31468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (p2p->in_listen) 31478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; /* Internal timeout will trigger the next step */ 31488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 31498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (p2p->state == P2P_CONNECT_LISTEN && p2p->go_neg_peer) { 31508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (p2p->go_neg_peer->connect_reqs >= 120) { 3151b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt p2p_dbg(p2p, "Timeout on sending GO Negotiation Request without getting response"); 31528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_go_neg_failed(p2p, p2p->go_neg_peer, -1); 31538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 31548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 31558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 31568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_set_state(p2p, P2P_CONNECT); 31578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_connect_send(p2p, p2p->go_neg_peer); 31588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 1; 31598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } else if (p2p->state == P2P_SEARCH) { 3160c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt if (p2p->p2p_scan_running) { 3161c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt /* 3162c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt * Search is already in progress. This can happen if 3163c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt * an Action frame RX is reported immediately after 3164c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt * the end of a remain-on-channel operation and the 3165c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt * response frame to that is sent using an offchannel 3166c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt * operation while in p2p_find. Avoid an attempt to 3167c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt * restart a scan here. 3168c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt */ 3169b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt p2p_dbg(p2p, "p2p_scan already in progress - do not try to start a new one"); 3170c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt return 1; 3171c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt } 317204949598a23f501be6eec21697465fd46a28840aDmitry Shmidt if (p2p->pending_listen_freq) { 317304949598a23f501be6eec21697465fd46a28840aDmitry Shmidt /* 317404949598a23f501be6eec21697465fd46a28840aDmitry Shmidt * Better wait a bit if the driver is unable to start 317504949598a23f501be6eec21697465fd46a28840aDmitry Shmidt * offchannel operation for some reason. p2p_search() 317604949598a23f501be6eec21697465fd46a28840aDmitry Shmidt * will be started from internal timeout. 317704949598a23f501be6eec21697465fd46a28840aDmitry Shmidt */ 3178b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt p2p_dbg(p2p, "Listen operation did not seem to start - delay search phase to avoid busy loop"); 317904949598a23f501be6eec21697465fd46a28840aDmitry Shmidt p2p_set_timeout(p2p, 0, 100000); 318004949598a23f501be6eec21697465fd46a28840aDmitry Shmidt return 1; 318104949598a23f501be6eec21697465fd46a28840aDmitry Shmidt } 318261d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt if (p2p->search_delay) { 3183b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt p2p_dbg(p2p, "Delay search operation by %u ms", 318461d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt p2p->search_delay); 318561d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt p2p_set_timeout(p2p, p2p->search_delay / 1000, 318661d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt (p2p->search_delay % 1000) * 1000); 318761d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt return 1; 318861d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt } 31898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_search(p2p); 31908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 1; 31918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 31928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 31938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 31948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 31958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 31968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 31978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic void p2p_timeout_connect(struct p2p_data *p2p) 31988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 31998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p->cfg->send_action_done(p2p->cfg->cb_ctx); 320004949598a23f501be6eec21697465fd46a28840aDmitry Shmidt if (p2p->go_neg_peer && 320104949598a23f501be6eec21697465fd46a28840aDmitry Shmidt (p2p->go_neg_peer->flags & P2P_DEV_WAIT_GO_NEG_CONFIRM)) { 3202b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt p2p_dbg(p2p, "Wait for GO Negotiation Confirm timed out - assume GO Negotiation failed"); 320304949598a23f501be6eec21697465fd46a28840aDmitry Shmidt p2p_go_neg_failed(p2p, p2p->go_neg_peer, -1); 320404949598a23f501be6eec21697465fd46a28840aDmitry Shmidt return; 320504949598a23f501be6eec21697465fd46a28840aDmitry Shmidt } 32068c65289885e84727226d81b3d32856f79c31ee5fDmitry Shmidt if (p2p->go_neg_peer && 32078c65289885e84727226d81b3d32856f79c31ee5fDmitry Shmidt (p2p->go_neg_peer->flags & P2P_DEV_PEER_WAITING_RESPONSE) && 32088c65289885e84727226d81b3d32856f79c31ee5fDmitry Shmidt p2p->go_neg_peer->connect_reqs < 120) { 3209b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt p2p_dbg(p2p, "Peer expected to wait our response - skip listen"); 32108c65289885e84727226d81b3d32856f79c31ee5fDmitry Shmidt p2p_connect_send(p2p, p2p->go_neg_peer); 32118c65289885e84727226d81b3d32856f79c31ee5fDmitry Shmidt return; 32128c65289885e84727226d81b3d32856f79c31ee5fDmitry Shmidt } 32138c65289885e84727226d81b3d32856f79c31ee5fDmitry Shmidt 32148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_set_state(p2p, P2P_CONNECT_LISTEN); 3215d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt p2p_listen_in_find(p2p, 0); 32168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 32178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 32188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 32198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic void p2p_timeout_connect_listen(struct p2p_data *p2p) 32208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 32218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (p2p->go_neg_peer) { 32228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (p2p->drv_in_listen) { 3223b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt p2p_dbg(p2p, "Driver is still in Listen state; wait for it to complete"); 32248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; 32258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 32268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 32278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (p2p->go_neg_peer->connect_reqs >= 120) { 3228b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt p2p_dbg(p2p, "Timeout on sending GO Negotiation Request without getting response"); 32298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_go_neg_failed(p2p, p2p->go_neg_peer, -1); 32308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; 32318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 32328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 32338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_set_state(p2p, P2P_CONNECT); 32348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_connect_send(p2p, p2p->go_neg_peer); 32358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } else 32368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_set_state(p2p, P2P_IDLE); 32378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 32388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 32398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 32408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic void p2p_timeout_wait_peer_connect(struct p2p_data *p2p) 32418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 32428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* 32438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * TODO: could remain constantly in Listen state for some time if there 32448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * are no other concurrent uses for the radio. For now, go to listen 32458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * state once per second to give other uses a chance to use the radio. 32468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */ 32478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_set_state(p2p, P2P_WAIT_PEER_IDLE); 32481f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt p2p_set_timeout(p2p, 0, 500000); 32498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 32508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 32518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 32528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic void p2p_timeout_wait_peer_idle(struct p2p_data *p2p) 32538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 32548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct p2p_device *dev = p2p->go_neg_peer; 32558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 32568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (dev == NULL) { 3257b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt p2p_dbg(p2p, "Unknown GO Neg peer - stop GO Neg wait"); 32588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; 32598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 32608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 32618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt dev->wait_count++; 32628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (dev->wait_count >= 120) { 3263b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt p2p_dbg(p2p, "Timeout on waiting peer to become ready for GO Negotiation"); 32648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_go_neg_failed(p2p, dev, -1); 32658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; 32668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 32678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 3268b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt p2p_dbg(p2p, "Go to Listen state while waiting for the peer to become ready for GO Negotiation"); 32698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_set_state(p2p, P2P_WAIT_PEER_CONNECT); 3270d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt p2p_listen_in_find(p2p, 0); 32718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 32728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 32738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 32748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic void p2p_timeout_sd_during_find(struct p2p_data *p2p) 32758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 3276b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt p2p_dbg(p2p, "Service Discovery Query timeout"); 32778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (p2p->sd_peer) { 32788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p->cfg->send_action_done(p2p->cfg->cb_ctx); 32798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p->sd_peer->flags &= ~P2P_DEV_SD_SCHEDULE; 32808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p->sd_peer = NULL; 32818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 32828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_continue_find(p2p); 32838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 32848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 32858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 32868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic void p2p_timeout_prov_disc_during_find(struct p2p_data *p2p) 32878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 3288b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt p2p_dbg(p2p, "Provision Discovery Request timeout"); 32898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p->cfg->send_action_done(p2p->cfg->cb_ctx); 32908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_continue_find(p2p); 32918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 32928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 32938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 329475ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinenstatic void p2p_timeout_prov_disc_req(struct p2p_data *p2p) 329575ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen{ 329675ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen p2p->pending_action_state = P2P_NO_PENDING_ACTION; 329775ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen 329875ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen /* 329975ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen * For user initiated PD requests that we have not gotten any responses 330075ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen * for while in IDLE state, we retry them a couple of times before 330175ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen * giving up. 330275ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen */ 330375ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen if (!p2p->user_initiated_pd) 330475ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen return; 330575ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen 3306b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt p2p_dbg(p2p, "User initiated Provision Discovery Request timeout"); 330775ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen 330875ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen if (p2p->pd_retries) { 330975ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen p2p->pd_retries--; 331075ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen p2p_retry_pd(p2p); 331175ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen } else { 3312d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt struct p2p_device *dev; 3313d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt int for_join = 0; 3314d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt 3315d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt dl_list_for_each(dev, &p2p->devices, struct p2p_device, list) { 3316d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt if (os_memcmp(p2p->pending_pd_devaddr, 3317d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt dev->info.p2p_device_addr, ETH_ALEN) != 0) 3318d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt continue; 3319d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt if (dev->req_config_methods && 3320d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt (dev->flags & P2P_DEV_PD_FOR_JOIN)) 3321d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt for_join = 1; 3322d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt } 3323d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt 332475ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen if (p2p->cfg->prov_disc_fail) 332575ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen p2p->cfg->prov_disc_fail(p2p->cfg->cb_ctx, 332675ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen p2p->pending_pd_devaddr, 3327d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt for_join ? 3328d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt P2P_PROV_DISC_TIMEOUT_JOIN : 332975ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen P2P_PROV_DISC_TIMEOUT); 333075ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen p2p_reset_pending_pd(p2p); 333175ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen } 333275ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen} 333375ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen 333475ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen 33358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic void p2p_timeout_invite(struct p2p_data *p2p) 33368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 33378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p->cfg->send_action_done(p2p->cfg->cb_ctx); 33388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_set_state(p2p, P2P_INVITE_LISTEN); 33398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (p2p->inv_role == P2P_INVITE_ROLE_ACTIVE_GO) { 33408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* 33418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * Better remain on operating channel instead of listen channel 33428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * when running a group. 33438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */ 3344b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt p2p_dbg(p2p, "Inviting in active GO role - wait on operating channel"); 33458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_set_timeout(p2p, 0, 100000); 33468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; 33478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 3348d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt p2p_listen_in_find(p2p, 0); 33498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 33508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 33518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 33528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic void p2p_timeout_invite_listen(struct p2p_data *p2p) 33538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 33548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (p2p->invite_peer && p2p->invite_peer->invitation_reqs < 100) { 33558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_set_state(p2p, P2P_INVITE); 33568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_invite_send(p2p, p2p->invite_peer, 33578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p->invite_go_dev_addr); 33588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } else { 33598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (p2p->invite_peer) { 3360b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt p2p_dbg(p2p, "Invitation Request retry limit reached"); 33618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (p2p->cfg->invitation_result) 33628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p->cfg->invitation_result( 3363700a137ab366edc72e371da68ba187b4717ee660Dmitry Shmidt p2p->cfg->cb_ctx, -1, NULL, NULL, 3364700a137ab366edc72e371da68ba187b4717ee660Dmitry Shmidt p2p->invite_peer->info.p2p_device_addr); 33658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 33668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_set_state(p2p, P2P_IDLE); 33678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 33688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 33698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 33708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 33718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic void p2p_state_timeout(void *eloop_ctx, void *timeout_ctx) 33728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 33738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct p2p_data *p2p = eloop_ctx; 33748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 3375b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt p2p_dbg(p2p, "Timeout (state=%s)", p2p_state_txt(p2p->state)); 33768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 33778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p->in_listen = 0; 33788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 33798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt switch (p2p->state) { 33808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case P2P_IDLE: 338175ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen /* Check if we timed out waiting for PD req */ 338275ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen if (p2p->pending_action_state == P2P_PENDING_PD) 338375ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen p2p_timeout_prov_disc_req(p2p); 33848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 33858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case P2P_SEARCH: 338675ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen /* Check if we timed out waiting for PD req */ 338775ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen if (p2p->pending_action_state == P2P_PENDING_PD) 338875ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen p2p_timeout_prov_disc_req(p2p); 338961d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt if (p2p->search_delay && !p2p->in_search_delay) { 3390b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt p2p_dbg(p2p, "Delay search operation by %u ms", 339161d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt p2p->search_delay); 339261d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt p2p->in_search_delay = 1; 339361d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt p2p_set_timeout(p2p, p2p->search_delay / 1000, 339461d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt (p2p->search_delay % 1000) * 1000); 339561d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt break; 339661d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt } 339761d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt p2p->in_search_delay = 0; 33988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_search(p2p); 33998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 34008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case P2P_CONNECT: 34018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_timeout_connect(p2p); 34028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 34038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case P2P_CONNECT_LISTEN: 34048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_timeout_connect_listen(p2p); 34058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 34068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case P2P_GO_NEG: 34078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 34088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case P2P_LISTEN_ONLY: 340975ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen /* Check if we timed out waiting for PD req */ 341075ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen if (p2p->pending_action_state == P2P_PENDING_PD) 341175ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen p2p_timeout_prov_disc_req(p2p); 341275ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen 34138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (p2p->ext_listen_only) { 3414b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt p2p_dbg(p2p, "Extended Listen Timing - Listen State completed"); 34158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p->ext_listen_only = 0; 34168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_set_state(p2p, P2P_IDLE); 34178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 34188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 34198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case P2P_WAIT_PEER_CONNECT: 34208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_timeout_wait_peer_connect(p2p); 34218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 34228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case P2P_WAIT_PEER_IDLE: 34238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_timeout_wait_peer_idle(p2p); 34248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 34258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case P2P_SD_DURING_FIND: 34268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_timeout_sd_during_find(p2p); 34278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 34288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case P2P_PROVISIONING: 34298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 34308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case P2P_PD_DURING_FIND: 34318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_timeout_prov_disc_during_find(p2p); 34328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 34338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case P2P_INVITE: 34348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_timeout_invite(p2p); 34358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 34368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case P2P_INVITE_LISTEN: 34378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_timeout_invite_listen(p2p); 34388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 34391f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt case P2P_SEARCH_WHEN_READY: 34401f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt break; 344161d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt case P2P_CONTINUE_SEARCH_WHEN_READY: 344261d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt break; 34438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 34448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 34458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 34468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 34478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtint p2p_reject(struct p2p_data *p2p, const u8 *peer_addr) 34488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 34498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct p2p_device *dev; 34508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 34518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt dev = p2p_get_device(p2p, peer_addr); 3452b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt p2p_dbg(p2p, "Local request to reject connection attempts by peer " 3453b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt MACSTR, MAC2STR(peer_addr)); 34548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (dev == NULL) { 3455b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt p2p_dbg(p2p, "Peer " MACSTR " unknown", MAC2STR(peer_addr)); 34568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 34578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 34588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt dev->status = P2P_SC_FAIL_REJECTED_BY_USER; 34598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt dev->flags |= P2P_DEV_USER_REJECTED; 34608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 34618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 34628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 34638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 34641f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidtconst char * p2p_wps_method_text(enum p2p_wps_method method) 34658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 34668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt switch (method) { 34678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case WPS_NOT_READY: 34688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return "not-ready"; 34698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case WPS_PIN_DISPLAY: 34708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return "Display"; 34718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case WPS_PIN_KEYPAD: 34728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return "Keypad"; 34738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case WPS_PBC: 34748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return "PBC"; 34758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 34768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 34778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return "??"; 34788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 34798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 34808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 34818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic const char * p2p_go_state_text(enum p2p_go_state go_state) 34828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 34838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt switch (go_state) { 34848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case UNKNOWN_GO: 34858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return "unknown"; 34868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case LOCAL_GO: 34878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return "local"; 34888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case REMOTE_GO: 34898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return "remote"; 34908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 34918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 34928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return "??"; 34938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 34948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 34958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 34961f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidtconst struct p2p_peer_info * p2p_get_peer_info(struct p2p_data *p2p, 34971f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt const u8 *addr, int next) 34988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 34998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct p2p_device *dev; 35008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 35018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (addr) 35028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt dev = p2p_get_device(p2p, addr); 35038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt else 35048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt dev = dl_list_first(&p2p->devices, struct p2p_device, list); 35058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 35068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (dev && next) { 35078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt dev = dl_list_first(&dev->list, struct p2p_device, list); 35088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (&dev->list == &p2p->devices) 35098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt dev = NULL; 35108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 35118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 35128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (dev == NULL) 35131f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt return NULL; 35141f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt 35151f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt return &dev->info; 35161f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt} 35171f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt 35181f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt 35191f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidtint p2p_get_peer_info_txt(const struct p2p_peer_info *info, 35201f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt char *buf, size_t buflen) 35211f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt{ 35221f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt struct p2p_device *dev; 35231f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt int res; 35241f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt char *pos, *end; 35251f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt struct os_time now; 35261f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt 35271f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt if (info == NULL) 35288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 35298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 35301f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt dev = (struct p2p_device *) (((u8 *) info) - 35311f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt offsetof(struct p2p_device, info)); 35321f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt 35338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt pos = buf; 35348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt end = buf + buflen; 35358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 35368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_get_time(&now); 35378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt res = os_snprintf(pos, end - pos, 35388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "age=%d\n" 35398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "listen_freq=%d\n" 35408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "wps_method=%s\n" 35418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "interface_addr=" MACSTR "\n" 35428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "member_in_go_dev=" MACSTR "\n" 35438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "member_in_go_iface=" MACSTR "\n" 35448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "go_neg_req_sent=%d\n" 35458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "go_state=%s\n" 35468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "dialog_token=%u\n" 35478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "intended_addr=" MACSTR "\n" 35488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "country=%c%c\n" 35498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "oper_freq=%d\n" 35508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "req_config_methods=0x%x\n" 35518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "flags=%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s\n" 35528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "status=%d\n" 35538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "wait_count=%u\n" 35548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "invitation_reqs=%u\n", 35558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt (int) (now.sec - dev->last_seen.sec), 35568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt dev->listen_freq, 35578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_wps_method_text(dev->wps_method), 35588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt MAC2STR(dev->interface_addr), 35598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt MAC2STR(dev->member_in_go_dev), 35608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt MAC2STR(dev->member_in_go_iface), 35618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt dev->go_neg_req_sent, 35628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_go_state_text(dev->go_state), 35638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt dev->dialog_token, 35648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt MAC2STR(dev->intended_addr), 35658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt dev->country[0] ? dev->country[0] : '_', 35668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt dev->country[1] ? dev->country[1] : '_', 35678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt dev->oper_freq, 35688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt dev->req_config_methods, 35698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt dev->flags & P2P_DEV_PROBE_REQ_ONLY ? 35708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "[PROBE_REQ_ONLY]" : "", 35718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt dev->flags & P2P_DEV_REPORTED ? "[REPORTED]" : "", 35728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt dev->flags & P2P_DEV_NOT_YET_READY ? 35738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "[NOT_YET_READY]" : "", 35748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt dev->flags & P2P_DEV_SD_INFO ? "[SD_INFO]" : "", 35758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt dev->flags & P2P_DEV_SD_SCHEDULE ? "[SD_SCHEDULE]" : 35768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "", 35778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt dev->flags & P2P_DEV_PD_PEER_DISPLAY ? 35788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "[PD_PEER_DISPLAY]" : "", 35798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt dev->flags & P2P_DEV_PD_PEER_KEYPAD ? 35808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "[PD_PEER_KEYPAD]" : "", 35818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt dev->flags & P2P_DEV_USER_REJECTED ? 35828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "[USER_REJECTED]" : "", 35838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt dev->flags & P2P_DEV_PEER_WAITING_RESPONSE ? 35848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "[PEER_WAITING_RESPONSE]" : "", 35858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt dev->flags & P2P_DEV_PREFER_PERSISTENT_GROUP ? 35868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "[PREFER_PERSISTENT_GROUP]" : "", 35878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt dev->flags & P2P_DEV_WAIT_GO_NEG_RESPONSE ? 35888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "[WAIT_GO_NEG_RESPONSE]" : "", 35898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt dev->flags & P2P_DEV_WAIT_GO_NEG_CONFIRM ? 35908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "[WAIT_GO_NEG_CONFIRM]" : "", 35918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt dev->flags & P2P_DEV_GROUP_CLIENT_ONLY ? 35928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "[GROUP_CLIENT_ONLY]" : "", 35938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt dev->flags & P2P_DEV_FORCE_FREQ ? 35948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "[FORCE_FREQ]" : "", 35958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt dev->flags & P2P_DEV_PD_FOR_JOIN ? 35968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "[PD_FOR_JOIN]" : "", 35978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt dev->status, 35988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt dev->wait_count, 35998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt dev->invitation_reqs); 36008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (res < 0 || res >= end - pos) 36018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return pos - buf; 36028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt pos += res; 36038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 36048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (dev->ext_listen_period) { 36058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt res = os_snprintf(pos, end - pos, 36068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "ext_listen_period=%u\n" 36078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "ext_listen_interval=%u\n", 36088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt dev->ext_listen_period, 36098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt dev->ext_listen_interval); 36108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (res < 0 || res >= end - pos) 36118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return pos - buf; 36128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt pos += res; 36138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 36148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 36158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (dev->oper_ssid_len) { 36168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt res = os_snprintf(pos, end - pos, 36178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "oper_ssid=%s\n", 36188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_ssid_txt(dev->oper_ssid, 36198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt dev->oper_ssid_len)); 36208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (res < 0 || res >= end - pos) 36218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return pos - buf; 36228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt pos += res; 36238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 36248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 362561d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt#ifdef CONFIG_WIFI_DISPLAY 362661d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt if (dev->info.wfd_subelems) { 362761d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt res = os_snprintf(pos, end - pos, "wfd_subelems="); 362861d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt if (res < 0 || res >= end - pos) 362961d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt return pos - buf; 363061d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt pos += res; 363161d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt 363261d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt pos += wpa_snprintf_hex(pos, end - pos, 363361d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt wpabuf_head(dev->info.wfd_subelems), 363461d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt wpabuf_len(dev->info.wfd_subelems)); 363561d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt 363661d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt res = os_snprintf(pos, end - pos, "\n"); 363761d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt if (res < 0 || res >= end - pos) 363861d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt return pos - buf; 363961d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt pos += res; 364061d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt } 364161d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt#endif /* CONFIG_WIFI_DISPLAY */ 364261d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt 36438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return pos - buf; 36448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 36458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 36468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 36471f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidtint p2p_peer_known(struct p2p_data *p2p, const u8 *addr) 36481f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt{ 36491f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt return p2p_get_device(p2p, addr) != NULL; 36501f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt} 36511f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt 36521f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt 36538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtvoid p2p_set_client_discoverability(struct p2p_data *p2p, int enabled) 36548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 36558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (enabled) { 3656b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt p2p_dbg(p2p, "Client discoverability enabled"); 36578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p->dev_capab |= P2P_DEV_CAPAB_CLIENT_DISCOVERABILITY; 36588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } else { 3659b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt p2p_dbg(p2p, "Client discoverability disabled"); 36608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p->dev_capab &= ~P2P_DEV_CAPAB_CLIENT_DISCOVERABILITY; 36618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 36628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 36638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 36648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 36658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic struct wpabuf * p2p_build_presence_req(u32 duration1, u32 interval1, 36668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt u32 duration2, u32 interval2) 36678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 36688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct wpabuf *req; 36698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct p2p_noa_desc desc1, desc2, *ptr1 = NULL, *ptr2 = NULL; 36708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt u8 *len; 36718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 36728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt req = wpabuf_alloc(100); 36738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (req == NULL) 36748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return NULL; 36758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 36768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (duration1 || interval1) { 36778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memset(&desc1, 0, sizeof(desc1)); 36788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt desc1.count_type = 1; 36798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt desc1.duration = duration1; 36808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt desc1.interval = interval1; 36818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ptr1 = &desc1; 36828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 36838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (duration2 || interval2) { 36848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memset(&desc2, 0, sizeof(desc2)); 36858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt desc2.count_type = 2; 36868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt desc2.duration = duration2; 36878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt desc2.interval = interval2; 36888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ptr2 = &desc2; 36898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 36908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 36918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 36928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_buf_add_action_hdr(req, P2P_PRESENCE_REQ, 1); 36938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt len = p2p_buf_add_ie_hdr(req); 36948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_buf_add_noa(req, 0, 0, 0, ptr1, ptr2); 36958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_buf_update_ie_hdr(req, len); 36968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 36978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return req; 36988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 36998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 37008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 37018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtint p2p_presence_req(struct p2p_data *p2p, const u8 *go_interface_addr, 37028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt const u8 *own_interface_addr, unsigned int freq, 37038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt u32 duration1, u32 interval1, u32 duration2, 37048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt u32 interval2) 37058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 37068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct wpabuf *req; 37078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 3708b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt p2p_dbg(p2p, "Send Presence Request to GO " MACSTR 3709b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt " (own interface " MACSTR ") freq=%u dur1=%u int1=%u " 3710b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt "dur2=%u int2=%u", 37118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt MAC2STR(go_interface_addr), MAC2STR(own_interface_addr), 37128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt freq, duration1, interval1, duration2, interval2); 37138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 37148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt req = p2p_build_presence_req(duration1, interval1, duration2, 37158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt interval2); 37168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (req == NULL) 37178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 37188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 37198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p->pending_action_state = P2P_NO_PENDING_ACTION; 37208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (p2p_send_action(p2p, freq, go_interface_addr, own_interface_addr, 37218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt go_interface_addr, 37228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpabuf_head(req), wpabuf_len(req), 200) < 0) { 3723b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt p2p_dbg(p2p, "Failed to send Action frame"); 37248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 37258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpabuf_free(req); 37268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 37278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 37288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 37298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 37308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 37318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic struct wpabuf * p2p_build_presence_resp(u8 status, const u8 *noa, 37328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt size_t noa_len, u8 dialog_token) 37338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 37348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct wpabuf *resp; 37358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt u8 *len; 37368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 37378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt resp = wpabuf_alloc(100 + noa_len); 37388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (resp == NULL) 37398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return NULL; 37408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 37418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_buf_add_action_hdr(resp, P2P_PRESENCE_RESP, dialog_token); 37428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt len = p2p_buf_add_ie_hdr(resp); 37438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_buf_add_status(resp, status); 37448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (noa) { 37458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpabuf_put_u8(resp, P2P_ATTR_NOTICE_OF_ABSENCE); 37468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpabuf_put_le16(resp, noa_len); 37478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpabuf_put_data(resp, noa, noa_len); 37488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } else 37498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_buf_add_noa(resp, 0, 0, 0, NULL, NULL); 37508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_buf_update_ie_hdr(resp, len); 37518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 37528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return resp; 37538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 37548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 37558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 37568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic void p2p_process_presence_req(struct p2p_data *p2p, const u8 *da, 37578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt const u8 *sa, const u8 *data, size_t len, 37588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt int rx_freq) 37598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 37608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct p2p_message msg; 37618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt u8 status; 37628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct wpabuf *resp; 37638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt size_t g; 37648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct p2p_group *group = NULL; 37658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt int parsed = 0; 37668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt u8 noa[50]; 37678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt int noa_len; 37688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 3769b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt p2p_dbg(p2p, "Received P2P Action - P2P Presence Request"); 37708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 37718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt for (g = 0; g < p2p->num_groups; g++) { 37728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (os_memcmp(da, p2p_group_get_interface_addr(p2p->groups[g]), 37738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ETH_ALEN) == 0) { 37748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt group = p2p->groups[g]; 37758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 37768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 37778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 37788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (group == NULL) { 3779b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt p2p_dbg(p2p, "Ignore P2P Presence Request for unknown group " 37808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt MACSTR, MAC2STR(da)); 37818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; 37828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 37838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 37848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (p2p_parse(data, len, &msg) < 0) { 3785b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt p2p_dbg(p2p, "Failed to parse P2P Presence Request"); 37868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt status = P2P_SC_FAIL_INVALID_PARAMS; 37878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt goto fail; 37888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 37898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt parsed = 1; 37908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 37918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (msg.noa == NULL) { 3792b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt p2p_dbg(p2p, "No NoA attribute in P2P Presence Request"); 37938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt status = P2P_SC_FAIL_INVALID_PARAMS; 37948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt goto fail; 37958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 37968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 37978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt status = p2p_group_presence_req(group, sa, msg.noa, msg.noa_len); 37988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 37998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtfail: 38008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (p2p->cfg->get_noa) 38018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt noa_len = p2p->cfg->get_noa(p2p->cfg->cb_ctx, da, noa, 38028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sizeof(noa)); 38038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt else 38048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt noa_len = -1; 38058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt resp = p2p_build_presence_resp(status, noa_len > 0 ? noa : NULL, 38068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt noa_len > 0 ? noa_len : 0, 38078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt msg.dialog_token); 38088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (parsed) 38098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_parse_free(&msg); 38108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (resp == NULL) 38118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; 38128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 38138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p->pending_action_state = P2P_NO_PENDING_ACTION; 38148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (p2p_send_action(p2p, rx_freq, sa, da, da, 38158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpabuf_head(resp), wpabuf_len(resp), 200) < 0) { 3816b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt p2p_dbg(p2p, "Failed to send Action frame"); 38178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 38188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpabuf_free(resp); 38198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 38208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 38218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 38228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic void p2p_process_presence_resp(struct p2p_data *p2p, const u8 *da, 38238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt const u8 *sa, const u8 *data, size_t len) 38248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 38258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct p2p_message msg; 38268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 3827b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt p2p_dbg(p2p, "Received P2P Action - P2P Presence Response"); 38288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 38298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (p2p_parse(data, len, &msg) < 0) { 3830b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt p2p_dbg(p2p, "Failed to parse P2P Presence Response"); 38318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; 38328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 38338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 38348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (msg.status == NULL || msg.noa == NULL) { 3835b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt p2p_dbg(p2p, "No Status or NoA attribute in P2P Presence Response"); 38368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_parse_free(&msg); 38378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; 38388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 38398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 38408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (*msg.status) { 3841b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt p2p_dbg(p2p, "P2P Presence Request was rejected: status %u", 38428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt *msg.status); 38438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_parse_free(&msg); 38448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; 38458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 38468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 3847b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt p2p_dbg(p2p, "P2P Presence Request was accepted"); 38488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_hexdump(MSG_DEBUG, "P2P: P2P Presence Response - NoA", 38498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt msg.noa, msg.noa_len); 38508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* TODO: process NoA */ 38518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_parse_free(&msg); 38528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 38538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 38548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 38558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic void p2p_ext_listen_timeout(void *eloop_ctx, void *timeout_ctx) 38568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 38578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct p2p_data *p2p = eloop_ctx; 38588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 38598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (p2p->ext_listen_interval) { 38608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* Schedule next extended listen timeout */ 38618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt eloop_register_timeout(p2p->ext_listen_interval_sec, 38628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p->ext_listen_interval_usec, 38638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_ext_listen_timeout, p2p, NULL); 38648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 38658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 38668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (p2p->state == P2P_LISTEN_ONLY && p2p->ext_listen_only) { 38678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* 38688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * This should not really happen, but it looks like the Listen 38698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * command may fail is something else (e.g., a scan) was 38708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * running at an inconvenient time. As a workaround, allow new 38718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * Extended Listen operation to be started. 38728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */ 3873b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt p2p_dbg(p2p, "Previous Extended Listen operation had not been completed - try again"); 38748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p->ext_listen_only = 0; 38758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_set_state(p2p, P2P_IDLE); 38768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 38778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 38788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (p2p->state != P2P_IDLE) { 3879b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt p2p_dbg(p2p, "Skip Extended Listen timeout in active state (%s)", p2p_state_txt(p2p->state)); 38808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; 38818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 38828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 3883b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt p2p_dbg(p2p, "Extended Listen timeout"); 38848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p->ext_listen_only = 1; 38858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (p2p_listen(p2p, p2p->ext_listen_period) < 0) { 3886b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt p2p_dbg(p2p, "Failed to start Listen state for Extended Listen Timing"); 38878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p->ext_listen_only = 0; 38888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 38898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 38908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 38918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 38928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtint p2p_ext_listen(struct p2p_data *p2p, unsigned int period, 38938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt unsigned int interval) 38948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 38958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (period > 65535 || interval > 65535 || period > interval || 38968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt (period == 0 && interval > 0) || (period > 0 && interval == 0)) { 3897b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt p2p_dbg(p2p, "Invalid Extended Listen Timing request: period=%u interval=%u", 3898b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt period, interval); 38998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 39008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 39018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 39028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt eloop_cancel_timeout(p2p_ext_listen_timeout, p2p, NULL); 39038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 39048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (interval == 0) { 3905b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt p2p_dbg(p2p, "Disabling Extended Listen Timing"); 39068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p->ext_listen_period = 0; 39078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p->ext_listen_interval = 0; 39088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 39098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 39108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 3911b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt p2p_dbg(p2p, "Enabling Extended Listen Timing: period %u msec, interval %u msec", 3912b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt period, interval); 39138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p->ext_listen_period = period; 39148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p->ext_listen_interval = interval; 39158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p->ext_listen_interval_sec = interval / 1000; 39168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p->ext_listen_interval_usec = (interval % 1000) * 1000; 39178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 39188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt eloop_register_timeout(p2p->ext_listen_interval_sec, 39198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p->ext_listen_interval_usec, 39208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_ext_listen_timeout, p2p, NULL); 39218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 39228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 39238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 39248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 39258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 39268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtvoid p2p_deauth_notif(struct p2p_data *p2p, const u8 *bssid, u16 reason_code, 39278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt const u8 *ie, size_t ie_len) 39288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 39298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct p2p_message msg; 39308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 39318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (bssid == NULL || ie == NULL) 39328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; 39338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 39348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memset(&msg, 0, sizeof(msg)); 39358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (p2p_parse_ies(ie, ie_len, &msg)) 39368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; 39378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (msg.minor_reason_code == NULL) 39388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; 39398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 3940b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt p2p_dbg(p2p, "Deauthentication notification BSSID " MACSTR 39418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt " reason_code=%u minor_reason_code=%u", 39428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt MAC2STR(bssid), reason_code, *msg.minor_reason_code); 39438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 39448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_parse_free(&msg); 39458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 39468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 39478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 39488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtvoid p2p_disassoc_notif(struct p2p_data *p2p, const u8 *bssid, u16 reason_code, 39498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt const u8 *ie, size_t ie_len) 39508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 39518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct p2p_message msg; 39528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 39538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (bssid == NULL || ie == NULL) 39548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; 39558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 39568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memset(&msg, 0, sizeof(msg)); 39578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (p2p_parse_ies(ie, ie_len, &msg)) 39588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; 39598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (msg.minor_reason_code == NULL) 39608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; 39618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 3962b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt p2p_dbg(p2p, "Disassociation notification BSSID " MACSTR 39638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt " reason_code=%u minor_reason_code=%u", 39648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt MAC2STR(bssid), reason_code, *msg.minor_reason_code); 39658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 39668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_parse_free(&msg); 39678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 39688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 39698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 39708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtvoid p2p_set_managed_oper(struct p2p_data *p2p, int enabled) 39718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 39728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (enabled) { 3973b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt p2p_dbg(p2p, "Managed P2P Device operations enabled"); 39748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p->dev_capab |= P2P_DEV_CAPAB_INFRA_MANAGED; 39758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } else { 3976b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt p2p_dbg(p2p, "Managed P2P Device operations disabled"); 39778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p->dev_capab &= ~P2P_DEV_CAPAB_INFRA_MANAGED; 39788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 39798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 39808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 39818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 39828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtint p2p_set_listen_channel(struct p2p_data *p2p, u8 reg_class, u8 channel) 39838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 39844b06059785b935dd1f4f09314e4e12c417d2c6a4Dmitry Shmidt if (p2p_channel_to_freq(reg_class, channel) < 0) 39858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 39868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 3987b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt p2p_dbg(p2p, "Set Listen channel: reg_class %u channel %u", 3988b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt reg_class, channel); 39898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p->cfg->reg_class = reg_class; 39908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p->cfg->channel = channel; 39918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 39928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 39938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 39948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 39958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 39968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtint p2p_set_ssid_postfix(struct p2p_data *p2p, const u8 *postfix, size_t len) 39978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 3998b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt p2p_dbg(p2p, "New SSID postfix: %s", wpa_ssid_txt(postfix, len)); 39998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (postfix == NULL) { 40008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p->cfg->ssid_postfix_len = 0; 40018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 40028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 40038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (len > sizeof(p2p->cfg->ssid_postfix)) 40048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 40058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memcpy(p2p->cfg->ssid_postfix, postfix, len); 40068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p->cfg->ssid_postfix_len = len; 40078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 40088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 40098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 40108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 401175ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinenint p2p_set_oper_channel(struct p2p_data *p2p, u8 op_reg_class, u8 op_channel, 401275ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen int cfg_op_channel) 401375ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen{ 40144b06059785b935dd1f4f09314e4e12c417d2c6a4Dmitry Shmidt if (p2p_channel_to_freq(op_reg_class, op_channel) < 0) 401575ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen return -1; 401675ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen 4017b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt p2p_dbg(p2p, "Set Operating channel: reg_class %u channel %u", 4018b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt op_reg_class, op_channel); 401975ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen p2p->cfg->op_reg_class = op_reg_class; 402075ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen p2p->cfg->op_channel = op_channel; 402175ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen p2p->cfg->cfg_op_channel = cfg_op_channel; 402275ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen return 0; 402375ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen} 402475ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen 402575ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen 402604949598a23f501be6eec21697465fd46a28840aDmitry Shmidtint p2p_set_pref_chan(struct p2p_data *p2p, unsigned int num_pref_chan, 402704949598a23f501be6eec21697465fd46a28840aDmitry Shmidt const struct p2p_channel *pref_chan) 402804949598a23f501be6eec21697465fd46a28840aDmitry Shmidt{ 402904949598a23f501be6eec21697465fd46a28840aDmitry Shmidt struct p2p_channel *n; 403004949598a23f501be6eec21697465fd46a28840aDmitry Shmidt 403104949598a23f501be6eec21697465fd46a28840aDmitry Shmidt if (pref_chan) { 403204949598a23f501be6eec21697465fd46a28840aDmitry Shmidt n = os_malloc(num_pref_chan * sizeof(struct p2p_channel)); 403304949598a23f501be6eec21697465fd46a28840aDmitry Shmidt if (n == NULL) 403404949598a23f501be6eec21697465fd46a28840aDmitry Shmidt return -1; 403504949598a23f501be6eec21697465fd46a28840aDmitry Shmidt os_memcpy(n, pref_chan, 403604949598a23f501be6eec21697465fd46a28840aDmitry Shmidt num_pref_chan * sizeof(struct p2p_channel)); 403704949598a23f501be6eec21697465fd46a28840aDmitry Shmidt } else 403804949598a23f501be6eec21697465fd46a28840aDmitry Shmidt n = NULL; 403904949598a23f501be6eec21697465fd46a28840aDmitry Shmidt 404004949598a23f501be6eec21697465fd46a28840aDmitry Shmidt os_free(p2p->cfg->pref_chan); 404104949598a23f501be6eec21697465fd46a28840aDmitry Shmidt p2p->cfg->pref_chan = n; 404204949598a23f501be6eec21697465fd46a28840aDmitry Shmidt p2p->cfg->num_pref_chan = num_pref_chan; 404304949598a23f501be6eec21697465fd46a28840aDmitry Shmidt 404404949598a23f501be6eec21697465fd46a28840aDmitry Shmidt return 0; 404504949598a23f501be6eec21697465fd46a28840aDmitry Shmidt} 404604949598a23f501be6eec21697465fd46a28840aDmitry Shmidt 404704949598a23f501be6eec21697465fd46a28840aDmitry Shmidt 40488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtint p2p_get_interface_addr(struct p2p_data *p2p, const u8 *dev_addr, 40498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt u8 *iface_addr) 40508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 40518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct p2p_device *dev = p2p_get_device(p2p, dev_addr); 40528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (dev == NULL || is_zero_ether_addr(dev->interface_addr)) 40538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 40548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memcpy(iface_addr, dev->interface_addr, ETH_ALEN); 40558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 40568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 40578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 40588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 40598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtint p2p_get_dev_addr(struct p2p_data *p2p, const u8 *iface_addr, 40608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt u8 *dev_addr) 40618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 40628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct p2p_device *dev = p2p_get_device_interface(p2p, iface_addr); 40638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (dev == NULL) 40648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 40658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memcpy(dev_addr, dev->info.p2p_device_addr, ETH_ALEN); 40668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 40678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 40688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 40698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 40708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtvoid p2p_set_peer_filter(struct p2p_data *p2p, const u8 *addr) 40718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 40728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memcpy(p2p->peer_filter, addr, ETH_ALEN); 40738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (is_zero_ether_addr(p2p->peer_filter)) 4074b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt p2p_dbg(p2p, "Disable peer filter"); 40758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt else 4076b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt p2p_dbg(p2p, "Enable peer filter for " MACSTR, 4077b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt MAC2STR(p2p->peer_filter)); 40788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 40798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 40808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 40818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtvoid p2p_set_cross_connect(struct p2p_data *p2p, int enabled) 40828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 4083b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt p2p_dbg(p2p, "Cross connection %s", enabled ? "enabled" : "disabled"); 40848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (p2p->cross_connect == enabled) 40858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; 40868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p->cross_connect = enabled; 40878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* TODO: may need to tear down any action group where we are GO(?) */ 40888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 40898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 40908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 40918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtint p2p_get_oper_freq(struct p2p_data *p2p, const u8 *iface_addr) 40928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 40938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct p2p_device *dev = p2p_get_device_interface(p2p, iface_addr); 40948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (dev == NULL) 40958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 40968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (dev->oper_freq <= 0) 40978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 40988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return dev->oper_freq; 40998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 41008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 41018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 41028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtvoid p2p_set_intra_bss_dist(struct p2p_data *p2p, int enabled) 41038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 4104b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt p2p_dbg(p2p, "Intra BSS distribution %s", 41058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt enabled ? "enabled" : "disabled"); 41068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p->cfg->p2p_intra_bss = enabled; 41078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 41088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 41098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 41108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtvoid p2p_update_channel_list(struct p2p_data *p2p, struct p2p_channels *chan) 41118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 4112b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt p2p_dbg(p2p, "Update channel list"); 41138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memcpy(&p2p->cfg->channels, chan, sizeof(struct p2p_channels)); 41148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 41158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 41168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 41178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtint p2p_send_action(struct p2p_data *p2p, unsigned int freq, const u8 *dst, 41188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt const u8 *src, const u8 *bssid, const u8 *buf, 41198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt size_t len, unsigned int wait_time) 41208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 41218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (p2p->p2p_scan_running) { 4122b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt p2p_dbg(p2p, "Delay Action frame TX until p2p_scan completes"); 41238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (p2p->after_scan_tx) { 4124b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt p2p_dbg(p2p, "Dropped previous pending Action frame TX"); 41258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_free(p2p->after_scan_tx); 41268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 41278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p->after_scan_tx = os_malloc(sizeof(*p2p->after_scan_tx) + 41288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt len); 41298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (p2p->after_scan_tx == NULL) 41308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 41318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p->after_scan_tx->freq = freq; 41328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memcpy(p2p->after_scan_tx->dst, dst, ETH_ALEN); 41338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memcpy(p2p->after_scan_tx->src, src, ETH_ALEN); 41348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memcpy(p2p->after_scan_tx->bssid, bssid, ETH_ALEN); 41358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p->after_scan_tx->len = len; 41368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p->after_scan_tx->wait_time = wait_time; 41378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memcpy(p2p->after_scan_tx + 1, buf, len); 41388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 41398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 41408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 41418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return p2p->cfg->send_action(p2p->cfg->cb_ctx, freq, dst, src, bssid, 41428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt buf, len, wait_time); 41438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 41448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 41458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 41468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtvoid p2p_set_best_channels(struct p2p_data *p2p, int freq_24, int freq_5, 41478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt int freq_overall) 41488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 4149b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt p2p_dbg(p2p, "Best channel: 2.4 GHz: %d, 5 GHz: %d, overall: %d", 4150b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt freq_24, freq_5, freq_overall); 41518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p->best_freq_24 = freq_24; 41528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p->best_freq_5 = freq_5; 41538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p->best_freq_overall = freq_overall; 41548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 41558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 41568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 4157700a137ab366edc72e371da68ba187b4717ee660Dmitry Shmidtvoid p2p_set_own_freq_preference(struct p2p_data *p2p, int freq) 4158700a137ab366edc72e371da68ba187b4717ee660Dmitry Shmidt{ 4159b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt p2p_dbg(p2p, "Own frequency preference: %d MHz", freq); 4160700a137ab366edc72e371da68ba187b4717ee660Dmitry Shmidt p2p->own_freq_preference = freq; 4161700a137ab366edc72e371da68ba187b4717ee660Dmitry Shmidt} 4162700a137ab366edc72e371da68ba187b4717ee660Dmitry Shmidt 4163700a137ab366edc72e371da68ba187b4717ee660Dmitry Shmidt 41648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtconst u8 * p2p_get_go_neg_peer(struct p2p_data *p2p) 41658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 41668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (p2p == NULL || p2p->go_neg_peer == NULL) 41678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return NULL; 41688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return p2p->go_neg_peer->info.p2p_device_addr; 41698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 41708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 41718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 41728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtconst struct p2p_peer_info * 41738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtp2p_get_peer_found(struct p2p_data *p2p, const u8 *addr, int next) 41748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 41758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct p2p_device *dev; 41768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 41778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (addr) { 41788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt dev = p2p_get_device(p2p, addr); 41798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (!dev) 41808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return NULL; 41818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 41828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (!next) { 41838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (dev->flags & P2P_DEV_PROBE_REQ_ONLY) 41848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return NULL; 41858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 41868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return &dev->info; 41878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } else { 41888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt do { 41898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt dev = dl_list_first(&dev->list, 41908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct p2p_device, 41918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt list); 41928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (&dev->list == &p2p->devices) 41938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return NULL; 41948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } while (dev->flags & P2P_DEV_PROBE_REQ_ONLY); 41958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 41968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } else { 41978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt dev = dl_list_first(&p2p->devices, struct p2p_device, list); 41988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (!dev) 41998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return NULL; 42008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt while (dev->flags & P2P_DEV_PROBE_REQ_ONLY) { 42018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt dev = dl_list_first(&dev->list, 42028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct p2p_device, 42038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt list); 42048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (&dev->list == &p2p->devices) 42058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return NULL; 42068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 42078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 42088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 42098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return &dev->info; 42108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 42111f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt 42121f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt#ifdef ANDROID_P2P 42131f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidtint p2p_search_in_progress(struct p2p_data *p2p) 42141f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt{ 42151f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt if (p2p == NULL) 42161f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt return 0; 42171f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt 42181f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt return p2p->state == P2P_SEARCH; 42191f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt} 42201f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt#endif 42211f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt 42221f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidtint p2p_in_progress(struct p2p_data *p2p) 42231f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt{ 42241f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt if (p2p == NULL) 42251f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt return 0; 422661d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt if (p2p->state == P2P_SEARCH || p2p->state == P2P_SEARCH_WHEN_READY || 422761d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt p2p->state == P2P_CONTINUE_SEARCH_WHEN_READY) 422861d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt return 2; 42291f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt return p2p->state != P2P_IDLE && p2p->state != P2P_PROVISIONING; 42301f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt} 423161d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt 423261d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt 423361d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidtvoid p2p_set_config_timeout(struct p2p_data *p2p, u8 go_timeout, 423461d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt u8 client_timeout) 423561d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt{ 423661d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt if (p2p) { 423761d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt p2p->go_timeout = go_timeout; 423861d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt p2p->client_timeout = client_timeout; 423961d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt } 424061d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt} 424161d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt 424261d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt 424361d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidtvoid p2p_increase_search_delay(struct p2p_data *p2p, unsigned int delay) 424461d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt{ 424561d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt if (p2p && p2p->search_delay < delay) 424661d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt p2p->search_delay = delay; 424761d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt} 424861d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt 424961d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt 425061d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt#ifdef CONFIG_WIFI_DISPLAY 425161d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt 425261d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidtstatic void p2p_update_wfd_ie_groups(struct p2p_data *p2p) 425361d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt{ 425461d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt size_t g; 425561d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt struct p2p_group *group; 425661d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt 425761d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt for (g = 0; g < p2p->num_groups; g++) { 425861d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt group = p2p->groups[g]; 425961d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt p2p_group_update_ies(group); 426061d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt } 426161d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt} 426261d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt 426361d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt 426461d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidtint p2p_set_wfd_ie_beacon(struct p2p_data *p2p, struct wpabuf *ie) 426561d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt{ 426661d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt wpabuf_free(p2p->wfd_ie_beacon); 426761d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt p2p->wfd_ie_beacon = ie; 426861d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt p2p_update_wfd_ie_groups(p2p); 426961d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt return 0; 427061d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt} 427161d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt 427261d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt 427361d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidtint p2p_set_wfd_ie_probe_req(struct p2p_data *p2p, struct wpabuf *ie) 427461d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt{ 427561d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt wpabuf_free(p2p->wfd_ie_probe_req); 427661d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt p2p->wfd_ie_probe_req = ie; 427761d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt return 0; 427861d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt} 427961d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt 428061d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt 428161d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidtint p2p_set_wfd_ie_probe_resp(struct p2p_data *p2p, struct wpabuf *ie) 428261d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt{ 428361d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt wpabuf_free(p2p->wfd_ie_probe_resp); 428461d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt p2p->wfd_ie_probe_resp = ie; 428561d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt p2p_update_wfd_ie_groups(p2p); 428661d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt return 0; 428761d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt} 428861d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt 428961d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt 429061d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidtint p2p_set_wfd_ie_assoc_req(struct p2p_data *p2p, struct wpabuf *ie) 429161d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt{ 429261d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt wpabuf_free(p2p->wfd_ie_assoc_req); 429361d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt p2p->wfd_ie_assoc_req = ie; 429461d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt return 0; 429561d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt} 429661d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt 429761d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt 429861d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidtint p2p_set_wfd_ie_invitation(struct p2p_data *p2p, struct wpabuf *ie) 429961d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt{ 430061d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt wpabuf_free(p2p->wfd_ie_invitation); 430161d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt p2p->wfd_ie_invitation = ie; 430261d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt return 0; 430361d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt} 430461d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt 430561d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt 430661d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidtint p2p_set_wfd_ie_prov_disc_req(struct p2p_data *p2p, struct wpabuf *ie) 430761d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt{ 430861d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt wpabuf_free(p2p->wfd_ie_prov_disc_req); 430961d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt p2p->wfd_ie_prov_disc_req = ie; 431061d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt return 0; 431161d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt} 431261d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt 431361d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt 431461d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidtint p2p_set_wfd_ie_prov_disc_resp(struct p2p_data *p2p, struct wpabuf *ie) 431561d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt{ 431661d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt wpabuf_free(p2p->wfd_ie_prov_disc_resp); 431761d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt p2p->wfd_ie_prov_disc_resp = ie; 431861d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt return 0; 431961d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt} 432061d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt 432161d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt 432261d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidtint p2p_set_wfd_ie_go_neg(struct p2p_data *p2p, struct wpabuf *ie) 432361d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt{ 432461d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt wpabuf_free(p2p->wfd_ie_go_neg); 432561d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt p2p->wfd_ie_go_neg = ie; 432661d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt return 0; 432761d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt} 432861d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt 432961d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt 433061d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidtint p2p_set_wfd_dev_info(struct p2p_data *p2p, const struct wpabuf *elem) 433161d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt{ 433261d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt wpabuf_free(p2p->wfd_dev_info); 433361d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt if (elem) { 433461d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt p2p->wfd_dev_info = wpabuf_dup(elem); 433561d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt if (p2p->wfd_dev_info == NULL) 433661d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt return -1; 433761d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt } else 433861d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt p2p->wfd_dev_info = NULL; 433961d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt 434061d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt return 0; 434161d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt} 434261d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt 434361d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt 434461d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidtint p2p_set_wfd_assoc_bssid(struct p2p_data *p2p, const struct wpabuf *elem) 434561d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt{ 434661d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt wpabuf_free(p2p->wfd_assoc_bssid); 434761d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt if (elem) { 434861d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt p2p->wfd_assoc_bssid = wpabuf_dup(elem); 434961d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt if (p2p->wfd_assoc_bssid == NULL) 435061d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt return -1; 435161d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt } else 435261d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt p2p->wfd_assoc_bssid = NULL; 435361d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt 435461d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt return 0; 435561d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt} 435661d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt 435761d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt 435861d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidtint p2p_set_wfd_coupled_sink_info(struct p2p_data *p2p, 435961d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt const struct wpabuf *elem) 436061d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt{ 436161d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt wpabuf_free(p2p->wfd_coupled_sink_info); 436261d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt if (elem) { 436361d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt p2p->wfd_coupled_sink_info = wpabuf_dup(elem); 436461d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt if (p2p->wfd_coupled_sink_info == NULL) 436561d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt return -1; 436661d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt } else 436761d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt p2p->wfd_coupled_sink_info = NULL; 436861d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt 436961d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt return 0; 437061d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt} 437161d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt 437261d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt#endif /* CONFIG_WIFI_DISPLAY */ 4373d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt 4374d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt 4375d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidtint p2p_set_disc_int(struct p2p_data *p2p, int min_disc_int, int max_disc_int, 4376d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt int max_disc_tu) 4377d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt{ 4378d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt if (min_disc_int > max_disc_int || min_disc_int < 0 || max_disc_int < 0) 4379d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt return -1; 4380d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt 4381d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt p2p->min_disc_int = min_disc_int; 4382d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt p2p->max_disc_int = max_disc_int; 4383d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt p2p->max_disc_tu = max_disc_tu; 4384b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt p2p_dbg(p2p, "Set discoverable interval: min=%d max=%d max_tu=%d", 4385b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt min_disc_int, max_disc_int, max_disc_tu); 4386d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt 4387d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt return 0; 4388d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt} 4389b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt 4390b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt 4391b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidtvoid p2p_dbg(struct p2p_data *p2p, const char *fmt, ...) 4392b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt{ 4393b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt va_list ap; 4394b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt char buf[500]; 4395b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt 4396b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt if (!p2p->cfg->debug_print) 4397b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt return; 4398b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt 4399b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt va_start(ap, fmt); 4400b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt vsnprintf(buf, sizeof(buf), fmt, ap); 4401b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt buf[sizeof(buf) - 1] = '\0'; 4402b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt va_end(ap); 4403b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt p2p->cfg->debug_print(p2p->cfg->cb_ctx, MSG_DEBUG, buf); 4404b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt} 4405b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt 4406b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt 4407b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidtvoid p2p_info(struct p2p_data *p2p, const char *fmt, ...) 4408b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt{ 4409b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt va_list ap; 4410b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt char buf[500]; 4411b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt 4412b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt if (!p2p->cfg->debug_print) 4413b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt return; 4414b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt 4415b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt va_start(ap, fmt); 4416b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt vsnprintf(buf, sizeof(buf), fmt, ap); 4417b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt buf[sizeof(buf) - 1] = '\0'; 4418b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt va_end(ap); 4419b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt p2p->cfg->debug_print(p2p->cfg->cb_ctx, MSG_INFO, buf); 4420b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt} 4421b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt 4422b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt 4423b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidtvoid p2p_err(struct p2p_data *p2p, const char *fmt, ...) 4424b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt{ 4425b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt va_list ap; 4426b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt char buf[500]; 4427b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt 4428b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt if (!p2p->cfg->debug_print) 4429b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt return; 4430b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt 4431b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt va_start(ap, fmt); 4432b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt vsnprintf(buf, sizeof(buf), fmt, ap); 4433b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt buf[sizeof(buf) - 1] = '\0'; 4434b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt va_end(ap); 4435b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt p2p->cfg->debug_print(p2p->cfg->cb_ctx, MSG_ERROR, buf); 4436b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt} 4437