18d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt/* 28d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * Wi-Fi Direct - P2P module 38d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * Copyright (c) 2009-2010, Atheros Communications 48d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * 5c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt * This software may be distributed under the terms of the BSD license. 6c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt * See README for more details. 78d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */ 88d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 98d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include "includes.h" 108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include "common.h" 128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include "eloop.h" 138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include "common/ieee802_11_defs.h" 148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include "common/ieee802_11_common.h" 15c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt#include "common/wpa_ctrl.h" 168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include "wps/wps_i.h" 178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include "p2p_i.h" 188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include "p2p.h" 198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic void p2p_state_timeout(void *eloop_ctx, void *timeout_ctx); 228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic void p2p_device_free(struct p2p_data *p2p, struct p2p_device *dev); 238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic void p2p_process_presence_req(struct p2p_data *p2p, const u8 *da, 248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt const u8 *sa, const u8 *data, size_t len, 258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt int rx_freq); 268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic void p2p_process_presence_resp(struct p2p_data *p2p, const u8 *da, 278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt const u8 *sa, const u8 *data, 288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt size_t len); 298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic void p2p_ext_listen_timeout(void *eloop_ctx, void *timeout_ctx); 308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic void p2p_scan_timeout(void *eloop_ctx, void *timeout_ctx); 318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt/* 348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * p2p_scan recovery timeout 358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * 368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * Many drivers are using 30 second timeout on scan results. Allow a bit larger 378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * timeout for this to avoid hitting P2P timeout unnecessarily. 388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */ 398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#define P2P_SCAN_TIMEOUT 35 408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt/** 428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * P2P_PEER_EXPIRATION_AGE - Number of seconds after which inactive peer 438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * entries will be removed 448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */ 452fb777c379ad560c309c54b96c2c13291da23f54Dmitry Shmidt#ifdef ANDROID_P2P 462fb777c379ad560c309c54b96c2c13291da23f54Dmitry Shmidt#define P2P_PEER_EXPIRATION_AGE 30 472fb777c379ad560c309c54b96c2c13291da23f54Dmitry Shmidt#else 488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#define P2P_PEER_EXPIRATION_AGE 300 492fb777c379ad560c309c54b96c2c13291da23f54Dmitry Shmidt#endif 508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#define P2P_PEER_EXPIRATION_INTERVAL (P2P_PEER_EXPIRATION_AGE / 2) 528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 532fb777c379ad560c309c54b96c2c13291da23f54Dmitry Shmidt#ifdef ANDROID_P2P 542fb777c379ad560c309c54b96c2c13291da23f54Dmitry Shmidtint p2p_connection_in_progress(struct p2p_data *p2p) 552fb777c379ad560c309c54b96c2c13291da23f54Dmitry Shmidt{ 562fb777c379ad560c309c54b96c2c13291da23f54Dmitry Shmidt int ret = 0; 572fb777c379ad560c309c54b96c2c13291da23f54Dmitry Shmidt 582fb777c379ad560c309c54b96c2c13291da23f54Dmitry Shmidt switch (p2p->state) { 592fb777c379ad560c309c54b96c2c13291da23f54Dmitry Shmidt case P2P_CONNECT: 602fb777c379ad560c309c54b96c2c13291da23f54Dmitry Shmidt case P2P_CONNECT_LISTEN: 612fb777c379ad560c309c54b96c2c13291da23f54Dmitry Shmidt case P2P_GO_NEG: 622fb777c379ad560c309c54b96c2c13291da23f54Dmitry Shmidt case P2P_WAIT_PEER_CONNECT: 6398f9e76624da6bb96edc1982c423e4a119c5170aDmitry Shmidt case P2P_WAIT_PEER_IDLE: 642fb777c379ad560c309c54b96c2c13291da23f54Dmitry Shmidt case P2P_PROVISIONING: 652fb777c379ad560c309c54b96c2c13291da23f54Dmitry Shmidt case P2P_INVITE: 662fb777c379ad560c309c54b96c2c13291da23f54Dmitry Shmidt case P2P_INVITE_LISTEN: 672fb777c379ad560c309c54b96c2c13291da23f54Dmitry Shmidt ret = 1; 682fb777c379ad560c309c54b96c2c13291da23f54Dmitry Shmidt break; 692fb777c379ad560c309c54b96c2c13291da23f54Dmitry Shmidt 702fb777c379ad560c309c54b96c2c13291da23f54Dmitry Shmidt default: 7198f9e76624da6bb96edc1982c423e4a119c5170aDmitry Shmidt wpa_printf(MSG_DEBUG, "p2p_connection_in_progress state %d", p2p->state); 722fb777c379ad560c309c54b96c2c13291da23f54Dmitry Shmidt ret = 0; 732fb777c379ad560c309c54b96c2c13291da23f54Dmitry Shmidt } 742fb777c379ad560c309c54b96c2c13291da23f54Dmitry Shmidt 752fb777c379ad560c309c54b96c2c13291da23f54Dmitry Shmidt return ret; 762fb777c379ad560c309c54b96c2c13291da23f54Dmitry Shmidt} 772fb777c379ad560c309c54b96c2c13291da23f54Dmitry Shmidt#endif 782fb777c379ad560c309c54b96c2c13291da23f54Dmitry Shmidt 798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic void p2p_expire_peers(struct p2p_data *p2p) 808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct p2p_device *dev, *n; 828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct os_time now; 83c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt size_t i; 848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_get_time(&now); 868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt dl_list_for_each_safe(dev, n, &p2p->devices, struct p2p_device, list) { 878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (dev->last_seen.sec + P2P_PEER_EXPIRATION_AGE >= now.sec) 888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt continue; 89c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt 90c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt if (p2p->cfg->go_connected && 91c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt p2p->cfg->go_connected(p2p->cfg->cb_ctx, 92c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt dev->info.p2p_device_addr)) { 93c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt /* 94c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt * We are connected as a client to a group in which the 95c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt * peer is the GO, so do not expire the peer entry. 96c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt */ 97c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt os_get_time(&dev->last_seen); 98c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt continue; 99c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt } 100c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt 101c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt for (i = 0; i < p2p->num_groups; i++) { 102c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt if (p2p_group_is_client_connected( 103c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt p2p->groups[i], dev->info.p2p_device_addr)) 104c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt break; 105c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt } 106c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt if (i < p2p->num_groups) { 107c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt /* 108c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt * The peer is connected as a client in a group where 109c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt * we are the GO, so do not expire the peer entry. 110c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt */ 111c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt os_get_time(&dev->last_seen); 112c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt continue; 113c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt } 114c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt 1152fb777c379ad560c309c54b96c2c13291da23f54Dmitry Shmidt#ifdef ANDROID_P2P 1162fb777c379ad560c309c54b96c2c13291da23f54Dmitry Shmidt /* If Connection is in progress, don't expire the peer 1172fb777c379ad560c309c54b96c2c13291da23f54Dmitry Shmidt */ 1182fb777c379ad560c309c54b96c2c13291da23f54Dmitry Shmidt if (p2p_connection_in_progress(p2p)) 1192fb777c379ad560c309c54b96c2c13291da23f54Dmitry Shmidt continue; 1202fb777c379ad560c309c54b96c2c13291da23f54Dmitry Shmidt#endif 1212fb777c379ad560c309c54b96c2c13291da23f54Dmitry Shmidt 12204949598a23f501be6eec21697465fd46a28840aDmitry Shmidt wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG, "P2P: Expiring old peer " 1238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "entry " MACSTR, MAC2STR(dev->info.p2p_device_addr)); 124f44b9c4a18d17fbd39901f76a014c32006570fb8Irfan Sheriff#ifdef ANDROID_P2P 125f44b9c4a18d17fbd39901f76a014c32006570fb8Irfan Sheriff /* SD_FAIR_POLICY: Update the current sd_dev_list pointer to next device */ 126f44b9c4a18d17fbd39901f76a014c32006570fb8Irfan Sheriff if(&dev->list == p2p->sd_dev_list) 127f44b9c4a18d17fbd39901f76a014c32006570fb8Irfan Sheriff p2p->sd_dev_list = dev->list.next; 128f44b9c4a18d17fbd39901f76a014c32006570fb8Irfan Sheriff#endif 1298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt dl_list_del(&dev->list); 1308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_device_free(p2p, dev); 1318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 1328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 1338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic void p2p_expiration_timeout(void *eloop_ctx, void *timeout_ctx) 1368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 1378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct p2p_data *p2p = eloop_ctx; 1388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_expire_peers(p2p); 1398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt eloop_register_timeout(P2P_PEER_EXPIRATION_INTERVAL, 0, 1408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_expiration_timeout, p2p, NULL); 1418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 1428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic const char * p2p_state_txt(int state) 1458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 1468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt switch (state) { 1478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case P2P_IDLE: 1488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return "IDLE"; 1498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case P2P_SEARCH: 1508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return "SEARCH"; 1518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case P2P_CONNECT: 1528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return "CONNECT"; 1538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case P2P_CONNECT_LISTEN: 1548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return "CONNECT_LISTEN"; 1558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case P2P_GO_NEG: 1568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return "GO_NEG"; 1578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case P2P_LISTEN_ONLY: 1588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return "LISTEN_ONLY"; 1598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case P2P_WAIT_PEER_CONNECT: 1608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return "WAIT_PEER_CONNECT"; 1618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case P2P_WAIT_PEER_IDLE: 1628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return "WAIT_PEER_IDLE"; 1638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case P2P_SD_DURING_FIND: 1648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return "SD_DURING_FIND"; 1658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case P2P_PROVISIONING: 1668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return "PROVISIONING"; 1678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case P2P_PD_DURING_FIND: 1688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return "PD_DURING_FIND"; 1698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case P2P_INVITE: 1708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return "INVITE"; 1718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case P2P_INVITE_LISTEN: 1728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return "INVITE_LISTEN"; 1731f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt case P2P_SEARCH_WHEN_READY: 1741f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt return "SEARCH_WHEN_READY"; 17561d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt case P2P_CONTINUE_SEARCH_WHEN_READY: 17661d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt return "CONTINUE_SEARCH_WHEN_READY"; 1778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt default: 1788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return "?"; 1798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 1808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 1818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1831f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidtu16 p2p_get_provisioning_info(struct p2p_data *p2p, const u8 *addr) 1841f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt{ 1851f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt struct p2p_device *dev = NULL; 1861f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt 1871f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt if (!addr || !p2p) 1881f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt return 0; 1891f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt 1901f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt dev = p2p_get_device(p2p, addr); 1911f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt if (dev) 1921f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt return dev->wps_prov_info; 1931f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt else 1941f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt return 0; 1951f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt} 1961f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt 1971f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt 19804949598a23f501be6eec21697465fd46a28840aDmitry Shmidtvoid p2p_clear_provisioning_info(struct p2p_data *p2p, const u8 *addr) 1991f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt{ 2001f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt struct p2p_device *dev = NULL; 2011f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt 20204949598a23f501be6eec21697465fd46a28840aDmitry Shmidt if (!addr || !p2p) 2031f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt return; 2041f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt 20504949598a23f501be6eec21697465fd46a28840aDmitry Shmidt dev = p2p_get_device(p2p, addr); 2061f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt if (dev) 2071f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt dev->wps_prov_info = 0; 2081f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt} 2091f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt 2101f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt 2118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtvoid p2p_set_state(struct p2p_data *p2p, int new_state) 2128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 2138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG, "P2P: State %s -> %s", 2148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_state_txt(p2p->state), p2p_state_txt(new_state)); 2158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p->state = new_state; 2168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 2178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtvoid p2p_set_timeout(struct p2p_data *p2p, unsigned int sec, unsigned int usec) 2208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 2218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG, 2228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "P2P: Set timeout (state=%s): %u.%06u sec", 2238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_state_txt(p2p->state), sec, usec); 2248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt eloop_cancel_timeout(p2p_state_timeout, p2p, NULL); 2258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt eloop_register_timeout(sec, usec, p2p_state_timeout, p2p, NULL); 2268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 2278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtvoid p2p_clear_timeout(struct p2p_data *p2p) 2308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 2318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG, "P2P: Clear timeout (state=%s)", 2328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_state_txt(p2p->state)); 2338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt eloop_cancel_timeout(p2p_state_timeout, p2p, NULL); 2348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 2358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtvoid p2p_go_neg_failed(struct p2p_data *p2p, struct p2p_device *peer, 2388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt int status) 2398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 2408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct p2p_go_neg_results res; 2418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_clear_timeout(p2p); 2428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_set_state(p2p, P2P_IDLE); 2431f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt if (p2p->go_neg_peer) 2441f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt p2p->go_neg_peer->wps_method = WPS_NOT_READY; 2458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p->go_neg_peer = NULL; 2468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memset(&res, 0, sizeof(res)); 2488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt res.status = status; 2498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (peer) { 2508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memcpy(res.peer_device_addr, peer->info.p2p_device_addr, 2518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ETH_ALEN); 2528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memcpy(res.peer_interface_addr, peer->intended_addr, 2538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ETH_ALEN); 2548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 2558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p->cfg->go_neg_completed(p2p->cfg->cb_ctx, &res); 2568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 2578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic void p2p_listen_in_find(struct p2p_data *p2p) 2608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 2618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt unsigned int r, tu; 2628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt int freq; 2638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct wpabuf *ies; 2648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG, 2668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "P2P: Starting short listen state (state=%s)", 2678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_state_txt(p2p->state)); 2688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt freq = p2p_channel_to_freq(p2p->cfg->country, p2p->cfg->reg_class, 2708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p->cfg->channel); 2718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (freq < 0) { 2728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG, 2738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "P2P: Unknown regulatory class/channel"); 2748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; 2758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 2768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_get_random((u8 *) &r, sizeof(r)); 2788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt tu = (r % ((p2p->max_disc_int - p2p->min_disc_int) + 1) + 2798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p->min_disc_int) * 100; 2808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p->pending_listen_freq = freq; 2828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p->pending_listen_sec = 0; 2838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p->pending_listen_usec = 1024 * tu; 2848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ies = p2p_build_probe_resp_ies(p2p); 2868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (ies == NULL) 2878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; 2888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (p2p->cfg->start_listen(p2p->cfg->cb_ctx, freq, 1024 * tu / 1000, 2908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ies) < 0) { 2918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG, 2928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "P2P: Failed to start listen mode"); 2938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p->pending_listen_freq = 0; 2948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 2958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpabuf_free(ies); 2968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 2978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtint p2p_listen(struct p2p_data *p2p, unsigned int timeout) 3008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 3018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt int freq; 3028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct wpabuf *ies; 3038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 3048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG, 3058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "P2P: Going to listen(only) state"); 3068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 3078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt freq = p2p_channel_to_freq(p2p->cfg->country, p2p->cfg->reg_class, 3088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p->cfg->channel); 3098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (freq < 0) { 3108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG, 3118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "P2P: Unknown regulatory class/channel"); 3128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 3138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 3148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 3158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p->pending_listen_freq = freq; 3168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p->pending_listen_sec = timeout / 1000; 3178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p->pending_listen_usec = (timeout % 1000) * 1000; 3188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 3198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (p2p->p2p_scan_running) { 32004949598a23f501be6eec21697465fd46a28840aDmitry Shmidt if (p2p->start_after_scan == P2P_AFTER_SCAN_CONNECT) { 3211f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG, 3221f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt "P2P: p2p_scan running - connect is already " 3231f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt "pending - skip listen"); 3241f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt return 0; 3251f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt } 3268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG, 3278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "P2P: p2p_scan running - delay start of listen state"); 3288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p->start_after_scan = P2P_AFTER_SCAN_LISTEN; 3298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 3308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 3318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 3328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ies = p2p_build_probe_resp_ies(p2p); 3338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (ies == NULL) 3348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 3358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 3368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (p2p->cfg->start_listen(p2p->cfg->cb_ctx, freq, timeout, ies) < 0) { 3378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG, 3388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "P2P: Failed to start listen mode"); 3398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p->pending_listen_freq = 0; 3408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpabuf_free(ies); 3418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 3428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 3438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpabuf_free(ies); 3448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 3458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_set_state(p2p, P2P_LISTEN_ONLY); 3468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 3478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 3488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 3498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 3508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 3518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic void p2p_device_clear_reported(struct p2p_data *p2p) 3528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 3538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct p2p_device *dev; 3548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt dl_list_for_each(dev, &p2p->devices, struct p2p_device, list) 3558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt dev->flags &= ~P2P_DEV_REPORTED; 3568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 3578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 3588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 3598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt/** 3608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * p2p_get_device - Fetch a peer entry 3618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @p2p: P2P module context from p2p_init() 3628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @addr: P2P Device Address of the peer 3638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * Returns: Pointer to the device entry or %NULL if not found 3648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */ 3658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstruct p2p_device * p2p_get_device(struct p2p_data *p2p, const u8 *addr) 3668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 3678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct p2p_device *dev; 3688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt dl_list_for_each(dev, &p2p->devices, struct p2p_device, list) { 3698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (os_memcmp(dev->info.p2p_device_addr, addr, ETH_ALEN) == 0) 3708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return dev; 3718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 3728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return NULL; 3738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 3748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 3758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 3768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt/** 3778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * p2p_get_device_interface - Fetch a peer entry based on P2P Interface Address 3788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @p2p: P2P module context from p2p_init() 3798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @addr: P2P Interface Address of the peer 3808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * Returns: Pointer to the device entry or %NULL if not found 3818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */ 3828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstruct p2p_device * p2p_get_device_interface(struct p2p_data *p2p, 3838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt const u8 *addr) 3848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 3858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct p2p_device *dev; 3868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt dl_list_for_each(dev, &p2p->devices, struct p2p_device, list) { 3878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (os_memcmp(dev->interface_addr, addr, ETH_ALEN) == 0) 3888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return dev; 3898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 3908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return NULL; 3918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 3928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 3938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 3948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt/** 3958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * p2p_create_device - Create a peer entry 3968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @p2p: P2P module context from p2p_init() 3978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @addr: P2P Device Address of the peer 3988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * Returns: Pointer to the device entry or %NULL on failure 3998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * 4008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * If there is already an entry for the peer, it will be returned instead of 4018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * creating a new one. 4028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */ 4038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic struct p2p_device * p2p_create_device(struct p2p_data *p2p, 4048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt const u8 *addr) 4058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 4068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct p2p_device *dev, *oldest = NULL; 4078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt size_t count = 0; 4088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 4098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt dev = p2p_get_device(p2p, addr); 4108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (dev) 4118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return dev; 4128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 4138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt dl_list_for_each(dev, &p2p->devices, struct p2p_device, list) { 4148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt count++; 4158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (oldest == NULL || 4168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_time_before(&dev->last_seen, &oldest->last_seen)) 4178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt oldest = dev; 4188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 4198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (count + 1 > p2p->cfg->max_peers && oldest) { 4208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG, 4218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "P2P: Remove oldest peer entry to make room for a new " 4228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "peer"); 423f44b9c4a18d17fbd39901f76a014c32006570fb8Irfan Sheriff#ifdef ANDROID_P2P 424f44b9c4a18d17fbd39901f76a014c32006570fb8Irfan Sheriff /* SD_FAIR_POLICY: Update the current sd_dev_list pointer to next device */ 425f44b9c4a18d17fbd39901f76a014c32006570fb8Irfan Sheriff if(&oldest->list == p2p->sd_dev_list) 426f44b9c4a18d17fbd39901f76a014c32006570fb8Irfan Sheriff p2p->sd_dev_list = oldest->list.next; 427f44b9c4a18d17fbd39901f76a014c32006570fb8Irfan Sheriff#endif 4288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt dl_list_del(&oldest->list); 4298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_device_free(p2p, oldest); 4308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 4318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 4328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt dev = os_zalloc(sizeof(*dev)); 4338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (dev == NULL) 4348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return NULL; 4358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt dl_list_add(&p2p->devices, &dev->list); 4368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memcpy(dev->info.p2p_device_addr, addr, ETH_ALEN); 4378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 4388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return dev; 4398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 4408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 4418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 4428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic void p2p_copy_client_info(struct p2p_device *dev, 4438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct p2p_client_info *cli) 4448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 4458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memcpy(dev->info.device_name, cli->dev_name, cli->dev_name_len); 4468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt dev->info.device_name[cli->dev_name_len] = '\0'; 4478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt dev->info.dev_capab = cli->dev_capab; 4488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt dev->info.config_methods = cli->config_methods; 4498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memcpy(dev->info.pri_dev_type, cli->pri_dev_type, 8); 4508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt dev->info.wps_sec_dev_type_list_len = 8 * cli->num_sec_dev_types; 4518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memcpy(dev->info.wps_sec_dev_type_list, cli->sec_dev_types, 4528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt dev->info.wps_sec_dev_type_list_len); 4538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 4548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 4558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 4568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic int p2p_add_group_clients(struct p2p_data *p2p, const u8 *go_dev_addr, 4578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt const u8 *go_interface_addr, int freq, 4588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt const u8 *gi, size_t gi_len) 4598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 4608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct p2p_group_info info; 4618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt size_t c; 4628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct p2p_device *dev; 4638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 4648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (gi == NULL) 4658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 4668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 4678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (p2p_group_info_parse(gi, gi_len, &info) < 0) 4688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 4698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 4708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* 4718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * Clear old data for this group; if the devices are still in the 4728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * group, the information will be restored in the loop following this. 4738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */ 4748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt dl_list_for_each(dev, &p2p->devices, struct p2p_device, list) { 4751f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt if (os_memcmp(dev->member_in_go_iface, go_interface_addr, 4768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ETH_ALEN) == 0) { 4778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memset(dev->member_in_go_iface, 0, ETH_ALEN); 4788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memset(dev->member_in_go_dev, 0, ETH_ALEN); 4798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 4808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 4818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 4828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt for (c = 0; c < info.num_clients; c++) { 4838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct p2p_client_info *cli = &info.client[c]; 4841f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt if (os_memcmp(cli->p2p_device_addr, p2p->cfg->dev_addr, 4851f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt ETH_ALEN) == 0) 4861f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt continue; /* ignore our own entry */ 4878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt dev = p2p_get_device(p2p, cli->p2p_device_addr); 4888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (dev) { 4898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (dev->flags & (P2P_DEV_GROUP_CLIENT_ONLY | 49004949598a23f501be6eec21697465fd46a28840aDmitry Shmidt P2P_DEV_PROBE_REQ_ONLY)) { 49104949598a23f501be6eec21697465fd46a28840aDmitry Shmidt /* 49204949598a23f501be6eec21697465fd46a28840aDmitry Shmidt * Update information since we have not 49304949598a23f501be6eec21697465fd46a28840aDmitry Shmidt * received this directly from the client. 49404949598a23f501be6eec21697465fd46a28840aDmitry Shmidt */ 4958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_copy_client_info(dev, cli); 49604949598a23f501be6eec21697465fd46a28840aDmitry Shmidt } else { 49704949598a23f501be6eec21697465fd46a28840aDmitry Shmidt /* 49804949598a23f501be6eec21697465fd46a28840aDmitry Shmidt * Need to update P2P Client Discoverability 49904949598a23f501be6eec21697465fd46a28840aDmitry Shmidt * flag since it is valid only in P2P Group 50004949598a23f501be6eec21697465fd46a28840aDmitry Shmidt * Info attribute. 50104949598a23f501be6eec21697465fd46a28840aDmitry Shmidt */ 50204949598a23f501be6eec21697465fd46a28840aDmitry Shmidt dev->info.dev_capab &= 50304949598a23f501be6eec21697465fd46a28840aDmitry Shmidt ~P2P_DEV_CAPAB_CLIENT_DISCOVERABILITY; 50404949598a23f501be6eec21697465fd46a28840aDmitry Shmidt dev->info.dev_capab |= 50504949598a23f501be6eec21697465fd46a28840aDmitry Shmidt cli->dev_capab & 50604949598a23f501be6eec21697465fd46a28840aDmitry Shmidt P2P_DEV_CAPAB_CLIENT_DISCOVERABILITY; 50704949598a23f501be6eec21697465fd46a28840aDmitry Shmidt } 5088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (dev->flags & P2P_DEV_PROBE_REQ_ONLY) { 5098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt dev->flags &= ~P2P_DEV_PROBE_REQ_ONLY; 5108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 5118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } else { 5128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt dev = p2p_create_device(p2p, cli->p2p_device_addr); 5138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (dev == NULL) 5148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt continue; 5158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt dev->flags |= P2P_DEV_GROUP_CLIENT_ONLY; 5168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_copy_client_info(dev, cli); 5178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt dev->oper_freq = freq; 5188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p->cfg->dev_found(p2p->cfg->cb_ctx, 5198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt dev->info.p2p_device_addr, 5208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt &dev->info, 1); 5218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt dev->flags |= P2P_DEV_REPORTED | P2P_DEV_REPORTED_ONCE; 5228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 5238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 5248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memcpy(dev->interface_addr, cli->p2p_interface_addr, 5258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ETH_ALEN); 5268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_get_time(&dev->last_seen); 5278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memcpy(dev->member_in_go_dev, go_dev_addr, ETH_ALEN); 5288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memcpy(dev->member_in_go_iface, go_interface_addr, 5298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ETH_ALEN); 5308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 5318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 5328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 5338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 5348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 5358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 5368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic void p2p_copy_wps_info(struct p2p_device *dev, int probe_req, 5378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt const struct p2p_message *msg) 5388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 5398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memcpy(dev->info.device_name, msg->device_name, 5408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sizeof(dev->info.device_name)); 5418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 5428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (msg->manufacturer && 5438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt msg->manufacturer_len < sizeof(dev->info.manufacturer)) { 5448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memset(dev->info.manufacturer, 0, 5458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sizeof(dev->info.manufacturer)); 5468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memcpy(dev->info.manufacturer, msg->manufacturer, 5478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt msg->manufacturer_len); 5488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 5498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 5508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (msg->model_name && 5518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt msg->model_name_len < sizeof(dev->info.model_name)) { 5528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memset(dev->info.model_name, 0, 5538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sizeof(dev->info.model_name)); 5548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memcpy(dev->info.model_name, msg->model_name, 5558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt msg->model_name_len); 5568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 5578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 5588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (msg->model_number && 5598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt msg->model_number_len < sizeof(dev->info.model_number)) { 5608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memset(dev->info.model_number, 0, 5618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sizeof(dev->info.model_number)); 5628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memcpy(dev->info.model_number, msg->model_number, 5638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt msg->model_number_len); 5648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 5658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 5668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (msg->serial_number && 5678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt msg->serial_number_len < sizeof(dev->info.serial_number)) { 5688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memset(dev->info.serial_number, 0, 5698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sizeof(dev->info.serial_number)); 5708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memcpy(dev->info.serial_number, msg->serial_number, 5718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt msg->serial_number_len); 5728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 5738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 5748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (msg->pri_dev_type) 5758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memcpy(dev->info.pri_dev_type, msg->pri_dev_type, 5768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sizeof(dev->info.pri_dev_type)); 5778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt else if (msg->wps_pri_dev_type) 5788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memcpy(dev->info.pri_dev_type, msg->wps_pri_dev_type, 5798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sizeof(dev->info.pri_dev_type)); 5808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 5818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (msg->wps_sec_dev_type_list) { 5828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memcpy(dev->info.wps_sec_dev_type_list, 5838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt msg->wps_sec_dev_type_list, 5848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt msg->wps_sec_dev_type_list_len); 5858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt dev->info.wps_sec_dev_type_list_len = 5868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt msg->wps_sec_dev_type_list_len; 5878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 5888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 5898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (msg->capability) { 59004949598a23f501be6eec21697465fd46a28840aDmitry Shmidt /* 59104949598a23f501be6eec21697465fd46a28840aDmitry Shmidt * P2P Client Discoverability bit is reserved in all frames 59204949598a23f501be6eec21697465fd46a28840aDmitry Shmidt * that use this function, so do not change its value here. 59304949598a23f501be6eec21697465fd46a28840aDmitry Shmidt */ 59404949598a23f501be6eec21697465fd46a28840aDmitry Shmidt dev->info.dev_capab &= P2P_DEV_CAPAB_CLIENT_DISCOVERABILITY; 59504949598a23f501be6eec21697465fd46a28840aDmitry Shmidt dev->info.dev_capab |= msg->capability[0] & 59604949598a23f501be6eec21697465fd46a28840aDmitry Shmidt ~P2P_DEV_CAPAB_CLIENT_DISCOVERABILITY; 5978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt dev->info.group_capab = msg->capability[1]; 5988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 5998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 6008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (msg->ext_listen_timing) { 6018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt dev->ext_listen_period = WPA_GET_LE16(msg->ext_listen_timing); 6028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt dev->ext_listen_interval = 6038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt WPA_GET_LE16(msg->ext_listen_timing + 2); 6048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 60504949598a23f501be6eec21697465fd46a28840aDmitry Shmidt 6068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (!probe_req) { 6078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt dev->info.config_methods = msg->config_methods ? 6088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt msg->config_methods : msg->wps_config_methods; 6098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 6108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 6118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 6128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 6138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt/** 61404949598a23f501be6eec21697465fd46a28840aDmitry Shmidt * p2p_add_device - Add peer entries based on scan results or P2P frames 6158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @p2p: P2P module context from p2p_init() 6168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @addr: Source address of Beacon or Probe Response frame (may be either 6178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * P2P Device Address or P2P Interface Address) 6188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @level: Signal level (signal strength of the received frame from the peer) 6198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @freq: Frequency on which the Beacon or Probe Response frame was received 6208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @ies: IEs from the Beacon or Probe Response frame 6218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @ies_len: Length of ies buffer in octets 62204949598a23f501be6eec21697465fd46a28840aDmitry Shmidt * @scan_res: Whether this was based on scan results 6238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * Returns: 0 on success, -1 on failure 6248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * 6258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * If the scan result is for a GO, the clients in the group will also be added 6268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * to the peer table. This function can also be used with some other frames 6278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * like Provision Discovery Request that contains P2P Capability and P2P Device 6288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * Info attributes. 6298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */ 6308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtint p2p_add_device(struct p2p_data *p2p, const u8 *addr, int freq, int level, 63104949598a23f501be6eec21697465fd46a28840aDmitry Shmidt const u8 *ies, size_t ies_len, int scan_res) 6328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 6338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct p2p_device *dev; 6348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct p2p_message msg; 6358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt const u8 *p2p_dev_addr; 6368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt int i; 6378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 6388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memset(&msg, 0, sizeof(msg)); 6398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (p2p_parse_ies(ies, ies_len, &msg)) { 6408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG, 6418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "P2P: Failed to parse P2P IE for a device entry"); 6428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_parse_free(&msg); 6438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 6448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 6458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 6468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (msg.p2p_device_addr) 6478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_dev_addr = msg.p2p_device_addr; 6488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt else if (msg.device_id) 6498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_dev_addr = msg.device_id; 6508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt else { 6518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG, 6528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "P2P: Ignore scan data without P2P Device Info or " 6538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "P2P Device Id"); 6548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_parse_free(&msg); 6558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 6568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 6578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 6588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (!is_zero_ether_addr(p2p->peer_filter) && 6598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memcmp(p2p_dev_addr, p2p->peer_filter, ETH_ALEN) != 0) { 6608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG, "P2P: Do not add peer " 6618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "filter for " MACSTR " due to peer filter", 6628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt MAC2STR(p2p_dev_addr)); 6638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 6648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 6658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 6668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt dev = p2p_create_device(p2p, p2p_dev_addr); 6678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (dev == NULL) { 6688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_parse_free(&msg); 6698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 6708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 6718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_get_time(&dev->last_seen); 6728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt dev->flags &= ~(P2P_DEV_PROBE_REQ_ONLY | P2P_DEV_GROUP_CLIENT_ONLY); 6738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 6748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (os_memcmp(addr, p2p_dev_addr, ETH_ALEN) != 0) 6758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memcpy(dev->interface_addr, addr, ETH_ALEN); 6768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (msg.ssid && 6778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt (msg.ssid[1] != P2P_WILDCARD_SSID_LEN || 6788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memcmp(msg.ssid + 2, P2P_WILDCARD_SSID, P2P_WILDCARD_SSID_LEN) 6798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt != 0)) { 6808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memcpy(dev->oper_ssid, msg.ssid + 2, msg.ssid[1]); 6818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt dev->oper_ssid_len = msg.ssid[1]; 6828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 6838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 6848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (freq >= 2412 && freq <= 2484 && msg.ds_params && 6858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt *msg.ds_params >= 1 && *msg.ds_params <= 14) { 6868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt int ds_freq; 6878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (*msg.ds_params == 14) 6888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ds_freq = 2484; 6898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt else 6908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ds_freq = 2407 + *msg.ds_params * 5; 6918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (freq != ds_freq) { 6928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG, 6938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "P2P: Update Listen frequency based on DS " 6948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "Parameter Set IE: %d -> %d MHz", 6958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt freq, ds_freq); 6968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt freq = ds_freq; 6978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 6988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 6998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 70004949598a23f501be6eec21697465fd46a28840aDmitry Shmidt if (dev->listen_freq && dev->listen_freq != freq && scan_res) { 7018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG, 7028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "P2P: Update Listen frequency based on scan " 7038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "results (" MACSTR " %d -> %d MHz (DS param %d)", 7048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt MAC2STR(dev->info.p2p_device_addr), dev->listen_freq, 7058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt freq, msg.ds_params ? *msg.ds_params : -1); 7068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 70704949598a23f501be6eec21697465fd46a28840aDmitry Shmidt if (scan_res) { 70804949598a23f501be6eec21697465fd46a28840aDmitry Shmidt dev->listen_freq = freq; 70904949598a23f501be6eec21697465fd46a28840aDmitry Shmidt if (msg.group_info) 71004949598a23f501be6eec21697465fd46a28840aDmitry Shmidt dev->oper_freq = freq; 71104949598a23f501be6eec21697465fd46a28840aDmitry Shmidt } 71275ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen dev->info.level = level; 7138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 7148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_copy_wps_info(dev, 0, &msg); 7158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 7168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt for (i = 0; i < P2P_MAX_WPS_VENDOR_EXT; i++) { 7178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpabuf_free(dev->info.wps_vendor_ext[i]); 7188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt dev->info.wps_vendor_ext[i] = NULL; 7198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 7208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 7218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt for (i = 0; i < P2P_MAX_WPS_VENDOR_EXT; i++) { 7228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (msg.wps_vendor_ext[i] == NULL) 7238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 7248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt dev->info.wps_vendor_ext[i] = wpabuf_alloc_copy( 7258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt msg.wps_vendor_ext[i], msg.wps_vendor_ext_len[i]); 7268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (dev->info.wps_vendor_ext[i] == NULL) 7278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 7288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 7298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 73061d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt if (msg.wfd_subelems) { 73161d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt wpabuf_free(dev->info.wfd_subelems); 73261d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt dev->info.wfd_subelems = wpabuf_dup(msg.wfd_subelems); 73361d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt } 73461d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt 73504949598a23f501be6eec21697465fd46a28840aDmitry Shmidt if (scan_res) { 73604949598a23f501be6eec21697465fd46a28840aDmitry Shmidt p2p_add_group_clients(p2p, p2p_dev_addr, addr, freq, 73704949598a23f501be6eec21697465fd46a28840aDmitry Shmidt msg.group_info, msg.group_info_len); 73804949598a23f501be6eec21697465fd46a28840aDmitry Shmidt } 7398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 7408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_parse_free(&msg); 7418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 7428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (p2p_pending_sd_req(p2p, dev)) 7438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt dev->flags |= P2P_DEV_SD_SCHEDULE; 7448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 7458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (dev->flags & P2P_DEV_REPORTED) 7468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 7478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 7488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG, 7498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "P2P: Peer found with Listen frequency %d MHz", freq); 7508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (dev->flags & P2P_DEV_USER_REJECTED) { 7518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG, 7528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "P2P: Do not report rejected device"); 7538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 7548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 7558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 7568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p->cfg->dev_found(p2p->cfg->cb_ctx, addr, &dev->info, 7578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt !(dev->flags & P2P_DEV_REPORTED_ONCE)); 7588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt dev->flags |= P2P_DEV_REPORTED | P2P_DEV_REPORTED_ONCE; 7598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 7608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 7618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 7628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 7638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 7648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic void p2p_device_free(struct p2p_data *p2p, struct p2p_device *dev) 7658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 7668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt int i; 7678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 768497c1d5e50162d6b3c1cce5dbd9c5fd9da69aaefDmitry Shmidt if (p2p->go_neg_peer == dev) { 7691f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt /* 7701f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt * If GO Negotiation is in progress, report that it has failed. 7711f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt */ 772497c1d5e50162d6b3c1cce5dbd9c5fd9da69aaefDmitry Shmidt p2p_go_neg_failed(p2p, dev, -1); 7738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p->go_neg_peer = NULL; 774497c1d5e50162d6b3c1cce5dbd9c5fd9da69aaefDmitry Shmidt } 7758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (p2p->invite_peer == dev) 7768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p->invite_peer = NULL; 7778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (p2p->sd_peer == dev) 7788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p->sd_peer = NULL; 7798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (p2p->pending_client_disc_go == dev) 7808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p->pending_client_disc_go = NULL; 7818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 782c55524ad84d13014e8019491c2b17e5dcf13545aDmitry Shmidt /* dev_lost() device, but only if it was previously dev_found() */ 783c55524ad84d13014e8019491c2b17e5dcf13545aDmitry Shmidt if (dev->flags & P2P_DEV_REPORTED_ONCE) 784c55524ad84d13014e8019491c2b17e5dcf13545aDmitry Shmidt p2p->cfg->dev_lost(p2p->cfg->cb_ctx, 785c55524ad84d13014e8019491c2b17e5dcf13545aDmitry Shmidt dev->info.p2p_device_addr); 7868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 7878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt for (i = 0; i < P2P_MAX_WPS_VENDOR_EXT; i++) { 7888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpabuf_free(dev->info.wps_vendor_ext[i]); 7898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt dev->info.wps_vendor_ext[i] = NULL; 7908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 7918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 79261d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt wpabuf_free(dev->info.wfd_subelems); 79361d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt 7948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_free(dev); 7958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 7968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 7978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 7988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic int p2p_get_next_prog_freq(struct p2p_data *p2p) 7998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 8008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct p2p_channels *c; 8018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct p2p_reg_class *cla; 8028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt size_t cl, ch; 8038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt int found = 0; 8048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt u8 reg_class; 8058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt u8 channel; 8068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt int freq; 8078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 8088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt c = &p2p->cfg->channels; 8098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt for (cl = 0; cl < c->reg_classes; cl++) { 8108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt cla = &c->reg_class[cl]; 8118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (cla->reg_class != p2p->last_prog_scan_class) 8128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt continue; 8138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt for (ch = 0; ch < cla->channels; ch++) { 8148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (cla->channel[ch] == p2p->last_prog_scan_chan) { 8158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt found = 1; 8168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 8178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 8188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 8198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (found) 8208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 8218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 8228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 8238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (!found) { 8248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* Start from beginning */ 8258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt reg_class = c->reg_class[0].reg_class; 8268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt channel = c->reg_class[0].channel[0]; 8278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } else { 8288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* Pick the next channel */ 8298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ch++; 8308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (ch == cla->channels) { 8318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt cl++; 8328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (cl == c->reg_classes) 8338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt cl = 0; 8348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ch = 0; 8358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 8368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt reg_class = c->reg_class[cl].reg_class; 8378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt channel = c->reg_class[cl].channel[ch]; 8388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 8398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 8408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt freq = p2p_channel_to_freq(p2p->cfg->country, reg_class, channel); 8418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG, "P2P: Next progressive search " 8428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "channel: reg_class %u channel %u -> %d MHz", 8438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt reg_class, channel, freq); 8448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p->last_prog_scan_class = reg_class; 8458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p->last_prog_scan_chan = channel; 8468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 8478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (freq == 2412 || freq == 2437 || freq == 2462) 8488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; /* No need to add social channels */ 8498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return freq; 8508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 8518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 8528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 8538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic void p2p_search(struct p2p_data *p2p) 8548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 8558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt int freq = 0; 8568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt enum p2p_scan_type type; 85704949598a23f501be6eec21697465fd46a28840aDmitry Shmidt u16 pw_id = DEV_PW_DEFAULT; 85861d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt int res; 8598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 8608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (p2p->drv_in_listen) { 8618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG, "P2P: Driver is still " 8628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "in Listen state - wait for it to end before " 8638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "continuing"); 8648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; 8658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 8668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p->cfg->stop_listen(p2p->cfg->cb_ctx); 8678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 86804949598a23f501be6eec21697465fd46a28840aDmitry Shmidt if (p2p->find_type == P2P_FIND_PROGRESSIVE && 86904949598a23f501be6eec21697465fd46a28840aDmitry Shmidt (freq = p2p_get_next_prog_freq(p2p)) > 0) { 8708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt type = P2P_SCAN_SOCIAL_PLUS_ONE; 8718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG, "P2P: Starting search " 8728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "(+ freq %u)", freq); 8738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } else { 8748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt type = P2P_SCAN_SOCIAL; 8758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG, "P2P: Starting search"); 8768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 8778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 87861d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt res = p2p->cfg->p2p_scan(p2p->cfg->cb_ctx, type, freq, 87961d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt p2p->num_req_dev_types, p2p->req_dev_types, 88061d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt p2p->find_dev_id, pw_id); 88161d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt if (res < 0) { 8828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG, 8838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "P2P: Scan request failed"); 8848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_continue_find(p2p); 88561d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt } else if (res == 1) { 88661d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG, "P2P: Could not start " 88761d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt "p2p_scan at this point - will try again after " 88861d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt "previous scan completes"); 88961d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt p2p_set_state(p2p, P2P_CONTINUE_SEARCH_WHEN_READY); 8908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } else { 8918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG, "P2P: Running p2p_scan"); 8928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p->p2p_scan_running = 1; 8938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt eloop_cancel_timeout(p2p_scan_timeout, p2p, NULL); 8948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt eloop_register_timeout(P2P_SCAN_TIMEOUT, 0, p2p_scan_timeout, 8958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p, NULL); 8968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 8978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 8988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 8998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 9008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic void p2p_find_timeout(void *eloop_ctx, void *timeout_ctx) 9018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 9028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct p2p_data *p2p = eloop_ctx; 9038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG, "P2P: Find timeout -> stop"); 9048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_stop_find(p2p); 9058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 9068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 9078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 9088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic int p2p_run_after_scan(struct p2p_data *p2p) 9098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 9108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct p2p_device *dev; 9118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt enum p2p_after_scan op; 9128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 9138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (p2p->after_scan_tx) { 9148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* TODO: schedule p2p_run_after_scan to be called from TX 9158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * status callback(?) */ 9168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG, "P2P: Send pending " 9178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "Action frame at p2p_scan completion"); 9181f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt p2p->cfg->send_action(p2p->cfg->cb_ctx, 9191f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt p2p->after_scan_tx->freq, 9201f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt p2p->after_scan_tx->dst, 9211f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt p2p->after_scan_tx->src, 9221f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt p2p->after_scan_tx->bssid, 9231f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt (u8 *) (p2p->after_scan_tx + 1), 9241f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt p2p->after_scan_tx->len, 9251f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt p2p->after_scan_tx->wait_time); 9268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_free(p2p->after_scan_tx); 9278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p->after_scan_tx = NULL; 928f44b9c4a18d17fbd39901f76a014c32006570fb8Irfan Sheriff#ifdef ANDROID_P2P 929f44b9c4a18d17fbd39901f76a014c32006570fb8Irfan Sheriff /* For SD frames, there is a scenario, where we can receive a SD request frame during p2p_scan. 930f44b9c4a18d17fbd39901f76a014c32006570fb8Irfan Sheriff * At that moment, we will send the SD response from this context. After sending the SD response, 931f44b9c4a18d17fbd39901f76a014c32006570fb8Irfan Sheriff * we need to continue p2p_find. But if we return 1 from here, p2p_find is going to be stopped. 932f44b9c4a18d17fbd39901f76a014c32006570fb8Irfan Sheriff */ 933f44b9c4a18d17fbd39901f76a014c32006570fb8Irfan Sheriff return 0; 934f44b9c4a18d17fbd39901f76a014c32006570fb8Irfan Sheriff#else 9358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 1; 936f44b9c4a18d17fbd39901f76a014c32006570fb8Irfan Sheriff#endif 9378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 9388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 9398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt op = p2p->start_after_scan; 9408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p->start_after_scan = P2P_AFTER_SCAN_NOTHING; 9418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt switch (op) { 9428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case P2P_AFTER_SCAN_NOTHING: 9438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 9448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case P2P_AFTER_SCAN_LISTEN: 9458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG, "P2P: Start previously " 9468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "requested Listen state"); 9478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_listen(p2p, p2p->pending_listen_sec * 1000 + 9488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p->pending_listen_usec / 1000); 9498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 1; 9508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case P2P_AFTER_SCAN_CONNECT: 9518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG, "P2P: Start previously " 9528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "requested connect with " MACSTR, 9538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt MAC2STR(p2p->after_scan_peer)); 9548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt dev = p2p_get_device(p2p, p2p->after_scan_peer); 9558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (dev == NULL) { 9568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG, "P2P: Peer not " 9578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "known anymore"); 9588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 9598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 9608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_connect_send(p2p, dev); 9618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 1; 9628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 9638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 9648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 9658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 9668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 9678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 9688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic void p2p_scan_timeout(void *eloop_ctx, void *timeout_ctx) 9698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 9708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct p2p_data *p2p = eloop_ctx; 9718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt int running; 9728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG, "P2P: p2p_scan timeout " 9738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "(running=%d)", p2p->p2p_scan_running); 9748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt running = p2p->p2p_scan_running; 9758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* Make sure we recover from missed scan results callback */ 9768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p->p2p_scan_running = 0; 9778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 9788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (running) 9798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_run_after_scan(p2p); 9808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 9818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 9828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 9838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic void p2p_free_req_dev_types(struct p2p_data *p2p) 9848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 9858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p->num_req_dev_types = 0; 9868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_free(p2p->req_dev_types); 9878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p->req_dev_types = NULL; 9888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 9898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 9908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 9918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtint p2p_find(struct p2p_data *p2p, unsigned int timeout, 9928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt enum p2p_discovery_type type, 993c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt unsigned int num_req_dev_types, const u8 *req_dev_types, 99461d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt const u8 *dev_id, unsigned int search_delay) 9958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 9968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt int res; 9978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 9988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG, "P2P: Starting find (type=%d)", 9998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt type); 10008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (p2p->p2p_scan_running) { 10018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG, "P2P: p2p_scan is " 10028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "already running"); 10038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 10048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 10058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_free_req_dev_types(p2p); 10068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (req_dev_types && num_req_dev_types) { 10078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p->req_dev_types = os_malloc(num_req_dev_types * 10088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt WPS_DEV_TYPE_LEN); 10098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (p2p->req_dev_types == NULL) 10108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 10118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memcpy(p2p->req_dev_types, req_dev_types, 10128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt num_req_dev_types * WPS_DEV_TYPE_LEN); 10138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p->num_req_dev_types = num_req_dev_types; 10148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 10158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1016c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt if (dev_id) { 1017c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt os_memcpy(p2p->find_dev_id_buf, dev_id, ETH_ALEN); 1018c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt p2p->find_dev_id = p2p->find_dev_id_buf; 1019c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt } else 1020c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt p2p->find_dev_id = NULL; 1021c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt 10228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p->start_after_scan = P2P_AFTER_SCAN_NOTHING; 10238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_clear_timeout(p2p); 10248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p->cfg->stop_listen(p2p->cfg->cb_ctx); 10258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p->find_type = type; 10268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_device_clear_reported(p2p); 10278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_set_state(p2p, P2P_SEARCH); 102861d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt p2p->search_delay = search_delay; 102961d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt p2p->in_search_delay = 0; 10308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt eloop_cancel_timeout(p2p_find_timeout, p2p, NULL); 10311f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt p2p->last_p2p_find_timeout = timeout; 10328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (timeout) 10338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt eloop_register_timeout(timeout, 0, p2p_find_timeout, 10348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p, NULL); 10358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt switch (type) { 10368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case P2P_FIND_START_WITH_FULL: 10378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case P2P_FIND_PROGRESSIVE: 10388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt res = p2p->cfg->p2p_scan(p2p->cfg->cb_ctx, P2P_SCAN_FULL, 0, 10398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p->num_req_dev_types, 104004949598a23f501be6eec21697465fd46a28840aDmitry Shmidt p2p->req_dev_types, dev_id, 104104949598a23f501be6eec21697465fd46a28840aDmitry Shmidt DEV_PW_DEFAULT); 10428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 10438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case P2P_FIND_ONLY_SOCIAL: 10448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt res = p2p->cfg->p2p_scan(p2p->cfg->cb_ctx, P2P_SCAN_SOCIAL, 0, 10458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p->num_req_dev_types, 104604949598a23f501be6eec21697465fd46a28840aDmitry Shmidt p2p->req_dev_types, dev_id, 104704949598a23f501be6eec21697465fd46a28840aDmitry Shmidt DEV_PW_DEFAULT); 10488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 10498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt default: 10508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 10518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 10528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 10538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (res == 0) { 10548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG, "P2P: Running p2p_scan"); 10558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p->p2p_scan_running = 1; 10568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt eloop_cancel_timeout(p2p_scan_timeout, p2p, NULL); 10578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt eloop_register_timeout(P2P_SCAN_TIMEOUT, 0, p2p_scan_timeout, 10588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p, NULL); 10591f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt } else if (res == 1) { 10601f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG, "P2P: Could not start " 10611f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt "p2p_scan at this point - will try again after " 10621f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt "previous scan completes"); 10631f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt res = 0; 10641f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt p2p_set_state(p2p, P2P_SEARCH_WHEN_READY); 10651f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt eloop_cancel_timeout(p2p_find_timeout, p2p, NULL); 10668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } else { 10678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG, "P2P: Failed to start " 10688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "p2p_scan"); 10691f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt p2p_set_state(p2p, P2P_IDLE); 10701f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt eloop_cancel_timeout(p2p_find_timeout, p2p, NULL); 10718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 10728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 10738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return res; 10748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 10758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 10762fb777c379ad560c309c54b96c2c13291da23f54Dmitry Shmidt#ifdef ANDROID_P2P 10772fb777c379ad560c309c54b96c2c13291da23f54Dmitry Shmidtint p2p_search_pending(struct p2p_data *p2p) 10782fb777c379ad560c309c54b96c2c13291da23f54Dmitry Shmidt{ 10792fb777c379ad560c309c54b96c2c13291da23f54Dmitry Shmidt if(p2p == NULL) 10802fb777c379ad560c309c54b96c2c13291da23f54Dmitry Shmidt return 0; 10812fb777c379ad560c309c54b96c2c13291da23f54Dmitry Shmidt 10822fb777c379ad560c309c54b96c2c13291da23f54Dmitry Shmidt if(p2p->state == P2P_SEARCH_WHEN_READY) 10832fb777c379ad560c309c54b96c2c13291da23f54Dmitry Shmidt return 1; 10842fb777c379ad560c309c54b96c2c13291da23f54Dmitry Shmidt 10852fb777c379ad560c309c54b96c2c13291da23f54Dmitry Shmidt return 0; 10862fb777c379ad560c309c54b96c2c13291da23f54Dmitry Shmidt} 10872fb777c379ad560c309c54b96c2c13291da23f54Dmitry Shmidt#endif 10888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 10891f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidtint p2p_other_scan_completed(struct p2p_data *p2p) 10901f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt{ 109161d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt if (p2p->state == P2P_CONTINUE_SEARCH_WHEN_READY) { 109261d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt p2p_set_state(p2p, P2P_SEARCH); 109361d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt p2p_search(p2p); 109461d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt return 1; 109561d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt } 10961f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt if (p2p->state != P2P_SEARCH_WHEN_READY) 10971f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt return 0; 10981f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG, "P2P: Starting pending P2P find " 10991f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt "now that previous scan was completed"); 11001f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt if (p2p_find(p2p, p2p->last_p2p_find_timeout, p2p->find_type, 1101c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt p2p->num_req_dev_types, p2p->req_dev_types, 110261d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt p2p->find_dev_id, p2p->search_delay) < 0) 11031f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt return 0; 11041f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt return 1; 11051f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt} 11061f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt 11071f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt 11088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtvoid p2p_stop_find_for_freq(struct p2p_data *p2p, int freq) 11098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 11108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG, "P2P: Stopping find"); 11118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt eloop_cancel_timeout(p2p_find_timeout, p2p, NULL); 11128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_clear_timeout(p2p); 1113c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt if (p2p->state == P2P_SEARCH) 1114c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt wpa_msg(p2p->cfg->msg_ctx, MSG_INFO, P2P_EVENT_FIND_STOPPED); 11158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_set_state(p2p, P2P_IDLE); 11168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_free_req_dev_types(p2p); 11178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p->start_after_scan = P2P_AFTER_SCAN_NOTHING; 11188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p->go_neg_peer = NULL; 11198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p->sd_peer = NULL; 11208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p->invite_peer = NULL; 112104949598a23f501be6eec21697465fd46a28840aDmitry Shmidt p2p_stop_listen_for_freq(p2p, freq); 112204949598a23f501be6eec21697465fd46a28840aDmitry Shmidt} 112304949598a23f501be6eec21697465fd46a28840aDmitry Shmidt 112404949598a23f501be6eec21697465fd46a28840aDmitry Shmidt 112504949598a23f501be6eec21697465fd46a28840aDmitry Shmidtvoid p2p_stop_listen_for_freq(struct p2p_data *p2p, int freq) 112604949598a23f501be6eec21697465fd46a28840aDmitry Shmidt{ 11278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (freq > 0 && p2p->drv_in_listen == freq && p2p->in_listen) { 11288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG, "P2P: Skip stop_listen " 11298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "since we are on correct channel for response"); 11308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; 11318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 113204949598a23f501be6eec21697465fd46a28840aDmitry Shmidt if (p2p->in_listen) { 113304949598a23f501be6eec21697465fd46a28840aDmitry Shmidt p2p->in_listen = 0; 113404949598a23f501be6eec21697465fd46a28840aDmitry Shmidt p2p_clear_timeout(p2p); 113504949598a23f501be6eec21697465fd46a28840aDmitry Shmidt } 11361f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt if (p2p->drv_in_listen) { 11371f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt /* 11381f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt * The driver may not deliver callback to p2p_listen_end() 11391f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt * when the operation gets canceled, so clear the internal 11401f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt * variable that is tracking driver state. 11411f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt */ 11421f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG, "P2P: Clear " 11431f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt "drv_in_listen (%d)", p2p->drv_in_listen); 11441f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt p2p->drv_in_listen = 0; 11451f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt } 11468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p->cfg->stop_listen(p2p->cfg->cb_ctx); 11478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 11488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 11498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 11508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtvoid p2p_stop_find(struct p2p_data *p2p) 11518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 11528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_stop_find_for_freq(p2p, 0); 11538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 11548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 11558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 11568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic int p2p_prepare_channel(struct p2p_data *p2p, unsigned int force_freq) 11578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 11588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (force_freq) { 11598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt u8 op_reg_class, op_channel; 11608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (p2p_freq_to_channel(p2p->cfg->country, force_freq, 11618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt &op_reg_class, &op_channel) < 0) { 11628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG, 11638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "P2P: Unsupported frequency %u MHz", 11648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt force_freq); 11658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 11668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 11678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (!p2p_channels_includes(&p2p->cfg->channels, op_reg_class, 11688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt op_channel)) { 11698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG, 11708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "P2P: Frequency %u MHz (oper_class %u " 11718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "channel %u) not allowed for P2P", 11728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt force_freq, op_reg_class, op_channel); 11738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 11748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 11758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p->op_reg_class = op_reg_class; 11768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p->op_channel = op_channel; 117704abaa93653bcee36d59576c90f283d4efdb0a64Dmitry Shmidt#ifndef ANDROID_P2P 11788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p->channels.reg_classes = 1; 11798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p->channels.reg_class[0].channels = 1; 11808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p->channels.reg_class[0].reg_class = p2p->op_reg_class; 11818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p->channels.reg_class[0].channel[0] = p2p->op_channel; 118204abaa93653bcee36d59576c90f283d4efdb0a64Dmitry Shmidt#else 118304abaa93653bcee36d59576c90f283d4efdb0a64Dmitry Shmidt if(p2p->cfg->p2p_concurrency == P2P_MULTI_CHANNEL_CONCURRENT) { 118404abaa93653bcee36d59576c90f283d4efdb0a64Dmitry Shmidt /* We we are requesting for a preferred channel. But since 118504abaa93653bcee36d59576c90f283d4efdb0a64Dmitry Shmidt * are multichannel concurrent, we have to poplulate the 118604abaa93653bcee36d59576c90f283d4efdb0a64Dmitry Shmidt * p2p_channels with list of channels that we support. 118704abaa93653bcee36d59576c90f283d4efdb0a64Dmitry Shmidt */ 1188069fa2c39ec7120656a2ea8cca83c5ee41ddab60Irfan Sheriff#ifdef ANDROID_P2P 1189069fa2c39ec7120656a2ea8cca83c5ee41ddab60Irfan Sheriff wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG, "Full channel list"); 1190069fa2c39ec7120656a2ea8cca83c5ee41ddab60Irfan Sheriff#endif 119104abaa93653bcee36d59576c90f283d4efdb0a64Dmitry Shmidt os_memcpy(&p2p->channels, &p2p->cfg->channels, 119204abaa93653bcee36d59576c90f283d4efdb0a64Dmitry Shmidt sizeof(struct p2p_channels)); 119304abaa93653bcee36d59576c90f283d4efdb0a64Dmitry Shmidt } else { 1194069fa2c39ec7120656a2ea8cca83c5ee41ddab60Irfan Sheriff#ifdef ANDROID_P2P 1195069fa2c39ec7120656a2ea8cca83c5ee41ddab60Irfan Sheriff wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG, "Single channel list %d", p2p->op_channel); 1196069fa2c39ec7120656a2ea8cca83c5ee41ddab60Irfan Sheriff#endif 119704abaa93653bcee36d59576c90f283d4efdb0a64Dmitry Shmidt p2p->channels.reg_classes = 1; 119804abaa93653bcee36d59576c90f283d4efdb0a64Dmitry Shmidt p2p->channels.reg_class[0].channels = 1; 119904abaa93653bcee36d59576c90f283d4efdb0a64Dmitry Shmidt p2p->channels.reg_class[0].reg_class = p2p->op_reg_class; 120004abaa93653bcee36d59576c90f283d4efdb0a64Dmitry Shmidt p2p->channels.reg_class[0].channel[0] = p2p->op_channel; 120104abaa93653bcee36d59576c90f283d4efdb0a64Dmitry Shmidt } 120204abaa93653bcee36d59576c90f283d4efdb0a64Dmitry Shmidt#endif 12038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } else { 12048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt u8 op_reg_class, op_channel; 12058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 12068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (!p2p->cfg->cfg_op_channel && p2p->best_freq_overall > 0 && 12078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_supported_freq(p2p, p2p->best_freq_overall) && 12088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_freq_to_channel(p2p->cfg->country, 12098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p->best_freq_overall, 12108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt &op_reg_class, &op_channel) == 0) { 12118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG, 12128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "P2P: Select best overall channel as " 12138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "operating channel preference"); 12148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p->op_reg_class = op_reg_class; 12158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p->op_channel = op_channel; 12168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } else if (!p2p->cfg->cfg_op_channel && p2p->best_freq_5 > 0 && 12178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_supported_freq(p2p, p2p->best_freq_5) && 12188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_freq_to_channel(p2p->cfg->country, 12198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p->best_freq_5, 12208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt &op_reg_class, &op_channel) == 12218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 0) { 12228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG, 12238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "P2P: Select best 5 GHz channel as " 12248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "operating channel preference"); 12258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p->op_reg_class = op_reg_class; 12268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p->op_channel = op_channel; 12278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } else if (!p2p->cfg->cfg_op_channel && 12288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p->best_freq_24 > 0 && 12298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_supported_freq(p2p, p2p->best_freq_24) && 12308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_freq_to_channel(p2p->cfg->country, 12318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p->best_freq_24, 12328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt &op_reg_class, &op_channel) == 12338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 0) { 12348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG, 12358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "P2P: Select best 2.4 GHz channel as " 12368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "operating channel preference"); 12378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p->op_reg_class = op_reg_class; 12388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p->op_channel = op_channel; 12398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } else { 12408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p->op_reg_class = p2p->cfg->op_reg_class; 12418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p->op_channel = p2p->cfg->op_channel; 12428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 12438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 12448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memcpy(&p2p->channels, &p2p->cfg->channels, 12458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sizeof(struct p2p_channels)); 12468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 12478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG, 12488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "P2P: Own preference for operation channel: " 12498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "Operating Class %u Channel %u%s", 12508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p->op_reg_class, p2p->op_channel, 12518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt force_freq ? " (forced)" : ""); 12528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 12538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 12548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 12558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 12568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 12571f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidtstatic void p2p_set_dev_persistent(struct p2p_device *dev, 12581f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt int persistent_group) 12591f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt{ 12601f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt switch (persistent_group) { 12611f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt case 0: 12621f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt dev->flags &= ~(P2P_DEV_PREFER_PERSISTENT_GROUP | 12631f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt P2P_DEV_PREFER_PERSISTENT_RECONN); 12641f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt break; 12651f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt case 1: 12661f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt dev->flags |= P2P_DEV_PREFER_PERSISTENT_GROUP; 12671f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt dev->flags &= ~P2P_DEV_PREFER_PERSISTENT_RECONN; 12681f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt break; 12691f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt case 2: 12701f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt dev->flags |= P2P_DEV_PREFER_PERSISTENT_GROUP | 12711f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt P2P_DEV_PREFER_PERSISTENT_RECONN; 12721f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt break; 12731f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt } 12741f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt} 12751f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt 12761f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt 12778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtint p2p_connect(struct p2p_data *p2p, const u8 *peer_addr, 12788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt enum p2p_wps_method wps_method, 12798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt int go_intent, const u8 *own_interface_addr, 128004949598a23f501be6eec21697465fd46a28840aDmitry Shmidt unsigned int force_freq, int persistent_group, 128104949598a23f501be6eec21697465fd46a28840aDmitry Shmidt const u8 *force_ssid, size_t force_ssid_len, 128204949598a23f501be6eec21697465fd46a28840aDmitry Shmidt int pd_before_go_neg) 12838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 12848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct p2p_device *dev; 12858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 12868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG, 12878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "P2P: Request to start group negotiation - peer=" MACSTR 12888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt " GO Intent=%d Intended Interface Address=" MACSTR 1289069fa2c39ec7120656a2ea8cca83c5ee41ddab60Irfan Sheriff " wps_method=%d persistent_group=%d pd_before_go_neg=%d force_freq %d", 12908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt MAC2STR(peer_addr), go_intent, MAC2STR(own_interface_addr), 1291069fa2c39ec7120656a2ea8cca83c5ee41ddab60Irfan Sheriff wps_method, persistent_group, pd_before_go_neg, force_freq); 12928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 12938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (p2p_prepare_channel(p2p, force_freq) < 0) 12948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 12958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 12968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt dev = p2p_get_device(p2p, peer_addr); 12978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (dev == NULL || (dev->flags & P2P_DEV_PROBE_REQ_ONLY)) { 12988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG, 12998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "P2P: Cannot connect to unknown P2P Device " MACSTR, 13008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt MAC2STR(peer_addr)); 13018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 13028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 13038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 13048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (dev->flags & P2P_DEV_GROUP_CLIENT_ONLY) { 13058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (!(dev->info.dev_capab & 13068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt P2P_DEV_CAPAB_CLIENT_DISCOVERABILITY)) { 13078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG, 13088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "P2P: Cannot connect to P2P Device " MACSTR 13098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt " that is in a group and is not discoverable", 13108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt MAC2STR(peer_addr)); 13118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 13128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 13138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (dev->oper_freq <= 0) { 13148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG, 13158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "P2P: Cannot connect to P2P Device " MACSTR 13168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt " with incomplete information", 13178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt MAC2STR(peer_addr)); 13188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 13198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 13208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 13218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* 13228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * First, try to connect directly. If the peer does not 13238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * acknowledge frames, assume it is sleeping and use device 13248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * discoverability via the GO at that point. 13258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */ 13268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 13278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 132804949598a23f501be6eec21697465fd46a28840aDmitry Shmidt p2p->ssid_set = 0; 132904949598a23f501be6eec21697465fd46a28840aDmitry Shmidt if (force_ssid) { 133004949598a23f501be6eec21697465fd46a28840aDmitry Shmidt wpa_hexdump_ascii(MSG_DEBUG, "P2P: Forced SSID", 133104949598a23f501be6eec21697465fd46a28840aDmitry Shmidt force_ssid, force_ssid_len); 133204949598a23f501be6eec21697465fd46a28840aDmitry Shmidt os_memcpy(p2p->ssid, force_ssid, force_ssid_len); 133304949598a23f501be6eec21697465fd46a28840aDmitry Shmidt p2p->ssid_len = force_ssid_len; 133404949598a23f501be6eec21697465fd46a28840aDmitry Shmidt p2p->ssid_set = 1; 133504949598a23f501be6eec21697465fd46a28840aDmitry Shmidt } 133604949598a23f501be6eec21697465fd46a28840aDmitry Shmidt 13378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt dev->flags &= ~P2P_DEV_NOT_YET_READY; 13388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt dev->flags &= ~P2P_DEV_USER_REJECTED; 13398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt dev->flags &= ~P2P_DEV_WAIT_GO_NEG_RESPONSE; 13408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt dev->flags &= ~P2P_DEV_WAIT_GO_NEG_CONFIRM; 134104949598a23f501be6eec21697465fd46a28840aDmitry Shmidt if (pd_before_go_neg) 134204949598a23f501be6eec21697465fd46a28840aDmitry Shmidt dev->flags |= P2P_DEV_PD_BEFORE_GO_NEG; 134304949598a23f501be6eec21697465fd46a28840aDmitry Shmidt else 134404949598a23f501be6eec21697465fd46a28840aDmitry Shmidt dev->flags &= ~P2P_DEV_PD_BEFORE_GO_NEG; 13458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt dev->connect_reqs = 0; 13468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt dev->go_neg_req_sent = 0; 13478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt dev->go_state = UNKNOWN_GO; 13481f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt p2p_set_dev_persistent(dev, persistent_group); 13498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p->go_intent = go_intent; 13508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memcpy(p2p->intended_addr, own_interface_addr, ETH_ALEN); 13518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 13528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (p2p->state != P2P_IDLE) 13538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_stop_find(p2p); 13548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 13558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (p2p->after_scan_tx) { 13568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* 13578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * We need to drop the pending frame to avoid issues with the 13588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * new GO Negotiation, e.g., when the pending frame was from a 13598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * previous attempt at starting a GO Negotiation. 13608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */ 13618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG, "P2P: Dropped " 13628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "previous pending Action frame TX that was waiting " 13638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "for p2p_scan completion"); 13648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_free(p2p->after_scan_tx); 13658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p->after_scan_tx = NULL; 13668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 13678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 13688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt dev->wps_method = wps_method; 13698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt dev->status = P2P_SC_SUCCESS; 13708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 13718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (force_freq) 13728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt dev->flags |= P2P_DEV_FORCE_FREQ; 13738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt else 13748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt dev->flags &= ~P2P_DEV_FORCE_FREQ; 13758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 13768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (p2p->p2p_scan_running) { 13778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG, 13788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "P2P: p2p_scan running - delay connect send"); 13798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p->start_after_scan = P2P_AFTER_SCAN_CONNECT; 13808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memcpy(p2p->after_scan_peer, peer_addr, ETH_ALEN); 13818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 13828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 13838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p->start_after_scan = P2P_AFTER_SCAN_NOTHING; 13848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 13858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return p2p_connect_send(p2p, dev); 13868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 13878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 13888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 13898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtint p2p_authorize(struct p2p_data *p2p, const u8 *peer_addr, 13908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt enum p2p_wps_method wps_method, 13918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt int go_intent, const u8 *own_interface_addr, 139204949598a23f501be6eec21697465fd46a28840aDmitry Shmidt unsigned int force_freq, int persistent_group, 139304949598a23f501be6eec21697465fd46a28840aDmitry Shmidt const u8 *force_ssid, size_t force_ssid_len) 13948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 13958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct p2p_device *dev; 13968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 13978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG, 13988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "P2P: Request to authorize group negotiation - peer=" MACSTR 13998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt " GO Intent=%d Intended Interface Address=" MACSTR 14008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt " wps_method=%d persistent_group=%d", 14018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt MAC2STR(peer_addr), go_intent, MAC2STR(own_interface_addr), 14028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wps_method, persistent_group); 14038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 14048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (p2p_prepare_channel(p2p, force_freq) < 0) 14058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 14068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 14078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt dev = p2p_get_device(p2p, peer_addr); 14088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (dev == NULL) { 14098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG, 14108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "P2P: Cannot authorize unknown P2P Device " MACSTR, 14118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt MAC2STR(peer_addr)); 14128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 14138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 14148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 141504949598a23f501be6eec21697465fd46a28840aDmitry Shmidt p2p->ssid_set = 0; 141604949598a23f501be6eec21697465fd46a28840aDmitry Shmidt if (force_ssid) { 141704949598a23f501be6eec21697465fd46a28840aDmitry Shmidt wpa_hexdump_ascii(MSG_DEBUG, "P2P: Forced SSID", 141804949598a23f501be6eec21697465fd46a28840aDmitry Shmidt force_ssid, force_ssid_len); 141904949598a23f501be6eec21697465fd46a28840aDmitry Shmidt os_memcpy(p2p->ssid, force_ssid, force_ssid_len); 142004949598a23f501be6eec21697465fd46a28840aDmitry Shmidt p2p->ssid_len = force_ssid_len; 142104949598a23f501be6eec21697465fd46a28840aDmitry Shmidt p2p->ssid_set = 1; 142204949598a23f501be6eec21697465fd46a28840aDmitry Shmidt } 142304949598a23f501be6eec21697465fd46a28840aDmitry Shmidt 14248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt dev->flags &= ~P2P_DEV_NOT_YET_READY; 14258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt dev->flags &= ~P2P_DEV_USER_REJECTED; 14268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt dev->go_neg_req_sent = 0; 14278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt dev->go_state = UNKNOWN_GO; 14281f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt p2p_set_dev_persistent(dev, persistent_group); 14298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p->go_intent = go_intent; 14308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memcpy(p2p->intended_addr, own_interface_addr, ETH_ALEN); 14318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 14328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt dev->wps_method = wps_method; 14338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt dev->status = P2P_SC_SUCCESS; 14348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 14358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (force_freq) 14368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt dev->flags |= P2P_DEV_FORCE_FREQ; 14378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt else 14388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt dev->flags &= ~P2P_DEV_FORCE_FREQ; 14398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 14408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 14418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 14428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 14438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 14448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtvoid p2p_add_dev_info(struct p2p_data *p2p, const u8 *addr, 14458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct p2p_device *dev, struct p2p_message *msg) 14468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 14478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_get_time(&dev->last_seen); 14488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 14498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_copy_wps_info(dev, 0, msg); 14508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 14518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (msg->listen_channel) { 14528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt int freq; 14538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt freq = p2p_channel_to_freq((char *) msg->listen_channel, 14548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt msg->listen_channel[3], 14558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt msg->listen_channel[4]); 14568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (freq < 0) { 14578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG, 14588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "P2P: Unknown peer Listen channel: " 14598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "country=%c%c(0x%02x) reg_class=%u channel=%u", 14608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt msg->listen_channel[0], 14618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt msg->listen_channel[1], 14628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt msg->listen_channel[2], 14638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt msg->listen_channel[3], 14648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt msg->listen_channel[4]); 14658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } else { 14668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG, "P2P: Update " 14678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "peer " MACSTR " Listen channel: %u -> %u MHz", 14688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt MAC2STR(dev->info.p2p_device_addr), 14698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt dev->listen_freq, freq); 14708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt dev->listen_freq = freq; 14718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 14728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 14738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 147461d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt if (msg->wfd_subelems) { 147561d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt wpabuf_free(dev->info.wfd_subelems); 147661d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt dev->info.wfd_subelems = wpabuf_dup(msg->wfd_subelems); 147761d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt } 147861d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt 14798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (dev->flags & P2P_DEV_PROBE_REQ_ONLY) { 14808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt dev->flags &= ~P2P_DEV_PROBE_REQ_ONLY; 14818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG, 14828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "P2P: Completed device entry based on data from " 14838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "GO Negotiation Request"); 14848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } else { 14858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG, 14868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "P2P: Created device entry based on GO Neg Req: " 14878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt MACSTR " dev_capab=0x%x group_capab=0x%x name='%s' " 14888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "listen_freq=%d", 14898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt MAC2STR(dev->info.p2p_device_addr), 14908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt dev->info.dev_capab, dev->info.group_capab, 14918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt dev->info.device_name, dev->listen_freq); 14928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 14938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 14948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt dev->flags &= ~P2P_DEV_GROUP_CLIENT_ONLY; 14958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 14968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (dev->flags & P2P_DEV_USER_REJECTED) { 14978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG, 14988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "P2P: Do not report rejected device"); 14998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; 15008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 15018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 15028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p->cfg->dev_found(p2p->cfg->cb_ctx, addr, &dev->info, 15038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt !(dev->flags & P2P_DEV_REPORTED_ONCE)); 15048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt dev->flags |= P2P_DEV_REPORTED | P2P_DEV_REPORTED_ONCE; 15058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 15068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 15078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 15088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtvoid p2p_build_ssid(struct p2p_data *p2p, u8 *ssid, size_t *ssid_len) 15098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 15108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memcpy(ssid, P2P_WILDCARD_SSID, P2P_WILDCARD_SSID_LEN); 15118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_random((char *) &ssid[P2P_WILDCARD_SSID_LEN], 2); 15128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memcpy(&ssid[P2P_WILDCARD_SSID_LEN + 2], 15138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p->cfg->ssid_postfix, p2p->cfg->ssid_postfix_len); 15148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt *ssid_len = P2P_WILDCARD_SSID_LEN + 2 + p2p->cfg->ssid_postfix_len; 15158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 15168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 15178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 15188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtint p2p_go_params(struct p2p_data *p2p, struct p2p_go_neg_results *params) 15198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 15208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_build_ssid(p2p, params->ssid, ¶ms->ssid_len); 15218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_random(params->passphrase, 8); 15228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 15238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 15248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 15258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 15268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtvoid p2p_go_complete(struct p2p_data *p2p, struct p2p_device *peer) 15278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 15288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct p2p_go_neg_results res; 15298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt int go = peer->go_state == LOCAL_GO; 15308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct p2p_channels intersection; 15318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt int freqs; 15328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt size_t i, j; 15338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 15348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG, 15358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "P2P: GO Negotiation with " MACSTR " completed (%s will be " 15368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "GO)", MAC2STR(peer->info.p2p_device_addr), 15378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt go ? "local end" : "peer"); 15388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 15398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memset(&res, 0, sizeof(res)); 15408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt res.role_go = go; 15418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memcpy(res.peer_device_addr, peer->info.p2p_device_addr, ETH_ALEN); 15428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memcpy(res.peer_interface_addr, peer->intended_addr, ETH_ALEN); 15438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt res.wps_method = peer->wps_method; 15441f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt if (peer->flags & P2P_DEV_PREFER_PERSISTENT_GROUP) { 15451f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt if (peer->flags & P2P_DEV_PREFER_PERSISTENT_RECONN) 15461f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt res.persistent_group = 2; 15471f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt else 15481f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt res.persistent_group = 1; 15491f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt } 15508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 15518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (go) { 15528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* Setup AP mode for WPS provisioning */ 15538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt res.freq = p2p_channel_to_freq(p2p->cfg->country, 15548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p->op_reg_class, 15558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p->op_channel); 15568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memcpy(res.ssid, p2p->ssid, p2p->ssid_len); 15578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt res.ssid_len = p2p->ssid_len; 15588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_random(res.passphrase, 8); 15598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } else { 15608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt res.freq = peer->oper_freq; 15618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (p2p->ssid_len) { 15628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memcpy(res.ssid, p2p->ssid, p2p->ssid_len); 15638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt res.ssid_len = p2p->ssid_len; 15648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 15658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 15668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 15678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_channels_intersect(&p2p->channels, &peer->channels, 15688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt &intersection); 15698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt freqs = 0; 15708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt for (i = 0; i < intersection.reg_classes; i++) { 15718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct p2p_reg_class *c = &intersection.reg_class[i]; 15728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (freqs + 1 == P2P_MAX_CHANNELS) 15738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 15748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt for (j = 0; j < c->channels; j++) { 15758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt int freq; 15768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (freqs + 1 == P2P_MAX_CHANNELS) 15778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 15788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt freq = p2p_channel_to_freq(peer->country, c->reg_class, 15798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt c->channel[j]); 15808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (freq < 0) 15818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt continue; 15828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt res.freq_list[freqs++] = freq; 15838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 15848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 15858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 15868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt res.peer_config_timeout = go ? peer->client_timeout : peer->go_timeout; 15878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 15888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_clear_timeout(p2p); 15891f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt p2p->ssid_set = 0; 15908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt peer->go_neg_req_sent = 0; 15918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt peer->wps_method = WPS_NOT_READY; 15928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 15938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_set_state(p2p, P2P_PROVISIONING); 15948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p->cfg->go_neg_completed(p2p->cfg->cb_ctx, &res); 15958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 15968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 15978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 15988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic void p2p_rx_p2p_action(struct p2p_data *p2p, const u8 *sa, 15998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt const u8 *data, size_t len, int rx_freq) 16008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 16018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG, 16028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "P2P: RX P2P Public Action from " MACSTR, MAC2STR(sa)); 16038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_hexdump(MSG_MSGDUMP, "P2P: P2P Public Action contents", data, len); 16048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 16058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (len < 1) 16068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; 16078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 16088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt switch (data[0]) { 16098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case P2P_GO_NEG_REQ: 16108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_process_go_neg_req(p2p, sa, data + 1, len - 1, rx_freq); 16118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 16128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case P2P_GO_NEG_RESP: 16138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_process_go_neg_resp(p2p, sa, data + 1, len - 1, rx_freq); 16148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 16158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case P2P_GO_NEG_CONF: 16168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_process_go_neg_conf(p2p, sa, data + 1, len - 1); 16178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 16188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case P2P_INVITATION_REQ: 16198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_process_invitation_req(p2p, sa, data + 1, len - 1, 16208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt rx_freq); 16218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 16228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case P2P_INVITATION_RESP: 16238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_process_invitation_resp(p2p, sa, data + 1, len - 1); 16248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 16258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case P2P_PROV_DISC_REQ: 16268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_process_prov_disc_req(p2p, sa, data + 1, len - 1, rx_freq); 16278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 16288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case P2P_PROV_DISC_RESP: 16298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_process_prov_disc_resp(p2p, sa, data + 1, len - 1); 16308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 16318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case P2P_DEV_DISC_REQ: 16328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_process_dev_disc_req(p2p, sa, data + 1, len - 1, rx_freq); 16338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 16348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case P2P_DEV_DISC_RESP: 16358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_process_dev_disc_resp(p2p, sa, data + 1, len - 1); 16368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 16378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt default: 16388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG, 16398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "P2P: Unsupported P2P Public Action frame type %d", 16408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt data[0]); 16418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 16428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 16438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 16448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 16458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 16461f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidtstatic void p2p_rx_action_public(struct p2p_data *p2p, const u8 *da, 16471f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt const u8 *sa, const u8 *bssid, const u8 *data, 16481f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt size_t len, int freq) 16498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 16508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (len < 1) 16518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; 16528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 16538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt switch (data[0]) { 16548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case WLAN_PA_VENDOR_SPECIFIC: 16558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt data++; 16568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt len--; 16578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (len < 3) 16588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; 16598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (WPA_GET_BE24(data) != OUI_WFA) 16608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; 16618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 16628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt data += 3; 16638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt len -= 3; 16648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (len < 1) 16658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; 16668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 16678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (*data != P2P_OUI_TYPE) 16688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; 16698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 16708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_rx_p2p_action(p2p, sa, data + 1, len - 1, freq); 16718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 16728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case WLAN_PA_GAS_INITIAL_REQ: 16738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_rx_gas_initial_req(p2p, sa, data + 1, len - 1, freq); 16748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 16758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case WLAN_PA_GAS_INITIAL_RESP: 16768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_rx_gas_initial_resp(p2p, sa, data + 1, len - 1, freq); 16778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 16788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case WLAN_PA_GAS_COMEBACK_REQ: 16798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_rx_gas_comeback_req(p2p, sa, data + 1, len - 1, freq); 16808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 16818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case WLAN_PA_GAS_COMEBACK_RESP: 16828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_rx_gas_comeback_resp(p2p, sa, data + 1, len - 1, freq); 16838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 16848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 16858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 16868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 16878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 16888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtvoid p2p_rx_action(struct p2p_data *p2p, const u8 *da, const u8 *sa, 16898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt const u8 *bssid, u8 category, 16908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt const u8 *data, size_t len, int freq) 16918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 16928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (category == WLAN_ACTION_PUBLIC) { 16938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_rx_action_public(p2p, da, sa, bssid, data, len, freq); 16948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; 16958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 16968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 16978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (category != WLAN_ACTION_VENDOR_SPECIFIC) 16988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; 16998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 17008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (len < 4) 17018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; 17028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 17038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (WPA_GET_BE24(data) != OUI_WFA) 17048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; 17058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt data += 3; 17068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt len -= 3; 17078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 17088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (*data != P2P_OUI_TYPE) 17098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; 17108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt data++; 17118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt len--; 17128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 17138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* P2P action frame */ 17148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG, 17158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "P2P: RX P2P Action from " MACSTR, MAC2STR(sa)); 17168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_hexdump(MSG_MSGDUMP, "P2P: P2P Action contents", data, len); 17178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 17188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (len < 1) 17198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; 17208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt switch (data[0]) { 17218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case P2P_NOA: 17228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG, 17238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "P2P: Received P2P Action - Notice of Absence"); 17248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* TODO */ 17258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 17268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case P2P_PRESENCE_REQ: 17278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_process_presence_req(p2p, da, sa, data + 1, len - 1, freq); 17288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 17298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case P2P_PRESENCE_RESP: 17308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_process_presence_resp(p2p, da, sa, data + 1, len - 1); 17318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 17328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case P2P_GO_DISC_REQ: 17338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_process_go_disc_req(p2p, da, sa, data + 1, len - 1, freq); 17348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 17358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt default: 17368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG, 17378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "P2P: Received P2P Action - unknown type %u", data[0]); 17388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 17398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 17408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 17418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 17428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 17438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic void p2p_go_neg_start(void *eloop_ctx, void *timeout_ctx) 17448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 17458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct p2p_data *p2p = eloop_ctx; 17468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (p2p->go_neg_peer == NULL) 17478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; 17488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p->cfg->stop_listen(p2p->cfg->cb_ctx); 17498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p->go_neg_peer->status = P2P_SC_SUCCESS; 17508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_connect_send(p2p, p2p->go_neg_peer); 17518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 17528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 17538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 17548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic void p2p_invite_start(void *eloop_ctx, void *timeout_ctx) 17558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 17568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct p2p_data *p2p = eloop_ctx; 17578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (p2p->invite_peer == NULL) 17588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; 17598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p->cfg->stop_listen(p2p->cfg->cb_ctx); 17608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_invite_send(p2p, p2p->invite_peer, p2p->invite_go_dev_addr); 17618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 17628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 17638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 17648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic void p2p_add_dev_from_probe_req(struct p2p_data *p2p, const u8 *addr, 17658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt const u8 *ie, size_t ie_len) 17668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 17678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct p2p_message msg; 17688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct p2p_device *dev; 17698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 17708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memset(&msg, 0, sizeof(msg)); 17718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (p2p_parse_ies(ie, ie_len, &msg) < 0 || msg.p2p_attributes == NULL) 17728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt { 17738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_parse_free(&msg); 17748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; /* not a P2P probe */ 17758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 17768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 17778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (msg.ssid == NULL || msg.ssid[1] != P2P_WILDCARD_SSID_LEN || 17788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memcmp(msg.ssid + 2, P2P_WILDCARD_SSID, P2P_WILDCARD_SSID_LEN) 17798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt != 0) { 17808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* The Probe Request is not part of P2P Device Discovery. It is 17818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * not known whether the source address of the frame is the P2P 17828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * Device Address or P2P Interface Address. Do not add a new 17838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * peer entry based on this frames. 17848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */ 17858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_parse_free(&msg); 17868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; 17878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 17888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 17898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt dev = p2p_get_device(p2p, addr); 17908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (dev) { 17918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (dev->country[0] == 0 && msg.listen_channel) 17928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memcpy(dev->country, msg.listen_channel, 3); 17931f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt os_get_time(&dev->last_seen); 17948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_parse_free(&msg); 17958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; /* already known */ 17968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 17978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 17988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt dev = p2p_create_device(p2p, addr); 17998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (dev == NULL) { 18008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_parse_free(&msg); 18018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; 18028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 18038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 18048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_get_time(&dev->last_seen); 18058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt dev->flags |= P2P_DEV_PROBE_REQ_ONLY; 18068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 18078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (msg.listen_channel) { 18088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memcpy(dev->country, msg.listen_channel, 3); 18098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt dev->listen_freq = p2p_channel_to_freq(dev->country, 18108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt msg.listen_channel[3], 18118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt msg.listen_channel[4]); 18128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 18138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 18148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_copy_wps_info(dev, 1, &msg); 18158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 181661d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt if (msg.wfd_subelems) { 181761d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt wpabuf_free(dev->info.wfd_subelems); 181861d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt dev->info.wfd_subelems = wpabuf_dup(msg.wfd_subelems); 181961d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt } 182061d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt 18218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_parse_free(&msg); 18228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 18238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG, 18248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "P2P: Created device entry based on Probe Req: " MACSTR 18258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt " dev_capab=0x%x group_capab=0x%x name='%s' listen_freq=%d", 18268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt MAC2STR(dev->info.p2p_device_addr), dev->info.dev_capab, 18278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt dev->info.group_capab, dev->info.device_name, 18288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt dev->listen_freq); 18298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 18308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 18318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 18328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstruct p2p_device * p2p_add_dev_from_go_neg_req(struct p2p_data *p2p, 18338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt const u8 *addr, 18348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct p2p_message *msg) 18358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 18368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct p2p_device *dev; 18378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 18388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt dev = p2p_get_device(p2p, addr); 18398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (dev) { 18408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_get_time(&dev->last_seen); 18418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return dev; /* already known */ 18428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 18438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 18448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt dev = p2p_create_device(p2p, addr); 18458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (dev == NULL) 18468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return NULL; 18478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 18488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_add_dev_info(p2p, addr, dev, msg); 18498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 18508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return dev; 18518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 18528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 18538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 18548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic int dev_type_match(const u8 *dev_type, const u8 *req_dev_type) 18558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 18568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (os_memcmp(dev_type, req_dev_type, WPS_DEV_TYPE_LEN) == 0) 18578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 1; 18588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (os_memcmp(dev_type, req_dev_type, 2) == 0 && 18598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt WPA_GET_BE32(&req_dev_type[2]) == 0 && 18608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt WPA_GET_BE16(&req_dev_type[6]) == 0) 18618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 1; /* Category match with wildcard OUI/sub-category */ 18628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 18638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 18648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 18658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 18668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtint dev_type_list_match(const u8 *dev_type, const u8 *req_dev_type[], 18678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt size_t num_req_dev_type) 18688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 18698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt size_t i; 18708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt for (i = 0; i < num_req_dev_type; i++) { 18718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (dev_type_match(dev_type, req_dev_type[i])) 18728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 1; 18738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 18748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 18758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 18768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 18778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 18788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt/** 18798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * p2p_match_dev_type - Match local device type with requested type 18808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @p2p: P2P module context from p2p_init() 18818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @wps: WPS TLVs from Probe Request frame (concatenated WPS IEs) 18828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * Returns: 1 on match, 0 on mismatch 18838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * 18848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * This function can be used to match the Requested Device Type attribute in 18858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * WPS IE with the local device types for deciding whether to reply to a Probe 18868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * Request frame. 18878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */ 18888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtint p2p_match_dev_type(struct p2p_data *p2p, struct wpabuf *wps) 18898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 18908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct wps_parse_attr attr; 18918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt size_t i; 18928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 18938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (wps_parse_msg(wps, &attr)) 18948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 1; /* assume no Requested Device Type attributes */ 18958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 18968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (attr.num_req_dev_type == 0) 18978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 1; /* no Requested Device Type attributes -> match */ 18988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 18998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (dev_type_list_match(p2p->cfg->pri_dev_type, attr.req_dev_type, 19008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt attr.num_req_dev_type)) 19018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 1; /* Own Primary Device Type matches */ 19028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 19038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt for (i = 0; i < p2p->cfg->num_sec_dev_types; i++) 19048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (dev_type_list_match(p2p->cfg->sec_dev_type[i], 19058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt attr.req_dev_type, 19068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt attr.num_req_dev_type)) 19078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 1; /* Own Secondary Device Type matches */ 19088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 19098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* No matching device type found */ 19108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 19118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 19128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 19138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 19148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstruct wpabuf * p2p_build_probe_resp_ies(struct p2p_data *p2p) 19158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 19168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct wpabuf *buf; 19178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt u8 *len; 191804949598a23f501be6eec21697465fd46a28840aDmitry Shmidt int pw_id = -1; 191961d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt size_t extra = 0; 192061d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt 192161d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt#ifdef CONFIG_WIFI_DISPLAY 192261d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt if (p2p->wfd_ie_probe_resp) 192361d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt extra = wpabuf_len(p2p->wfd_ie_probe_resp); 192461d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt#endif /* CONFIG_WIFI_DISPLAY */ 19258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 192661d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt buf = wpabuf_alloc(1000 + extra); 19278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (buf == NULL) 19288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return NULL; 19298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 193004949598a23f501be6eec21697465fd46a28840aDmitry Shmidt if (p2p->go_neg_peer) { 193104949598a23f501be6eec21697465fd46a28840aDmitry Shmidt /* Advertise immediate availability of WPS credential */ 193204949598a23f501be6eec21697465fd46a28840aDmitry Shmidt pw_id = p2p_wps_method_pw_id(p2p->go_neg_peer->wps_method); 193304949598a23f501be6eec21697465fd46a28840aDmitry Shmidt } 193404949598a23f501be6eec21697465fd46a28840aDmitry Shmidt 193504949598a23f501be6eec21697465fd46a28840aDmitry Shmidt p2p_build_wps_ie(p2p, buf, pw_id, 1); 19368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 193761d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt#ifdef CONFIG_WIFI_DISPLAY 193861d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt if (p2p->wfd_ie_probe_resp) 193961d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt wpabuf_put_buf(buf, p2p->wfd_ie_probe_resp); 194061d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt#endif /* CONFIG_WIFI_DISPLAY */ 194161d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt 19428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* P2P IE */ 19438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt len = p2p_buf_add_ie_hdr(buf); 194404949598a23f501be6eec21697465fd46a28840aDmitry Shmidt p2p_buf_add_capability(buf, p2p->dev_capab & 194504949598a23f501be6eec21697465fd46a28840aDmitry Shmidt ~P2P_DEV_CAPAB_CLIENT_DISCOVERABILITY, 0); 19468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (p2p->ext_listen_interval) 19478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_buf_add_ext_listen_timing(buf, p2p->ext_listen_period, 19488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p->ext_listen_interval); 19498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_buf_add_device_info(buf, p2p, NULL); 19508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_buf_update_ie_hdr(buf, len); 19518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 19528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return buf; 19538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 19548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 19558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 19561f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidtstatic int is_11b(u8 rate) 19571f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt{ 19581f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt return rate == 0x02 || rate == 0x04 || rate == 0x0b || rate == 0x16; 19591f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt} 19601f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt 19611f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt 19621f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidtstatic int supp_rates_11b_only(struct ieee802_11_elems *elems) 19631f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt{ 19641f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt int num_11b = 0, num_others = 0; 19651f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt int i; 19661f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt 19671f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt if (elems->supp_rates == NULL && elems->ext_supp_rates == NULL) 19681f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt return 0; 19691f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt 19701f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt for (i = 0; elems->supp_rates && i < elems->supp_rates_len; i++) { 19711f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt if (is_11b(elems->supp_rates[i])) 19721f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt num_11b++; 19731f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt else 19741f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt num_others++; 19751f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt } 19761f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt 19771f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt for (i = 0; elems->ext_supp_rates && i < elems->ext_supp_rates_len; 19781f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt i++) { 19791f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt if (is_11b(elems->ext_supp_rates[i])) 19801f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt num_11b++; 19811f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt else 19821f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt num_others++; 19831f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt } 19841f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt 19851f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt return num_11b > 0 && num_others == 0; 19861f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt} 19871f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt 19881f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt 198904949598a23f501be6eec21697465fd46a28840aDmitry Shmidtstatic enum p2p_probe_req_status 199004949598a23f501be6eec21697465fd46a28840aDmitry Shmidtp2p_reply_probe(struct p2p_data *p2p, const u8 *addr, const u8 *dst, 199104949598a23f501be6eec21697465fd46a28840aDmitry Shmidt const u8 *bssid, const u8 *ie, size_t ie_len) 19928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 19938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct ieee802_11_elems elems; 19948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct wpabuf *buf; 19958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct ieee80211_mgmt *resp; 19961f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt struct p2p_message msg; 19978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct wpabuf *ies; 19988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 19998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (!p2p->in_listen || !p2p->drv_in_listen) { 20008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* not in Listen state - ignore Probe Request */ 200104949598a23f501be6eec21697465fd46a28840aDmitry Shmidt return P2P_PREQ_NOT_LISTEN; 20028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 20038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 20048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (ieee802_11_parse_elems((u8 *) ie, ie_len, &elems, 0) == 20058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ParseFailed) { 20068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* Ignore invalid Probe Request frames */ 200704949598a23f501be6eec21697465fd46a28840aDmitry Shmidt return P2P_PREQ_MALFORMED; 20088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 20098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 20108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (elems.p2p == NULL) { 20118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* not a P2P probe - ignore it */ 201204949598a23f501be6eec21697465fd46a28840aDmitry Shmidt return P2P_PREQ_NOT_P2P; 20138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 20148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 20151f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt if (dst && !is_broadcast_ether_addr(dst) && 20161f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt os_memcmp(dst, p2p->cfg->dev_addr, ETH_ALEN) != 0) { 20171f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt /* Not sent to the broadcast address or our P2P Device Address 20181f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt */ 201904949598a23f501be6eec21697465fd46a28840aDmitry Shmidt return P2P_PREQ_NOT_PROCESSED; 20201f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt } 20211f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt 20221f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt if (bssid && !is_broadcast_ether_addr(bssid)) { 20231f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt /* Not sent to the Wildcard BSSID */ 202404949598a23f501be6eec21697465fd46a28840aDmitry Shmidt return P2P_PREQ_NOT_PROCESSED; 20251f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt } 20261f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt 20278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (elems.ssid == NULL || elems.ssid_len != P2P_WILDCARD_SSID_LEN || 20288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memcmp(elems.ssid, P2P_WILDCARD_SSID, P2P_WILDCARD_SSID_LEN) != 20298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 0) { 20308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* not using P2P Wildcard SSID - ignore */ 203104949598a23f501be6eec21697465fd46a28840aDmitry Shmidt return P2P_PREQ_NOT_PROCESSED; 20328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 20338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 20341f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt if (supp_rates_11b_only(&elems)) { 20351f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt /* Indicates support for 11b rates only */ 203604949598a23f501be6eec21697465fd46a28840aDmitry Shmidt return P2P_PREQ_NOT_P2P; 20371f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt } 20381f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt 20391f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt os_memset(&msg, 0, sizeof(msg)); 20401f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt if (p2p_parse_ies(ie, ie_len, &msg) < 0) { 20411f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt /* Could not parse P2P attributes */ 204204949598a23f501be6eec21697465fd46a28840aDmitry Shmidt return P2P_PREQ_NOT_P2P; 20431f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt } 20441f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt 20451f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt if (msg.device_id && 204604949598a23f501be6eec21697465fd46a28840aDmitry Shmidt os_memcmp(msg.device_id, p2p->cfg->dev_addr, ETH_ALEN) != 0) { 20471f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt /* Device ID did not match */ 20481f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt p2p_parse_free(&msg); 204904949598a23f501be6eec21697465fd46a28840aDmitry Shmidt return P2P_PREQ_NOT_PROCESSED; 20501f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt } 20511f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt 20528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* Check Requested Device Type match */ 20531f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt if (msg.wps_attributes && 20541f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt !p2p_match_dev_type(p2p, msg.wps_attributes)) { 20558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* No match with Requested Device Type */ 20561f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt p2p_parse_free(&msg); 205704949598a23f501be6eec21697465fd46a28840aDmitry Shmidt return P2P_PREQ_NOT_PROCESSED; 20588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 20591f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt p2p_parse_free(&msg); 20608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 206104949598a23f501be6eec21697465fd46a28840aDmitry Shmidt if (!p2p->cfg->send_probe_resp) { 206204949598a23f501be6eec21697465fd46a28840aDmitry Shmidt /* Response generated elsewhere */ 206304949598a23f501be6eec21697465fd46a28840aDmitry Shmidt return P2P_PREQ_NOT_PROCESSED; 206404949598a23f501be6eec21697465fd46a28840aDmitry Shmidt } 20658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 20668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG, 20678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "P2P: Reply to P2P Probe Request in Listen state"); 20688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 20698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* 20708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * We do not really have a specific BSS that this frame is advertising, 20718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * so build a frame that has some information in valid format. This is 20728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * really only used for discovery purposes, not to learn exact BSS 20738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * parameters. 20748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */ 20758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ies = p2p_build_probe_resp_ies(p2p); 20768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (ies == NULL) 207704949598a23f501be6eec21697465fd46a28840aDmitry Shmidt return P2P_PREQ_NOT_PROCESSED; 20788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 20798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt buf = wpabuf_alloc(200 + wpabuf_len(ies)); 20808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (buf == NULL) { 20818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpabuf_free(ies); 208204949598a23f501be6eec21697465fd46a28840aDmitry Shmidt return P2P_PREQ_NOT_PROCESSED; 20838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 20848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 20858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt resp = NULL; 20868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt resp = wpabuf_put(buf, resp->u.probe_resp.variable - (u8 *) resp); 20878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 20888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt resp->frame_control = host_to_le16((WLAN_FC_TYPE_MGMT << 2) | 20898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt (WLAN_FC_STYPE_PROBE_RESP << 4)); 20908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memcpy(resp->da, addr, ETH_ALEN); 20918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memcpy(resp->sa, p2p->cfg->dev_addr, ETH_ALEN); 20928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memcpy(resp->bssid, p2p->cfg->dev_addr, ETH_ALEN); 20938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt resp->u.probe_resp.beacon_int = host_to_le16(100); 20948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* hardware or low-level driver will setup seq_ctrl and timestamp */ 20958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt resp->u.probe_resp.capab_info = 20968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt host_to_le16(WLAN_CAPABILITY_SHORT_PREAMBLE | 20978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt WLAN_CAPABILITY_PRIVACY | 20988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt WLAN_CAPABILITY_SHORT_SLOT_TIME); 20998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 21008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpabuf_put_u8(buf, WLAN_EID_SSID); 21018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpabuf_put_u8(buf, P2P_WILDCARD_SSID_LEN); 21028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpabuf_put_data(buf, P2P_WILDCARD_SSID, P2P_WILDCARD_SSID_LEN); 21038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 21048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpabuf_put_u8(buf, WLAN_EID_SUPP_RATES); 21058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpabuf_put_u8(buf, 8); 21068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpabuf_put_u8(buf, (60 / 5) | 0x80); 21078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpabuf_put_u8(buf, 90 / 5); 21088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpabuf_put_u8(buf, (120 / 5) | 0x80); 21098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpabuf_put_u8(buf, 180 / 5); 21108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpabuf_put_u8(buf, (240 / 5) | 0x80); 21118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpabuf_put_u8(buf, 360 / 5); 21128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpabuf_put_u8(buf, 480 / 5); 21138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpabuf_put_u8(buf, 540 / 5); 21148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 21158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpabuf_put_u8(buf, WLAN_EID_DS_PARAMS); 21168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpabuf_put_u8(buf, 1); 21178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpabuf_put_u8(buf, p2p->cfg->channel); 21188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 21198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpabuf_put_buf(buf, ies); 21208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpabuf_free(ies); 21218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 21228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p->cfg->send_probe_resp(p2p->cfg->cb_ctx, buf); 21238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 21248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpabuf_free(buf); 212504949598a23f501be6eec21697465fd46a28840aDmitry Shmidt 212604949598a23f501be6eec21697465fd46a28840aDmitry Shmidt return P2P_PREQ_NOT_PROCESSED; 21278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 21288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 21298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 213004949598a23f501be6eec21697465fd46a28840aDmitry Shmidtenum p2p_probe_req_status 213104949598a23f501be6eec21697465fd46a28840aDmitry Shmidtp2p_probe_req_rx(struct p2p_data *p2p, const u8 *addr, const u8 *dst, 213204949598a23f501be6eec21697465fd46a28840aDmitry Shmidt const u8 *bssid, const u8 *ie, size_t ie_len) 21338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 213404949598a23f501be6eec21697465fd46a28840aDmitry Shmidt enum p2p_probe_req_status res; 213504949598a23f501be6eec21697465fd46a28840aDmitry Shmidt 21368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_add_dev_from_probe_req(p2p, addr, ie, ie_len); 21378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 213804949598a23f501be6eec21697465fd46a28840aDmitry Shmidt res = p2p_reply_probe(p2p, addr, dst, bssid, ie, ie_len); 21398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 21408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if ((p2p->state == P2P_CONNECT || p2p->state == P2P_CONNECT_LISTEN) && 21418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p->go_neg_peer && 21428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memcmp(addr, p2p->go_neg_peer->info.p2p_device_addr, ETH_ALEN) 21438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt == 0) { 21448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* Received a Probe Request from GO Negotiation peer */ 21458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG, 21468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "P2P: Found GO Negotiation peer - try to start GO " 21478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "negotiation from timeout"); 21488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt eloop_register_timeout(0, 0, p2p_go_neg_start, p2p, NULL); 214904949598a23f501be6eec21697465fd46a28840aDmitry Shmidt return P2P_PREQ_PROCESSED; 21508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 21518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 21528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if ((p2p->state == P2P_INVITE || p2p->state == P2P_INVITE_LISTEN) && 21538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p->invite_peer && 21548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memcmp(addr, p2p->invite_peer->info.p2p_device_addr, ETH_ALEN) 21558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt == 0) { 21568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* Received a Probe Request from Invite peer */ 21578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG, 21588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "P2P: Found Invite peer - try to start Invite from " 21598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "timeout"); 21608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt eloop_register_timeout(0, 0, p2p_invite_start, p2p, NULL); 216104949598a23f501be6eec21697465fd46a28840aDmitry Shmidt return P2P_PREQ_PROCESSED; 21628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 21638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 216404949598a23f501be6eec21697465fd46a28840aDmitry Shmidt return res; 21658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 21668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 21678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 21688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic int p2p_assoc_req_ie_wlan_ap(struct p2p_data *p2p, const u8 *bssid, 21698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt u8 *buf, size_t len, struct wpabuf *p2p_ie) 21708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 21718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct wpabuf *tmp; 21728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt u8 *lpos; 21738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt size_t tmplen; 21748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt int res; 21758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt u8 group_capab; 21768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 21778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (p2p_ie == NULL) 21788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; /* WLAN AP is not a P2P manager */ 21798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 21808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* 21818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * (Re)Association Request - P2P IE 21828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * P2P Capability attribute (shall be present) 21838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * P2P Interface attribute (present if concurrent device and 21848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * P2P Management is enabled) 21858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */ 21868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt tmp = wpabuf_alloc(200); 21878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (tmp == NULL) 21888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 21898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 21908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt lpos = p2p_buf_add_ie_hdr(tmp); 21918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt group_capab = 0; 21928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (p2p->num_groups > 0) { 21938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt group_capab |= P2P_GROUP_CAPAB_GROUP_OWNER; 21948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if ((p2p->dev_capab & P2P_DEV_CAPAB_CONCURRENT_OPER) && 21958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt (p2p->dev_capab & P2P_DEV_CAPAB_INFRA_MANAGED) && 21968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p->cross_connect) 21978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt group_capab |= P2P_GROUP_CAPAB_CROSS_CONN; 21988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 21998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_buf_add_capability(tmp, p2p->dev_capab, group_capab); 22008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if ((p2p->dev_capab & P2P_DEV_CAPAB_CONCURRENT_OPER) && 22018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt (p2p->dev_capab & P2P_DEV_CAPAB_INFRA_MANAGED)) 22028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_buf_add_p2p_interface(tmp, p2p); 22038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_buf_update_ie_hdr(tmp, lpos); 22048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 22058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt tmplen = wpabuf_len(tmp); 22068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (tmplen > len) 22078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt res = -1; 22088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt else { 22098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memcpy(buf, wpabuf_head(tmp), tmplen); 22108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt res = tmplen; 22118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 22128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpabuf_free(tmp); 22138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 22148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return res; 22158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 22168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 22178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 22188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtint p2p_assoc_req_ie(struct p2p_data *p2p, const u8 *bssid, u8 *buf, 22198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt size_t len, int p2p_group, struct wpabuf *p2p_ie) 22208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 22218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct wpabuf *tmp; 22228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt u8 *lpos; 22238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct p2p_device *peer; 22248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt size_t tmplen; 22258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt int res; 222661d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt size_t extra = 0; 22278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 22288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (!p2p_group) 22298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return p2p_assoc_req_ie_wlan_ap(p2p, bssid, buf, len, p2p_ie); 22308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 223161d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt#ifdef CONFIG_WIFI_DISPLAY 223261d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt if (p2p->wfd_ie_assoc_req) 223361d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt extra = wpabuf_len(p2p->wfd_ie_assoc_req); 223461d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt#endif /* CONFIG_WIFI_DISPLAY */ 223561d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt 22368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* 22378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * (Re)Association Request - P2P IE 22388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * P2P Capability attribute (shall be present) 22398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * Extended Listen Timing (may be present) 22408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * P2P Device Info attribute (shall be present) 22418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */ 224261d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt tmp = wpabuf_alloc(200 + extra); 22438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (tmp == NULL) 22448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 22458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 224661d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt#ifdef CONFIG_WIFI_DISPLAY 224761d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt if (p2p->wfd_ie_assoc_req) 224861d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt wpabuf_put_buf(tmp, p2p->wfd_ie_assoc_req); 224961d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt#endif /* CONFIG_WIFI_DISPLAY */ 225061d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt 22518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt peer = bssid ? p2p_get_device(p2p, bssid) : NULL; 22528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 22538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt lpos = p2p_buf_add_ie_hdr(tmp); 22548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_buf_add_capability(tmp, p2p->dev_capab, 0); 22558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (p2p->ext_listen_interval) 22568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_buf_add_ext_listen_timing(tmp, p2p->ext_listen_period, 22578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p->ext_listen_interval); 22588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_buf_add_device_info(tmp, p2p, peer); 22598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_buf_update_ie_hdr(tmp, lpos); 22608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 22618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt tmplen = wpabuf_len(tmp); 22628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (tmplen > len) 22638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt res = -1; 22648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt else { 22658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memcpy(buf, wpabuf_head(tmp), tmplen); 22668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt res = tmplen; 22678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 22688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpabuf_free(tmp); 22698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 22708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return res; 22718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 22728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 22738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 22748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtint p2p_scan_result_text(const u8 *ies, size_t ies_len, char *buf, char *end) 22758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 22768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct wpabuf *p2p_ie; 22778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt int ret; 22788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 22798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_ie = ieee802_11_vendor_ie_concat(ies, ies_len, P2P_IE_VENDOR_TYPE); 22808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (p2p_ie == NULL) 22818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 22828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 22838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ret = p2p_attr_text(p2p_ie, buf, end); 22848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpabuf_free(p2p_ie); 22858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return ret; 22868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 22878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 22888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 228904949598a23f501be6eec21697465fd46a28840aDmitry Shmidtint p2p_parse_dev_addr_in_p2p_ie(struct wpabuf *p2p_ie, u8 *dev_addr) 2290c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt{ 2291c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt struct p2p_message msg; 2292c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt 2293c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt os_memset(&msg, 0, sizeof(msg)); 229404949598a23f501be6eec21697465fd46a28840aDmitry Shmidt if (p2p_parse_p2p_ie(p2p_ie, &msg)) 2295c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt return -1; 2296c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt 229704949598a23f501be6eec21697465fd46a28840aDmitry Shmidt if (msg.p2p_device_addr) { 229804949598a23f501be6eec21697465fd46a28840aDmitry Shmidt os_memcpy(dev_addr, msg.p2p_device_addr, ETH_ALEN); 229904949598a23f501be6eec21697465fd46a28840aDmitry Shmidt return 0; 230004949598a23f501be6eec21697465fd46a28840aDmitry Shmidt } else if (msg.device_id) { 230104949598a23f501be6eec21697465fd46a28840aDmitry Shmidt os_memcpy(dev_addr, msg.device_id, ETH_ALEN); 230204949598a23f501be6eec21697465fd46a28840aDmitry Shmidt return 0; 2303c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt } 230404949598a23f501be6eec21697465fd46a28840aDmitry Shmidt return -1; 230504949598a23f501be6eec21697465fd46a28840aDmitry Shmidt} 2306c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt 230704949598a23f501be6eec21697465fd46a28840aDmitry Shmidt 230804949598a23f501be6eec21697465fd46a28840aDmitry Shmidtint p2p_parse_dev_addr(const u8 *ies, size_t ies_len, u8 *dev_addr) 230904949598a23f501be6eec21697465fd46a28840aDmitry Shmidt{ 231004949598a23f501be6eec21697465fd46a28840aDmitry Shmidt struct wpabuf *p2p_ie; 231104949598a23f501be6eec21697465fd46a28840aDmitry Shmidt int ret; 231204949598a23f501be6eec21697465fd46a28840aDmitry Shmidt 231304949598a23f501be6eec21697465fd46a28840aDmitry Shmidt p2p_ie = ieee802_11_vendor_ie_concat(ies, ies_len, 231404949598a23f501be6eec21697465fd46a28840aDmitry Shmidt P2P_IE_VENDOR_TYPE); 231504949598a23f501be6eec21697465fd46a28840aDmitry Shmidt if (p2p_ie == NULL) 231604949598a23f501be6eec21697465fd46a28840aDmitry Shmidt return -1; 231704949598a23f501be6eec21697465fd46a28840aDmitry Shmidt ret = p2p_parse_dev_addr_in_p2p_ie(p2p_ie, dev_addr); 2318c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt wpabuf_free(p2p_ie); 231904949598a23f501be6eec21697465fd46a28840aDmitry Shmidt return ret; 2320c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt} 2321c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt 2322c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt 23238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic void p2p_clear_go_neg(struct p2p_data *p2p) 23248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 23258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p->go_neg_peer = NULL; 23268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_clear_timeout(p2p); 23278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_set_state(p2p, P2P_IDLE); 23288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 23298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 23308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 23318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtvoid p2p_wps_success_cb(struct p2p_data *p2p, const u8 *mac_addr) 23328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 23338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (p2p->go_neg_peer == NULL) { 23348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG, 23358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "P2P: No pending Group Formation - " 23368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "ignore WPS registration success notification"); 23378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; /* No pending Group Formation */ 23388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 23398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 23408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (os_memcmp(mac_addr, p2p->go_neg_peer->intended_addr, ETH_ALEN) != 23418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 0) { 23428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG, 23438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "P2P: Ignore WPS registration success notification " 23448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "for " MACSTR " (GO Negotiation peer " MACSTR ")", 23458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt MAC2STR(mac_addr), 23468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt MAC2STR(p2p->go_neg_peer->intended_addr)); 23478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; /* Ignore unexpected peer address */ 23488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 23498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 23508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG, 23518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "P2P: Group Formation completed successfully with " MACSTR, 23528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt MAC2STR(mac_addr)); 23538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 23548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_clear_go_neg(p2p); 23558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 23568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 23578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 23588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtvoid p2p_group_formation_failed(struct p2p_data *p2p) 23598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 23608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (p2p->go_neg_peer == NULL) { 23618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG, 23628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "P2P: No pending Group Formation - " 23638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "ignore group formation failure notification"); 23648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; /* No pending Group Formation */ 23658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 23668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 23678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG, 23688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "P2P: Group Formation failed with " MACSTR, 23698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt MAC2STR(p2p->go_neg_peer->intended_addr)); 23708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 23718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_clear_go_neg(p2p); 23728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 23738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 23748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 23758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstruct p2p_data * p2p_init(const struct p2p_config *cfg) 23768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 23778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct p2p_data *p2p; 23788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 23798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (cfg->max_peers < 1) 23808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return NULL; 23818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 23828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p = os_zalloc(sizeof(*p2p) + sizeof(*cfg)); 23838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (p2p == NULL) 23848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return NULL; 23858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p->cfg = (struct p2p_config *) (p2p + 1); 23868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memcpy(p2p->cfg, cfg, sizeof(*cfg)); 23878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (cfg->dev_name) 23888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p->cfg->dev_name = os_strdup(cfg->dev_name); 23898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (cfg->manufacturer) 23908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p->cfg->manufacturer = os_strdup(cfg->manufacturer); 23918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (cfg->model_name) 23928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p->cfg->model_name = os_strdup(cfg->model_name); 23938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (cfg->model_number) 23948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p->cfg->model_number = os_strdup(cfg->model_number); 23958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (cfg->serial_number) 23968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p->cfg->serial_number = os_strdup(cfg->serial_number); 239704949598a23f501be6eec21697465fd46a28840aDmitry Shmidt if (cfg->pref_chan) { 239804949598a23f501be6eec21697465fd46a28840aDmitry Shmidt p2p->cfg->pref_chan = os_malloc(cfg->num_pref_chan * 239904949598a23f501be6eec21697465fd46a28840aDmitry Shmidt sizeof(struct p2p_channel)); 240004949598a23f501be6eec21697465fd46a28840aDmitry Shmidt if (p2p->cfg->pref_chan) { 240104949598a23f501be6eec21697465fd46a28840aDmitry Shmidt os_memcpy(p2p->cfg->pref_chan, cfg->pref_chan, 240204949598a23f501be6eec21697465fd46a28840aDmitry Shmidt cfg->num_pref_chan * 240304949598a23f501be6eec21697465fd46a28840aDmitry Shmidt sizeof(struct p2p_channel)); 240404949598a23f501be6eec21697465fd46a28840aDmitry Shmidt } else 240504949598a23f501be6eec21697465fd46a28840aDmitry Shmidt p2p->cfg->num_pref_chan = 0; 240604949598a23f501be6eec21697465fd46a28840aDmitry Shmidt } 240704949598a23f501be6eec21697465fd46a28840aDmitry Shmidt 2408f44b9c4a18d17fbd39901f76a014c32006570fb8Irfan Sheriff#ifdef ANDROID_P2P 2409f44b9c4a18d17fbd39901f76a014c32006570fb8Irfan Sheriff /* 100ms listen time is too less to receive the response frames in some scenarios 2410f44b9c4a18d17fbd39901f76a014c32006570fb8Irfan Sheriff * increasing min listen time to 200ms. 2411f44b9c4a18d17fbd39901f76a014c32006570fb8Irfan Sheriff */ 2412f44b9c4a18d17fbd39901f76a014c32006570fb8Irfan Sheriff p2p->min_disc_int = 2; 2413f44b9c4a18d17fbd39901f76a014c32006570fb8Irfan Sheriff /* SD_FAIR_POLICY: Initializing the SD current serviced pointer to NULL */ 2414f44b9c4a18d17fbd39901f76a014c32006570fb8Irfan Sheriff p2p->sd_dev_list = NULL; 2415f44b9c4a18d17fbd39901f76a014c32006570fb8Irfan Sheriff#else 24168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p->min_disc_int = 1; 2417f44b9c4a18d17fbd39901f76a014c32006570fb8Irfan Sheriff#endif 24188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p->max_disc_int = 3; 24198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 24208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_get_random(&p2p->next_tie_breaker, 1); 24218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p->next_tie_breaker &= 0x01; 24228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (cfg->sd_request) 24238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p->dev_capab |= P2P_DEV_CAPAB_SERVICE_DISCOVERY; 24248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p->dev_capab |= P2P_DEV_CAPAB_INVITATION_PROCEDURE; 24258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (cfg->concurrent_operations) 24268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p->dev_capab |= P2P_DEV_CAPAB_CONCURRENT_OPER; 24278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p->dev_capab |= P2P_DEV_CAPAB_CLIENT_DISCOVERABILITY; 24288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 24298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt dl_list_init(&p2p->devices); 24308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 24318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt eloop_register_timeout(P2P_PEER_EXPIRATION_INTERVAL, 0, 24328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_expiration_timeout, p2p, NULL); 24338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 243461d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt p2p->go_timeout = 100; 243561d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt p2p->client_timeout = 20; 243661d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt 24378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return p2p; 24388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 24398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 24408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 24418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtvoid p2p_deinit(struct p2p_data *p2p) 24428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 244361d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt#ifdef CONFIG_WIFI_DISPLAY 244461d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt wpabuf_free(p2p->wfd_ie_beacon); 244561d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt wpabuf_free(p2p->wfd_ie_probe_req); 244661d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt wpabuf_free(p2p->wfd_ie_probe_resp); 244761d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt wpabuf_free(p2p->wfd_ie_assoc_req); 244861d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt wpabuf_free(p2p->wfd_ie_invitation); 244961d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt wpabuf_free(p2p->wfd_ie_prov_disc_req); 245061d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt wpabuf_free(p2p->wfd_ie_prov_disc_resp); 245161d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt wpabuf_free(p2p->wfd_ie_go_neg); 245261d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt wpabuf_free(p2p->wfd_dev_info); 245361d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt wpabuf_free(p2p->wfd_assoc_bssid); 245461d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt wpabuf_free(p2p->wfd_coupled_sink_info); 245561d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt#endif /* CONFIG_WIFI_DISPLAY */ 245661d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt 24578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt eloop_cancel_timeout(p2p_expiration_timeout, p2p, NULL); 24588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt eloop_cancel_timeout(p2p_ext_listen_timeout, p2p, NULL); 24598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt eloop_cancel_timeout(p2p_scan_timeout, p2p, NULL); 24608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_flush(p2p); 24618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_free_req_dev_types(p2p); 24628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_free(p2p->cfg->dev_name); 24638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_free(p2p->cfg->manufacturer); 24648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_free(p2p->cfg->model_name); 24658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_free(p2p->cfg->model_number); 24668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_free(p2p->cfg->serial_number); 246704949598a23f501be6eec21697465fd46a28840aDmitry Shmidt os_free(p2p->cfg->pref_chan); 24688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_free(p2p->groups); 24698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpabuf_free(p2p->sd_resp); 24708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_free(p2p->after_scan_tx); 24718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_remove_wps_vendor_extensions(p2p); 24728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_free(p2p); 24738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 24748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 24758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 24768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtvoid p2p_flush(struct p2p_data *p2p) 24778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 24788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct p2p_device *dev, *prev; 247904949598a23f501be6eec21697465fd46a28840aDmitry Shmidt p2p_stop_find(p2p); 24808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt dl_list_for_each_safe(dev, prev, &p2p->devices, struct p2p_device, 24818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt list) { 24828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt dl_list_del(&dev->list); 24838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_device_free(p2p, dev); 24848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 2485f44b9c4a18d17fbd39901f76a014c32006570fb8Irfan Sheriff#ifdef ANDROID_P2P 2486f44b9c4a18d17fbd39901f76a014c32006570fb8Irfan Sheriff /* SD_FAIR_POLICY: Initializing the SD current serviced pointer to NULL */ 2487f44b9c4a18d17fbd39901f76a014c32006570fb8Irfan Sheriff p2p->sd_dev_list = NULL; 2488f44b9c4a18d17fbd39901f76a014c32006570fb8Irfan Sheriff#endif 24898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_free_sd_queries(p2p); 24908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_free(p2p->after_scan_tx); 24918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p->after_scan_tx = NULL; 24928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 24938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 24948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 24958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtint p2p_unauthorize(struct p2p_data *p2p, const u8 *addr) 24968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 24978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct p2p_device *dev; 24988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 24998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt dev = p2p_get_device(p2p, addr); 25008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (dev == NULL) 25018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 25028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 25038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG, "P2P: Unauthorizing " MACSTR, 25048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt MAC2STR(addr)); 25058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 25068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (p2p->go_neg_peer == dev) 25078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p->go_neg_peer = NULL; 25088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 25098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt dev->wps_method = WPS_NOT_READY; 25108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt dev->flags &= ~P2P_DEV_WAIT_GO_NEG_RESPONSE; 25118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt dev->flags &= ~P2P_DEV_WAIT_GO_NEG_CONFIRM; 25128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 25138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* Check if after_scan_tx is for this peer. If so free it */ 25148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (p2p->after_scan_tx && 25158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memcmp(addr, p2p->after_scan_tx->dst, ETH_ALEN) == 0) { 25168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_free(p2p->after_scan_tx); 25178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p->after_scan_tx = NULL; 25188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 25198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 25208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 25218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 25228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 25238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 25248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtint p2p_set_dev_name(struct p2p_data *p2p, const char *dev_name) 25258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 25268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_free(p2p->cfg->dev_name); 25278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (dev_name) { 25288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p->cfg->dev_name = os_strdup(dev_name); 25298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (p2p->cfg->dev_name == NULL) 25308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 25318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } else 25328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p->cfg->dev_name = NULL; 25338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 25348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 25358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 25368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 25378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtint p2p_set_manufacturer(struct p2p_data *p2p, const char *manufacturer) 25388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 25398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_free(p2p->cfg->manufacturer); 25408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p->cfg->manufacturer = NULL; 25418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (manufacturer) { 25428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p->cfg->manufacturer = os_strdup(manufacturer); 25438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (p2p->cfg->manufacturer == NULL) 25448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 25458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 25468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 25478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 25488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 25498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 25508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 25518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtint p2p_set_model_name(struct p2p_data *p2p, const char *model_name) 25528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 25538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_free(p2p->cfg->model_name); 25548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p->cfg->model_name = NULL; 25558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (model_name) { 25568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p->cfg->model_name = os_strdup(model_name); 25578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (p2p->cfg->model_name == NULL) 25588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 25598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 25608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 25618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 25628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 25638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 25648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 25658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtint p2p_set_model_number(struct p2p_data *p2p, const char *model_number) 25668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 25678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_free(p2p->cfg->model_number); 25688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p->cfg->model_number = NULL; 25698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (model_number) { 25708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p->cfg->model_number = os_strdup(model_number); 25718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (p2p->cfg->model_number == NULL) 25728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 25738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 25748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 25758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 25768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 25778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 25788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 25798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtint p2p_set_serial_number(struct p2p_data *p2p, const char *serial_number) 25808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 25818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_free(p2p->cfg->serial_number); 25828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p->cfg->serial_number = NULL; 25838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (serial_number) { 25848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p->cfg->serial_number = os_strdup(serial_number); 25858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (p2p->cfg->serial_number == NULL) 25868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 25878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 25888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 25898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 25908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 25918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 25928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 25938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtvoid p2p_set_config_methods(struct p2p_data *p2p, u16 config_methods) 25948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 25958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p->cfg->config_methods = config_methods; 25968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 25978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 25988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 25998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtvoid p2p_set_uuid(struct p2p_data *p2p, const u8 *uuid) 26008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 26018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memcpy(p2p->cfg->uuid, uuid, 16); 26028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 26038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 26048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 26058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtint p2p_set_pri_dev_type(struct p2p_data *p2p, const u8 *pri_dev_type) 26068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 26078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memcpy(p2p->cfg->pri_dev_type, pri_dev_type, 8); 26088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 26098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 26108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 26118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 26128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtint p2p_set_sec_dev_types(struct p2p_data *p2p, const u8 dev_types[][8], 26138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt size_t num_dev_types) 26148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 26158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (num_dev_types > P2P_SEC_DEVICE_TYPES) 26168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt num_dev_types = P2P_SEC_DEVICE_TYPES; 26178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p->cfg->num_sec_dev_types = num_dev_types; 26188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memcpy(p2p->cfg->sec_dev_type, dev_types, num_dev_types * 8); 26198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 26208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 26218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 26228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 26238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtvoid p2p_remove_wps_vendor_extensions(struct p2p_data *p2p) 26248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 26258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt int i; 26268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 26278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt for (i = 0; i < P2P_MAX_WPS_VENDOR_EXT; i++) { 26288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpabuf_free(p2p->wps_vendor_ext[i]); 26298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p->wps_vendor_ext[i] = NULL; 26308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 26318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 26328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 26338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 26348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtint p2p_add_wps_vendor_extension(struct p2p_data *p2p, 26358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt const struct wpabuf *vendor_ext) 26368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 26378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt int i; 26388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 26398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (vendor_ext == NULL) 26408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 26418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 26428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt for (i = 0; i < P2P_MAX_WPS_VENDOR_EXT; i++) { 26438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (p2p->wps_vendor_ext[i] == NULL) 26448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 26458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 26468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (i >= P2P_MAX_WPS_VENDOR_EXT) 26478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 26488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 26498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p->wps_vendor_ext[i] = wpabuf_dup(vendor_ext); 26508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (p2p->wps_vendor_ext[i] == NULL) 26518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 26528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 26538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 26548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 26558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 26568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 26578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtint p2p_set_country(struct p2p_data *p2p, const char *country) 26588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 26598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memcpy(p2p->cfg->country, country, 3); 26608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 26618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 26628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 26638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 26648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtvoid p2p_continue_find(struct p2p_data *p2p) 26658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 26668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct p2p_device *dev; 2667f44b9c4a18d17fbd39901f76a014c32006570fb8Irfan Sheriff#ifdef ANDROID_P2P 2668f44b9c4a18d17fbd39901f76a014c32006570fb8Irfan Sheriff int skip=1; 2669f44b9c4a18d17fbd39901f76a014c32006570fb8Irfan Sheriff#endif 26708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_set_state(p2p, P2P_SEARCH); 26718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt dl_list_for_each(dev, &p2p->devices, struct p2p_device, list) { 2672f44b9c4a18d17fbd39901f76a014c32006570fb8Irfan Sheriff#ifdef ANDROID_P2P 2673f44b9c4a18d17fbd39901f76a014c32006570fb8Irfan Sheriff /* SD_FAIR_POLICY: We need to give chance to all devices in the device list 2674f44b9c4a18d17fbd39901f76a014c32006570fb8Irfan Sheriff * There may be a scenario, where a particular peer device have 2675f44b9c4a18d17fbd39901f76a014c32006570fb8Irfan Sheriff * not registered any query response. When we send a SD request to such device, 2676f44b9c4a18d17fbd39901f76a014c32006570fb8Irfan Sheriff * no response will be received. And if we continue to get probe responses from that device, 2677f44b9c4a18d17fbd39901f76a014c32006570fb8Irfan Sheriff * and if that device happens to be on top in our device list, 2678f44b9c4a18d17fbd39901f76a014c32006570fb8Irfan Sheriff * we will always continue to send SD requests always to that peer only. 2679f44b9c4a18d17fbd39901f76a014c32006570fb8Irfan Sheriff * We will not be able to send SD requests to other devices in that case. 2680f44b9c4a18d17fbd39901f76a014c32006570fb8Irfan Sheriff * This implementation keeps track of last serviced peer device. 2681f44b9c4a18d17fbd39901f76a014c32006570fb8Irfan Sheriff * And then takes the next one from the device list, in the next iteration. 2682f44b9c4a18d17fbd39901f76a014c32006570fb8Irfan Sheriff */ 2683f44b9c4a18d17fbd39901f76a014c32006570fb8Irfan Sheriff if (p2p->sd_dev_list && p2p->sd_dev_list != &p2p->devices) { 2684f44b9c4a18d17fbd39901f76a014c32006570fb8Irfan Sheriff if(skip) { 2685f44b9c4a18d17fbd39901f76a014c32006570fb8Irfan Sheriff if ((&dev->list == p2p->sd_dev_list) ) { 2686f44b9c4a18d17fbd39901f76a014c32006570fb8Irfan Sheriff skip = 0; 2687f44b9c4a18d17fbd39901f76a014c32006570fb8Irfan Sheriff if (dev->list.next == &p2p->devices) 2688f44b9c4a18d17fbd39901f76a014c32006570fb8Irfan Sheriff p2p->sd_dev_list = NULL; 2689f44b9c4a18d17fbd39901f76a014c32006570fb8Irfan Sheriff } 2690f44b9c4a18d17fbd39901f76a014c32006570fb8Irfan Sheriff continue; 2691f44b9c4a18d17fbd39901f76a014c32006570fb8Irfan Sheriff } 2692f44b9c4a18d17fbd39901f76a014c32006570fb8Irfan Sheriff } 2693f44b9c4a18d17fbd39901f76a014c32006570fb8Irfan Sheriff p2p->sd_dev_list = &dev->list; 2694f44b9c4a18d17fbd39901f76a014c32006570fb8Irfan Sheriff wpa_printf(MSG_DEBUG, "P2P: ### Servicing %p dev->flags 0x%x SD schedule %s devaddr " MACSTR, 2695f44b9c4a18d17fbd39901f76a014c32006570fb8Irfan Sheriff p2p->sd_dev_list, dev->flags, dev->flags & P2P_DEV_SD_SCHEDULE ? "TRUE": "FALSE", 2696f44b9c4a18d17fbd39901f76a014c32006570fb8Irfan Sheriff MAC2STR(dev->info.p2p_device_addr)); 2697f44b9c4a18d17fbd39901f76a014c32006570fb8Irfan Sheriff#endif 26988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (dev->flags & P2P_DEV_SD_SCHEDULE) { 26998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (p2p_start_sd(p2p, dev) == 0) 27008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; 27018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt else 27028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 27038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } else if (dev->req_config_methods && 27048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt !(dev->flags & P2P_DEV_PD_FOR_JOIN)) { 27058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG, "P2P: Send " 27061f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt "pending Provision Discovery Request to " 27078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt MACSTR " (config methods 0x%x)", 27088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt MAC2STR(dev->info.p2p_device_addr), 27098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt dev->req_config_methods); 27101f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt if (p2p_send_prov_disc_req(p2p, dev, 0, 0) == 0) 27118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; 27128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 27138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 27148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 27158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_listen_in_find(p2p); 27168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 27178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 27188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 27198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic void p2p_sd_cb(struct p2p_data *p2p, int success) 27208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 27218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG, 27228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "P2P: Service Discovery Query TX callback: success=%d", 27238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt success); 27248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p->pending_action_state = P2P_NO_PENDING_ACTION; 27258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 27268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (!success) { 27278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (p2p->sd_peer) { 27288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p->sd_peer->flags &= ~P2P_DEV_SD_SCHEDULE; 27298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p->sd_peer = NULL; 27308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 27318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_continue_find(p2p); 27328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; 27338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 27348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 27358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (p2p->sd_peer == NULL) { 27368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG, 27378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "P2P: No SD peer entry known"); 27388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_continue_find(p2p); 27398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; 27408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 27418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 27428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* Wait for response from the peer */ 27438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_set_state(p2p, P2P_SD_DURING_FIND); 27448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_set_timeout(p2p, 0, 200000); 27458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 27468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 274775ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen 274875ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen/** 274975ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen * p2p_retry_pd - Retry any pending provision disc requests in IDLE state 275075ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen * @p2p: P2P module context from p2p_init() 275175ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen */ 27521f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidtstatic void p2p_retry_pd(struct p2p_data *p2p) 275375ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen{ 275475ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen struct p2p_device *dev; 275575ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen 275675ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen if (p2p->state != P2P_IDLE) 275775ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen return; 275875ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen 275975ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen /* 276075ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen * Retry the prov disc req attempt only for the peer that the user had 276175ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen * requested for and provided a join has not been initiated on it 276275ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen * in the meantime. 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 if (dev->flags & P2P_DEV_PD_FOR_JOIN) 277275ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen continue; 277375ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen 277475ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG, "P2P: Send " 27751f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt "pending Provision Discovery Request to " 277675ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen MACSTR " (config methods 0x%x)", 277775ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen MAC2STR(dev->info.p2p_device_addr), 277875ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen dev->req_config_methods); 27791f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt p2p_send_prov_disc_req(p2p, dev, 0, 0); 278075ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen return; 278175ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen } 278275ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen} 278375ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen 278475ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen 27858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic void p2p_prov_disc_cb(struct p2p_data *p2p, int success) 27868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 27878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG, 27888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "P2P: Provision Discovery Request TX callback: success=%d", 27898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt success); 279075ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen 279175ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen /* 279275ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen * Postpone resetting the pending action state till after we actually 279375ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen * time out. This allows us to take some action like notifying any 279475ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen * interested parties about no response to the request. 279575ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen * 279675ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen * When the timer (below) goes off we check in IDLE, SEARCH, or 279775ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen * LISTEN_ONLY state, which are the only allowed states to issue a PD 279875ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen * requests in, if this was still pending and then raise notification. 279975ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen */ 28008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 28018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (!success) { 280275ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen p2p->pending_action_state = P2P_NO_PENDING_ACTION; 280375ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen 280461d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt if (p2p->user_initiated_pd && 280561d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt (p2p->state == P2P_SEARCH || p2p->state == P2P_LISTEN_ONLY)) 280661d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt { 280761d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt /* Retry request from timeout to avoid busy loops */ 280861d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt p2p->pending_action_state = P2P_PENDING_PD; 280961d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt p2p_set_timeout(p2p, 0, 50000); 281061d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt } else if (p2p->state != P2P_IDLE) 28118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_continue_find(p2p); 281275ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen else if (p2p->user_initiated_pd) { 281375ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen p2p->pending_action_state = P2P_PENDING_PD; 28141a2ce111ade9563d99ed7bb8156d6148ffd6c3a3Irfan Sheriff#ifdef ANDROID_P2P 28151a2ce111ade9563d99ed7bb8156d6148ffd6c3a3Irfan Sheriff p2p_set_timeout(p2p, 0, 350000); 28161a2ce111ade9563d99ed7bb8156d6148ffd6c3a3Irfan Sheriff#else 281775ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen p2p_set_timeout(p2p, 0, 300000); 28181a2ce111ade9563d99ed7bb8156d6148ffd6c3a3Irfan Sheriff#endif 281975ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen } 28208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; 28218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 28228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 282375ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen /* 282475ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen * This postponing, of resetting pending_action_state, needs to be 282575ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen * done only for user initiated PD requests and not internal ones. 282675ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen */ 282775ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen if (p2p->user_initiated_pd) 282875ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen p2p->pending_action_state = P2P_PENDING_PD; 282975ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen else 283075ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen p2p->pending_action_state = P2P_NO_PENDING_ACTION; 283175ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen 28328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* Wait for response from the peer */ 28338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (p2p->state == P2P_SEARCH) 28348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_set_state(p2p, P2P_PD_DURING_FIND); 28351a2ce111ade9563d99ed7bb8156d6148ffd6c3a3Irfan Sheriff#ifdef ANDROID_P2P 28361a2ce111ade9563d99ed7bb8156d6148ffd6c3a3Irfan Sheriff p2p_set_timeout(p2p, 0, 350000); 28371a2ce111ade9563d99ed7bb8156d6148ffd6c3a3Irfan Sheriff#else 28388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_set_timeout(p2p, 0, 200000); 28391a2ce111ade9563d99ed7bb8156d6148ffd6c3a3Irfan Sheriff#endif 28408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 28418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 28428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 28438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtint p2p_scan_res_handler(struct p2p_data *p2p, const u8 *bssid, int freq, 28448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt int level, const u8 *ies, size_t ies_len) 28458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 284604949598a23f501be6eec21697465fd46a28840aDmitry Shmidt p2p_add_device(p2p, bssid, freq, level, ies, ies_len, 1); 28478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 28488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 28498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 28508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 28518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 28528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtvoid p2p_scan_res_handled(struct p2p_data *p2p) 28538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 28548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (!p2p->p2p_scan_running) { 28558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG, "P2P: p2p_scan was not " 28568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "running, but scan results received"); 28578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 28588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p->p2p_scan_running = 0; 28598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt eloop_cancel_timeout(p2p_scan_timeout, p2p, NULL); 28608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 28618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (p2p_run_after_scan(p2p)) 28628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; 28638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (p2p->state == P2P_SEARCH) 28648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_continue_find(p2p); 28658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 28668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 28678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2868c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidtvoid p2p_scan_ie(struct p2p_data *p2p, struct wpabuf *ies, const u8 *dev_id) 28698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 287061d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt u8 *len; 287161d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt 287261d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt#ifdef CONFIG_WIFI_DISPLAY 287361d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt if (p2p->wfd_ie_probe_req) 287461d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt wpabuf_put_buf(ies, p2p->wfd_ie_probe_req); 287561d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt#endif /* CONFIG_WIFI_DISPLAY */ 287661d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt 287761d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt len = p2p_buf_add_ie_hdr(ies); 287804949598a23f501be6eec21697465fd46a28840aDmitry Shmidt p2p_buf_add_capability(ies, p2p->dev_capab & 287904949598a23f501be6eec21697465fd46a28840aDmitry Shmidt ~P2P_DEV_CAPAB_CLIENT_DISCOVERABILITY, 0); 2880c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt if (dev_id) 2881c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt p2p_buf_add_device_id(ies, dev_id); 28828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (p2p->cfg->reg_class && p2p->cfg->channel) 28838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_buf_add_listen_channel(ies, p2p->cfg->country, 28848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p->cfg->reg_class, 28858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p->cfg->channel); 28868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (p2p->ext_listen_interval) 28878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_buf_add_ext_listen_timing(ies, p2p->ext_listen_period, 28888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p->ext_listen_interval); 28898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* TODO: p2p_buf_add_operating_channel() if GO */ 28908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_buf_update_ie_hdr(ies, len); 28918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 28928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 28938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 28941f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidtsize_t p2p_scan_ie_buf_len(struct p2p_data *p2p) 28951f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt{ 289661d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt size_t len = 100; 289761d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt 289861d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt#ifdef CONFIG_WIFI_DISPLAY 289961d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt if (p2p && p2p->wfd_ie_probe_req) 290061d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt len += wpabuf_len(p2p->wfd_ie_probe_req); 290161d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt#endif /* CONFIG_WIFI_DISPLAY */ 290261d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt 290361d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt return len; 29041f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt} 29051f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt 29061f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt 29078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtint p2p_ie_text(struct wpabuf *p2p_ie, char *buf, char *end) 29088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 29098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return p2p_attr_text(p2p_ie, buf, end); 29108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 29118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 29128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 29138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic void p2p_go_neg_req_cb(struct p2p_data *p2p, int success) 29148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 29158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct p2p_device *dev = p2p->go_neg_peer; 29168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 29178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG, 29188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "P2P: GO Negotiation Request TX callback: success=%d", 29198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt success); 29208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 29218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (dev == NULL) { 29228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG, 29238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "P2P: No pending GO Negotiation"); 29248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; 29258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 29268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 29278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (success) { 29288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (dev->flags & P2P_DEV_USER_REJECTED) { 29298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_set_state(p2p, P2P_IDLE); 29308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; 29318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 293204949598a23f501be6eec21697465fd46a28840aDmitry Shmidt } else if (dev->go_neg_req_sent) { 293304949598a23f501be6eec21697465fd46a28840aDmitry Shmidt /* Cancel the increment from p2p_connect_send() on failure */ 293498f9e76624da6bb96edc1982c423e4a119c5170aDmitry Shmidt dev->go_neg_req_sent--; 293598f9e76624da6bb96edc1982c423e4a119c5170aDmitry Shmidt } 29368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 29378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (!success && 29388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt (dev->info.dev_capab & P2P_DEV_CAPAB_CLIENT_DISCOVERABILITY) && 29398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt !is_zero_ether_addr(dev->member_in_go_dev)) { 29408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG, 29418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "P2P: Peer " MACSTR " did not acknowledge request - " 29428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "try to use device discoverability through its GO", 29438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt MAC2STR(dev->info.p2p_device_addr)); 29448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p->cfg->send_action_done(p2p->cfg->cb_ctx); 29458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_send_dev_disc_req(p2p, dev); 29468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; 29478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 29488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 29498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* 29508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * Use P2P find, if needed, to find the other device from its listen 29518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * channel. 29528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */ 29538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_set_state(p2p, P2P_CONNECT); 29541a2ce111ade9563d99ed7bb8156d6148ffd6c3a3Irfan Sheriff#ifdef ANDROID_P2P 29551a2ce111ade9563d99ed7bb8156d6148ffd6c3a3Irfan Sheriff p2p_set_timeout(p2p, 0, 350000); 29561a2ce111ade9563d99ed7bb8156d6148ffd6c3a3Irfan Sheriff#else 295761d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt p2p_set_timeout(p2p, 0, success ? 200000 : 100000); 29581a2ce111ade9563d99ed7bb8156d6148ffd6c3a3Irfan Sheriff#endif 29598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 29608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 29618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 29628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic void p2p_go_neg_resp_cb(struct p2p_data *p2p, int success) 29638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 29648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG, 29658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "P2P: GO Negotiation Response TX callback: success=%d", 29668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt success); 29678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (!p2p->go_neg_peer && p2p->state == P2P_PROVISIONING) { 29688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG, 29698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "P2P: Ignore TX callback event - GO Negotiation is " 29708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "not running anymore"); 29718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; 29728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 29738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_set_state(p2p, P2P_CONNECT); 29741a2ce111ade9563d99ed7bb8156d6148ffd6c3a3Irfan Sheriff#ifdef ANDROID_P2P 29751a2ce111ade9563d99ed7bb8156d6148ffd6c3a3Irfan Sheriff p2p_set_timeout(p2p, 0, 350000); 29761a2ce111ade9563d99ed7bb8156d6148ffd6c3a3Irfan Sheriff#else 297761d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt p2p_set_timeout(p2p, 0, 250000); 29781a2ce111ade9563d99ed7bb8156d6148ffd6c3a3Irfan Sheriff#endif 29798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 29808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 29818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 29828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic void p2p_go_neg_resp_failure_cb(struct p2p_data *p2p, int success) 29838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 29848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG, 29858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "P2P: GO Negotiation Response (failure) TX callback: " 29868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "success=%d", success); 29878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (p2p->go_neg_peer && p2p->go_neg_peer->status != P2P_SC_SUCCESS) { 29888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_go_neg_failed(p2p, p2p->go_neg_peer, 29898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p->go_neg_peer->status); 29908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 29918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 29928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 29938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 29948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic void p2p_go_neg_conf_cb(struct p2p_data *p2p, 29958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt enum p2p_send_action_result result) 29968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 29978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct p2p_device *dev; 29988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 29998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG, 30008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "P2P: GO Negotiation Confirm TX callback: result=%d", 30018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt result); 30028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p->cfg->send_action_done(p2p->cfg->cb_ctx); 30038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (result == P2P_SEND_ACTION_FAILED) { 30048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_go_neg_failed(p2p, p2p->go_neg_peer, -1); 30058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; 30068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 30078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (result == P2P_SEND_ACTION_NO_ACK) { 30088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* 30098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * It looks like the TX status for GO Negotiation Confirm is 30108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * often showing failure even when the peer has actually 30118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * received the frame. Since the peer may change channels 30128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * immediately after having received the frame, we may not see 30138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * an Ack for retries, so just dropping a single frame may 30148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * trigger this. To allow the group formation to succeed if the 30158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * peer did indeed receive the frame, continue regardless of 30168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * the TX status. 30178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */ 30188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG, 30198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "P2P: Assume GO Negotiation Confirm TX was actually " 30208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "received by the peer even though Ack was not " 30218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "reported"); 30228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 30238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 30248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt dev = p2p->go_neg_peer; 30258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (dev == NULL) 30268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; 30278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 30288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_go_complete(p2p, dev); 30298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 30308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 30318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 30328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtvoid p2p_send_action_cb(struct p2p_data *p2p, unsigned int freq, const u8 *dst, 30338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt const u8 *src, const u8 *bssid, 30348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt enum p2p_send_action_result result) 30358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 30368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt enum p2p_pending_action_state state; 30378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt int success; 30388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 30398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG, 30408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "P2P: Action frame TX callback (state=%d freq=%u dst=" MACSTR 30418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt " src=" MACSTR " bssid=" MACSTR " result=%d", 30428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p->pending_action_state, freq, MAC2STR(dst), MAC2STR(src), 30438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt MAC2STR(bssid), result); 30448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt success = result == P2P_SEND_ACTION_SUCCESS; 30458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt state = p2p->pending_action_state; 30468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p->pending_action_state = P2P_NO_PENDING_ACTION; 30478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt switch (state) { 30488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case P2P_NO_PENDING_ACTION: 30498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 30508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case P2P_PENDING_GO_NEG_REQUEST: 30518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_go_neg_req_cb(p2p, success); 30528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 30538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case P2P_PENDING_GO_NEG_RESPONSE: 30548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_go_neg_resp_cb(p2p, success); 30558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 30568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case P2P_PENDING_GO_NEG_RESPONSE_FAILURE: 30578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_go_neg_resp_failure_cb(p2p, success); 30588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 30598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case P2P_PENDING_GO_NEG_CONFIRM: 30608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_go_neg_conf_cb(p2p, result); 30618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 30628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case P2P_PENDING_SD: 30638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_sd_cb(p2p, success); 30648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 30658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case P2P_PENDING_PD: 30668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_prov_disc_cb(p2p, success); 30678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 30688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case P2P_PENDING_INVITATION_REQUEST: 30698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_invitation_req_cb(p2p, success); 30708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 30718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case P2P_PENDING_INVITATION_RESPONSE: 30728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_invitation_resp_cb(p2p, success); 30738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 30748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case P2P_PENDING_DEV_DISC_REQUEST: 30758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_dev_disc_req_cb(p2p, success); 30768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 30778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case P2P_PENDING_DEV_DISC_RESPONSE: 30788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_dev_disc_resp_cb(p2p, success); 30798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 30808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case P2P_PENDING_GO_DISC_REQ: 30818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_go_disc_req_cb(p2p, success); 30828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 30838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 30848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 30858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 30868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 30878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtvoid p2p_listen_cb(struct p2p_data *p2p, unsigned int freq, 30888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt unsigned int duration) 30898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 30908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (freq == p2p->pending_client_disc_freq) { 30918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG, 30928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "P2P: Client discoverability remain-awake completed"); 30938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p->pending_client_disc_freq = 0; 30948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; 30958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 30968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 30978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (freq != p2p->pending_listen_freq) { 30988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG, 30998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "P2P: Unexpected listen callback for freq=%u " 31008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "duration=%u (pending_listen_freq=%u)", 31018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt freq, duration, p2p->pending_listen_freq); 31028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; 31038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 31048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 31058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG, 31068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "P2P: Starting Listen timeout(%u,%u) on freq=%u based on " 31078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "callback", 31088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p->pending_listen_sec, p2p->pending_listen_usec, 31098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p->pending_listen_freq); 31108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p->in_listen = 1; 31118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p->drv_in_listen = freq; 31128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (p2p->pending_listen_sec || p2p->pending_listen_usec) { 31138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* 31148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * Add 20 msec extra wait to avoid race condition with driver 31158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * remain-on-channel end event, i.e., give driver more time to 31168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * complete the operation before our timeout expires. 31178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */ 31188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_set_timeout(p2p, p2p->pending_listen_sec, 31198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p->pending_listen_usec + 20000); 31208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 31218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 31228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p->pending_listen_freq = 0; 31238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 31248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 31258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 31268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtint p2p_listen_end(struct p2p_data *p2p, unsigned int freq) 31278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 31288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG, "P2P: Driver ended Listen " 31298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "state (freq=%u)", freq); 31308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p->drv_in_listen = 0; 31318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (p2p->in_listen) 31328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; /* Internal timeout will trigger the next step */ 31338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 31348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (p2p->state == P2P_CONNECT_LISTEN && p2p->go_neg_peer) { 31358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (p2p->go_neg_peer->connect_reqs >= 120) { 31368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG, 31378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "P2P: Timeout on sending GO Negotiation " 31388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "Request without getting response"); 31398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_go_neg_failed(p2p, p2p->go_neg_peer, -1); 31408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 31418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 31428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 31438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_set_state(p2p, P2P_CONNECT); 31448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_connect_send(p2p, p2p->go_neg_peer); 31458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 1; 31468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } else if (p2p->state == P2P_SEARCH) { 3147c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt if (p2p->p2p_scan_running) { 3148c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt /* 3149c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt * Search is already in progress. This can happen if 3150c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt * an Action frame RX is reported immediately after 3151c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt * the end of a remain-on-channel operation and the 3152c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt * response frame to that is sent using an offchannel 3153c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt * operation while in p2p_find. Avoid an attempt to 3154c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt * restart a scan here. 3155c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt */ 3156c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG, "P2P: p2p_scan " 3157c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt "already in progress - do not try to start a " 3158c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt "new one"); 3159c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt return 1; 3160c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt } 316104949598a23f501be6eec21697465fd46a28840aDmitry Shmidt if (p2p->pending_listen_freq) { 316204949598a23f501be6eec21697465fd46a28840aDmitry Shmidt /* 316304949598a23f501be6eec21697465fd46a28840aDmitry Shmidt * Better wait a bit if the driver is unable to start 316404949598a23f501be6eec21697465fd46a28840aDmitry Shmidt * offchannel operation for some reason. p2p_search() 316504949598a23f501be6eec21697465fd46a28840aDmitry Shmidt * will be started from internal timeout. 316604949598a23f501be6eec21697465fd46a28840aDmitry Shmidt */ 316704949598a23f501be6eec21697465fd46a28840aDmitry Shmidt wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG, "P2P: Listen " 316804949598a23f501be6eec21697465fd46a28840aDmitry Shmidt "operation did not seem to start - delay " 316904949598a23f501be6eec21697465fd46a28840aDmitry Shmidt "search phase to avoid busy loop"); 317004949598a23f501be6eec21697465fd46a28840aDmitry Shmidt p2p_set_timeout(p2p, 0, 100000); 317104949598a23f501be6eec21697465fd46a28840aDmitry Shmidt return 1; 317204949598a23f501be6eec21697465fd46a28840aDmitry Shmidt } 317361d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt if (p2p->search_delay) { 317461d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG, "P2P: Delay " 317561d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt "search operation by %u ms", 317661d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt p2p->search_delay); 317761d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt p2p_set_timeout(p2p, p2p->search_delay / 1000, 317861d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt (p2p->search_delay % 1000) * 1000); 317961d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt return 1; 318061d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt } 31818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_search(p2p); 31828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 1; 31838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 31848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 31858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 31868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 31878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 31888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 31898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic void p2p_timeout_connect(struct p2p_data *p2p) 31908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 31918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p->cfg->send_action_done(p2p->cfg->cb_ctx); 319204949598a23f501be6eec21697465fd46a28840aDmitry Shmidt if (p2p->go_neg_peer && 319304949598a23f501be6eec21697465fd46a28840aDmitry Shmidt (p2p->go_neg_peer->flags & P2P_DEV_WAIT_GO_NEG_CONFIRM)) { 319404949598a23f501be6eec21697465fd46a28840aDmitry Shmidt wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG, "P2P: Wait for GO " 319504949598a23f501be6eec21697465fd46a28840aDmitry Shmidt "Negotiation Confirm timed out - assume GO " 319604949598a23f501be6eec21697465fd46a28840aDmitry Shmidt "Negotiation failed"); 319704949598a23f501be6eec21697465fd46a28840aDmitry Shmidt p2p_go_neg_failed(p2p, p2p->go_neg_peer, -1); 319804949598a23f501be6eec21697465fd46a28840aDmitry Shmidt return; 319904949598a23f501be6eec21697465fd46a28840aDmitry Shmidt } 32008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_set_state(p2p, P2P_CONNECT_LISTEN); 32018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_listen_in_find(p2p); 32028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 32038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 32048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 32058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic void p2p_timeout_connect_listen(struct p2p_data *p2p) 32068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 32078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (p2p->go_neg_peer) { 32088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (p2p->drv_in_listen) { 32098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG, "P2P: Driver is " 32108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "still in Listen state; wait for it to " 32118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "complete"); 32128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; 32138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 32148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 32158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (p2p->go_neg_peer->connect_reqs >= 120) { 32168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG, 32178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "P2P: Timeout on sending GO Negotiation " 32188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "Request without getting response"); 32198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_go_neg_failed(p2p, p2p->go_neg_peer, -1); 32208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; 32218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 32228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 32238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_set_state(p2p, P2P_CONNECT); 32248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_connect_send(p2p, p2p->go_neg_peer); 32258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } else 32268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_set_state(p2p, P2P_IDLE); 32278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 32288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 32298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 32308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic void p2p_timeout_wait_peer_connect(struct p2p_data *p2p) 32318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 32328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* 32338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * TODO: could remain constantly in Listen state for some time if there 32348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * are no other concurrent uses for the radio. For now, go to listen 32358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * state once per second to give other uses a chance to use the radio. 32368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */ 32378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_set_state(p2p, P2P_WAIT_PEER_IDLE); 32381f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt p2p_set_timeout(p2p, 0, 500000); 32398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 32408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 32418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 32428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic void p2p_timeout_wait_peer_idle(struct p2p_data *p2p) 32438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 32448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct p2p_device *dev = p2p->go_neg_peer; 32458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 32468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (dev == NULL) { 32478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG, 32488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "P2P: Unknown GO Neg peer - stop GO Neg wait"); 32498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; 32508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 32518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 32528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt dev->wait_count++; 32538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (dev->wait_count >= 120) { 32548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG, 32558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "P2P: Timeout on waiting peer to become ready for GO " 32568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "Negotiation"); 32578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_go_neg_failed(p2p, dev, -1); 32588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; 32598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 32608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 32618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG, 32628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "P2P: Go to Listen state while waiting for the peer to become " 32638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "ready for GO Negotiation"); 32648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_set_state(p2p, P2P_WAIT_PEER_CONNECT); 32658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_listen_in_find(p2p); 32668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 32678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 32688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 32698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic void p2p_timeout_sd_during_find(struct p2p_data *p2p) 32708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 32718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG, 32728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "P2P: Service Discovery Query timeout"); 32738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (p2p->sd_peer) { 32748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p->cfg->send_action_done(p2p->cfg->cb_ctx); 32758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p->sd_peer->flags &= ~P2P_DEV_SD_SCHEDULE; 32768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p->sd_peer = NULL; 32778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 32788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_continue_find(p2p); 32798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 32808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 32818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 32828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic void p2p_timeout_prov_disc_during_find(struct p2p_data *p2p) 32838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 32848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG, 32858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "P2P: Provision Discovery Request timeout"); 32868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p->cfg->send_action_done(p2p->cfg->cb_ctx); 32878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_continue_find(p2p); 32888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 32898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 32908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 329175ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinenstatic void p2p_timeout_prov_disc_req(struct p2p_data *p2p) 329275ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen{ 329375ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen p2p->pending_action_state = P2P_NO_PENDING_ACTION; 329475ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen 329575ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen /* 329675ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen * For user initiated PD requests that we have not gotten any responses 329775ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen * for while in IDLE state, we retry them a couple of times before 329875ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen * giving up. 329975ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen */ 330075ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen if (!p2p->user_initiated_pd) 330175ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen return; 330275ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen 330375ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG, 330475ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen "P2P: User initiated Provision Discovery Request timeout"); 330575ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen 330675ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen if (p2p->pd_retries) { 330775ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen p2p->pd_retries--; 330875ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen p2p_retry_pd(p2p); 330975ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen } else { 331075ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen if (p2p->cfg->prov_disc_fail) 331175ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen p2p->cfg->prov_disc_fail(p2p->cfg->cb_ctx, 331275ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen p2p->pending_pd_devaddr, 331375ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen P2P_PROV_DISC_TIMEOUT); 331475ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen p2p_reset_pending_pd(p2p); 331575ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen } 331675ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen} 331775ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen 331875ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen 33198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic void p2p_timeout_invite(struct p2p_data *p2p) 33208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 33218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p->cfg->send_action_done(p2p->cfg->cb_ctx); 33228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_set_state(p2p, P2P_INVITE_LISTEN); 33238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (p2p->inv_role == P2P_INVITE_ROLE_ACTIVE_GO) { 33248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* 33258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * Better remain on operating channel instead of listen channel 33268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * when running a group. 33278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */ 33288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG, "P2P: Inviting in " 33298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "active GO role - wait on operating channel"); 33308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_set_timeout(p2p, 0, 100000); 33318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; 33328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 33338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_listen_in_find(p2p); 33348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 33358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 33368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 33378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic void p2p_timeout_invite_listen(struct p2p_data *p2p) 33388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 33398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (p2p->invite_peer && p2p->invite_peer->invitation_reqs < 100) { 33408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_set_state(p2p, P2P_INVITE); 33418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_invite_send(p2p, p2p->invite_peer, 33428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p->invite_go_dev_addr); 33438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } else { 33448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (p2p->invite_peer) { 33458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG, 33468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "P2P: Invitation Request retry limit reached"); 33478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (p2p->cfg->invitation_result) 33488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p->cfg->invitation_result( 33498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p->cfg->cb_ctx, -1, NULL); 33508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 33518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_set_state(p2p, P2P_IDLE); 33528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 33538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 33548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 33558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 33568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic void p2p_state_timeout(void *eloop_ctx, void *timeout_ctx) 33578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 33588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct p2p_data *p2p = eloop_ctx; 33598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 33608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG, "P2P: Timeout (state=%s)", 33618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_state_txt(p2p->state)); 33628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 33638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p->in_listen = 0; 33648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 33658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt switch (p2p->state) { 33668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case P2P_IDLE: 336775ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen /* Check if we timed out waiting for PD req */ 336875ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen if (p2p->pending_action_state == P2P_PENDING_PD) 336975ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen p2p_timeout_prov_disc_req(p2p); 33708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 33718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case P2P_SEARCH: 337275ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen /* Check if we timed out waiting for PD req */ 337375ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen if (p2p->pending_action_state == P2P_PENDING_PD) 337475ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen p2p_timeout_prov_disc_req(p2p); 337561d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt if (p2p->search_delay && !p2p->in_search_delay) { 337661d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG, "P2P: Delay " 337761d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt "search operation by %u ms", 337861d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt p2p->search_delay); 337961d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt p2p->in_search_delay = 1; 338061d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt p2p_set_timeout(p2p, p2p->search_delay / 1000, 338161d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt (p2p->search_delay % 1000) * 1000); 338261d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt break; 338361d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt } 338461d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt p2p->in_search_delay = 0; 33858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_search(p2p); 33868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 33878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case P2P_CONNECT: 33888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_timeout_connect(p2p); 33898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 33908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case P2P_CONNECT_LISTEN: 33918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_timeout_connect_listen(p2p); 33928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 33938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case P2P_GO_NEG: 33948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 33958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case P2P_LISTEN_ONLY: 339675ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen /* Check if we timed out waiting for PD req */ 339775ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen if (p2p->pending_action_state == P2P_PENDING_PD) 339875ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen p2p_timeout_prov_disc_req(p2p); 339975ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen 34008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (p2p->ext_listen_only) { 34018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG, 34028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "P2P: Extended Listen Timing - Listen State " 34038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "completed"); 34048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p->ext_listen_only = 0; 34058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_set_state(p2p, P2P_IDLE); 34068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 34078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 34088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case P2P_WAIT_PEER_CONNECT: 34098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_timeout_wait_peer_connect(p2p); 34108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 34118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case P2P_WAIT_PEER_IDLE: 34128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_timeout_wait_peer_idle(p2p); 34138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 34148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case P2P_SD_DURING_FIND: 34158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_timeout_sd_during_find(p2p); 34168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 34178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case P2P_PROVISIONING: 34188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 34198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case P2P_PD_DURING_FIND: 34208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_timeout_prov_disc_during_find(p2p); 34218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 34228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case P2P_INVITE: 34238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_timeout_invite(p2p); 34248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 34258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case P2P_INVITE_LISTEN: 34268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_timeout_invite_listen(p2p); 34278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 34281f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt case P2P_SEARCH_WHEN_READY: 34291f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt break; 343061d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt case P2P_CONTINUE_SEARCH_WHEN_READY: 343161d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt break; 34328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 34338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 34348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 34358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 34368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtint p2p_reject(struct p2p_data *p2p, const u8 *peer_addr) 34378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 34388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct p2p_device *dev; 34398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 34408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt dev = p2p_get_device(p2p, peer_addr); 34418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG, "P2P: Local request to reject " 34428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "connection attempts by peer " MACSTR, MAC2STR(peer_addr)); 34438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (dev == NULL) { 34448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG, "P2P: Peer " MACSTR 34458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt " unknown", MAC2STR(peer_addr)); 34468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 34478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 34488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt dev->status = P2P_SC_FAIL_REJECTED_BY_USER; 34498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt dev->flags |= P2P_DEV_USER_REJECTED; 34508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 34518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 34528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 34538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 34541f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidtconst char * p2p_wps_method_text(enum p2p_wps_method method) 34558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 34568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt switch (method) { 34578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case WPS_NOT_READY: 34588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return "not-ready"; 34598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case WPS_PIN_DISPLAY: 34608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return "Display"; 34618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case WPS_PIN_KEYPAD: 34628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return "Keypad"; 34638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case WPS_PBC: 34648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return "PBC"; 34658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 34668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 34678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return "??"; 34688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 34698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 34708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 34718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic const char * p2p_go_state_text(enum p2p_go_state go_state) 34728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 34738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt switch (go_state) { 34748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case UNKNOWN_GO: 34758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return "unknown"; 34768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case LOCAL_GO: 34778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return "local"; 34788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case REMOTE_GO: 34798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return "remote"; 34808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 34818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 34828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return "??"; 34838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 34848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 34858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 34861f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidtconst struct p2p_peer_info * p2p_get_peer_info(struct p2p_data *p2p, 34871f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt const u8 *addr, int next) 34888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 34898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct p2p_device *dev; 34908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 34918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (addr) 34928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt dev = p2p_get_device(p2p, addr); 34938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt else 34948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt dev = dl_list_first(&p2p->devices, struct p2p_device, list); 34958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 34968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (dev && next) { 34978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt dev = dl_list_first(&dev->list, struct p2p_device, list); 34988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (&dev->list == &p2p->devices) 34998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt dev = NULL; 35008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 35018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 35028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (dev == NULL) 35031f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt return NULL; 35041f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt 35051f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt return &dev->info; 35061f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt} 35071f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt 35081f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt 35091f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidtint p2p_get_peer_info_txt(const struct p2p_peer_info *info, 35101f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt char *buf, size_t buflen) 35111f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt{ 35121f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt struct p2p_device *dev; 35131f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt int res; 35141f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt char *pos, *end; 35151f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt struct os_time now; 35161f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt 35171f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt if (info == NULL) 35188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 35198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 35201f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt dev = (struct p2p_device *) (((u8 *) info) - 35211f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt offsetof(struct p2p_device, info)); 35221f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt 35238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt pos = buf; 35248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt end = buf + buflen; 35258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 35268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_get_time(&now); 35278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt res = os_snprintf(pos, end - pos, 35288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "age=%d\n" 35298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "listen_freq=%d\n" 35308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "wps_method=%s\n" 35318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "interface_addr=" MACSTR "\n" 35328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "member_in_go_dev=" MACSTR "\n" 35338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "member_in_go_iface=" MACSTR "\n" 35348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "go_neg_req_sent=%d\n" 35358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "go_state=%s\n" 35368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "dialog_token=%u\n" 35378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "intended_addr=" MACSTR "\n" 35388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "country=%c%c\n" 35398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "oper_freq=%d\n" 35408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "req_config_methods=0x%x\n" 35418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "flags=%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s\n" 35428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "status=%d\n" 35438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "wait_count=%u\n" 35448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "invitation_reqs=%u\n", 35458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt (int) (now.sec - dev->last_seen.sec), 35468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt dev->listen_freq, 35478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_wps_method_text(dev->wps_method), 35488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt MAC2STR(dev->interface_addr), 35498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt MAC2STR(dev->member_in_go_dev), 35508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt MAC2STR(dev->member_in_go_iface), 35518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt dev->go_neg_req_sent, 35528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_go_state_text(dev->go_state), 35538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt dev->dialog_token, 35548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt MAC2STR(dev->intended_addr), 35558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt dev->country[0] ? dev->country[0] : '_', 35568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt dev->country[1] ? dev->country[1] : '_', 35578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt dev->oper_freq, 35588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt dev->req_config_methods, 35598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt dev->flags & P2P_DEV_PROBE_REQ_ONLY ? 35608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "[PROBE_REQ_ONLY]" : "", 35618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt dev->flags & P2P_DEV_REPORTED ? "[REPORTED]" : "", 35628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt dev->flags & P2P_DEV_NOT_YET_READY ? 35638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "[NOT_YET_READY]" : "", 35648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt dev->flags & P2P_DEV_SD_INFO ? "[SD_INFO]" : "", 35658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt dev->flags & P2P_DEV_SD_SCHEDULE ? "[SD_SCHEDULE]" : 35668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "", 35678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt dev->flags & P2P_DEV_PD_PEER_DISPLAY ? 35688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "[PD_PEER_DISPLAY]" : "", 35698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt dev->flags & P2P_DEV_PD_PEER_KEYPAD ? 35708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "[PD_PEER_KEYPAD]" : "", 35718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt dev->flags & P2P_DEV_USER_REJECTED ? 35728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "[USER_REJECTED]" : "", 35738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt dev->flags & P2P_DEV_PEER_WAITING_RESPONSE ? 35748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "[PEER_WAITING_RESPONSE]" : "", 35758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt dev->flags & P2P_DEV_PREFER_PERSISTENT_GROUP ? 35768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "[PREFER_PERSISTENT_GROUP]" : "", 35778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt dev->flags & P2P_DEV_WAIT_GO_NEG_RESPONSE ? 35788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "[WAIT_GO_NEG_RESPONSE]" : "", 35798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt dev->flags & P2P_DEV_WAIT_GO_NEG_CONFIRM ? 35808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "[WAIT_GO_NEG_CONFIRM]" : "", 35818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt dev->flags & P2P_DEV_GROUP_CLIENT_ONLY ? 35828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "[GROUP_CLIENT_ONLY]" : "", 35838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt dev->flags & P2P_DEV_FORCE_FREQ ? 35848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "[FORCE_FREQ]" : "", 35858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt dev->flags & P2P_DEV_PD_FOR_JOIN ? 35868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "[PD_FOR_JOIN]" : "", 35878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt dev->status, 35888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt dev->wait_count, 35898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt dev->invitation_reqs); 35908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (res < 0 || res >= end - pos) 35918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return pos - buf; 35928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt pos += res; 35938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 35948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (dev->ext_listen_period) { 35958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt res = os_snprintf(pos, end - pos, 35968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "ext_listen_period=%u\n" 35978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "ext_listen_interval=%u\n", 35988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt dev->ext_listen_period, 35998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt dev->ext_listen_interval); 36008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (res < 0 || res >= end - pos) 36018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return pos - buf; 36028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt pos += res; 36038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 36048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 36058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (dev->oper_ssid_len) { 36068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt res = os_snprintf(pos, end - pos, 36078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "oper_ssid=%s\n", 36088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_ssid_txt(dev->oper_ssid, 36098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt dev->oper_ssid_len)); 36108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (res < 0 || res >= end - pos) 36118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return pos - buf; 36128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt pos += res; 36138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 36148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 361561d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt#ifdef CONFIG_WIFI_DISPLAY 361661d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt if (dev->info.wfd_subelems) { 361761d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt res = os_snprintf(pos, end - pos, "wfd_subelems="); 361861d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt if (res < 0 || res >= end - pos) 361961d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt return pos - buf; 362061d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt pos += res; 362161d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt 362261d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt pos += wpa_snprintf_hex(pos, end - pos, 362361d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt wpabuf_head(dev->info.wfd_subelems), 362461d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt wpabuf_len(dev->info.wfd_subelems)); 362561d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt 362661d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt res = os_snprintf(pos, end - pos, "\n"); 362761d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt if (res < 0 || res >= end - pos) 362861d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt return pos - buf; 362961d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt pos += res; 363061d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt } 363161d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt#endif /* CONFIG_WIFI_DISPLAY */ 363261d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt 36338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return pos - buf; 36348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 36358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 36368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 36371f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidtint p2p_peer_known(struct p2p_data *p2p, const u8 *addr) 36381f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt{ 36391f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt return p2p_get_device(p2p, addr) != NULL; 36401f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt} 36411f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt 36421f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt 36438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtvoid p2p_set_client_discoverability(struct p2p_data *p2p, int enabled) 36448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 36458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (enabled) { 36468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG, "P2P: Client " 36478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "discoverability enabled"); 36488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p->dev_capab |= P2P_DEV_CAPAB_CLIENT_DISCOVERABILITY; 36498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } else { 36508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG, "P2P: Client " 36518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "discoverability disabled"); 36528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p->dev_capab &= ~P2P_DEV_CAPAB_CLIENT_DISCOVERABILITY; 36538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 36548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 36558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 36568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 36578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic struct wpabuf * p2p_build_presence_req(u32 duration1, u32 interval1, 36588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt u32 duration2, u32 interval2) 36598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 36608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct wpabuf *req; 36618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct p2p_noa_desc desc1, desc2, *ptr1 = NULL, *ptr2 = NULL; 36628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt u8 *len; 36638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 36648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt req = wpabuf_alloc(100); 36658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (req == NULL) 36668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return NULL; 36678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 36688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (duration1 || interval1) { 36698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memset(&desc1, 0, sizeof(desc1)); 36708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt desc1.count_type = 1; 36718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt desc1.duration = duration1; 36728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt desc1.interval = interval1; 36738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ptr1 = &desc1; 36748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 36758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (duration2 || interval2) { 36768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memset(&desc2, 0, sizeof(desc2)); 36778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt desc2.count_type = 2; 36788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt desc2.duration = duration2; 36798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt desc2.interval = interval2; 36808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ptr2 = &desc2; 36818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 36828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 36838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 36848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_buf_add_action_hdr(req, P2P_PRESENCE_REQ, 1); 36858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt len = p2p_buf_add_ie_hdr(req); 36868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_buf_add_noa(req, 0, 0, 0, ptr1, ptr2); 36878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_buf_update_ie_hdr(req, len); 36888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 36898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return req; 36908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 36918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 36928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 36938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtint p2p_presence_req(struct p2p_data *p2p, const u8 *go_interface_addr, 36948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt const u8 *own_interface_addr, unsigned int freq, 36958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt u32 duration1, u32 interval1, u32 duration2, 36968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt u32 interval2) 36978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 36988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct wpabuf *req; 36998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 37008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG, "P2P: Send Presence Request to " 37018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "GO " MACSTR " (own interface " MACSTR ") freq=%u dur1=%u " 37028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "int1=%u dur2=%u int2=%u", 37038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt MAC2STR(go_interface_addr), MAC2STR(own_interface_addr), 37048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt freq, duration1, interval1, duration2, interval2); 37058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 37068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt req = p2p_build_presence_req(duration1, interval1, duration2, 37078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt interval2); 37088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (req == NULL) 37098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 37108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 37118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p->pending_action_state = P2P_NO_PENDING_ACTION; 37128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (p2p_send_action(p2p, freq, go_interface_addr, own_interface_addr, 37138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt go_interface_addr, 37148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpabuf_head(req), wpabuf_len(req), 200) < 0) { 37158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG, 37168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "P2P: Failed to send Action frame"); 37178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 37188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpabuf_free(req); 37198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 37208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 37218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 37228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 37238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 37248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic struct wpabuf * p2p_build_presence_resp(u8 status, const u8 *noa, 37258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt size_t noa_len, u8 dialog_token) 37268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 37278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct wpabuf *resp; 37288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt u8 *len; 37298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 37308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt resp = wpabuf_alloc(100 + noa_len); 37318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (resp == NULL) 37328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return NULL; 37338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 37348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_buf_add_action_hdr(resp, P2P_PRESENCE_RESP, dialog_token); 37358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt len = p2p_buf_add_ie_hdr(resp); 37368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_buf_add_status(resp, status); 37378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (noa) { 37388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpabuf_put_u8(resp, P2P_ATTR_NOTICE_OF_ABSENCE); 37398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpabuf_put_le16(resp, noa_len); 37408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpabuf_put_data(resp, noa, noa_len); 37418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } else 37428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_buf_add_noa(resp, 0, 0, 0, NULL, NULL); 37438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_buf_update_ie_hdr(resp, len); 37448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 37458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return resp; 37468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 37478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 37488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 37498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic void p2p_process_presence_req(struct p2p_data *p2p, const u8 *da, 37508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt const u8 *sa, const u8 *data, size_t len, 37518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt int rx_freq) 37528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 37538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct p2p_message msg; 37548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt u8 status; 37558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct wpabuf *resp; 37568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt size_t g; 37578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct p2p_group *group = NULL; 37588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt int parsed = 0; 37598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt u8 noa[50]; 37608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt int noa_len; 37618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 37628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG, 37638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "P2P: Received P2P Action - P2P Presence Request"); 37648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 37658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt for (g = 0; g < p2p->num_groups; g++) { 37668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (os_memcmp(da, p2p_group_get_interface_addr(p2p->groups[g]), 37678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ETH_ALEN) == 0) { 37688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt group = p2p->groups[g]; 37698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 37708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 37718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 37728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (group == NULL) { 37738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG, 37748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "P2P: Ignore P2P Presence Request for unknown group " 37758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt MACSTR, MAC2STR(da)); 37768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; 37778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 37788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 37798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (p2p_parse(data, len, &msg) < 0) { 37808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG, 37818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "P2P: Failed to parse P2P Presence Request"); 37828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt status = P2P_SC_FAIL_INVALID_PARAMS; 37838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt goto fail; 37848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 37858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt parsed = 1; 37868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 37878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (msg.noa == NULL) { 37888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG, 37898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "P2P: No NoA attribute in P2P Presence Request"); 37908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt status = P2P_SC_FAIL_INVALID_PARAMS; 37918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt goto fail; 37928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 37938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 37948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt status = p2p_group_presence_req(group, sa, msg.noa, msg.noa_len); 37958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 37968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtfail: 37978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (p2p->cfg->get_noa) 37988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt noa_len = p2p->cfg->get_noa(p2p->cfg->cb_ctx, da, noa, 37998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sizeof(noa)); 38008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt else 38018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt noa_len = -1; 38028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt resp = p2p_build_presence_resp(status, noa_len > 0 ? noa : NULL, 38038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt noa_len > 0 ? noa_len : 0, 38048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt msg.dialog_token); 38058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (parsed) 38068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_parse_free(&msg); 38078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (resp == NULL) 38088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; 38098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 38108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p->pending_action_state = P2P_NO_PENDING_ACTION; 38118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (p2p_send_action(p2p, rx_freq, sa, da, da, 38128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpabuf_head(resp), wpabuf_len(resp), 200) < 0) { 38138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG, 38148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "P2P: Failed to send Action frame"); 38158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 38168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpabuf_free(resp); 38178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 38188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 38198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 38208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic void p2p_process_presence_resp(struct p2p_data *p2p, const u8 *da, 38218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt const u8 *sa, const u8 *data, size_t len) 38228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 38238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct p2p_message msg; 38248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 38258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG, 38268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "P2P: Received P2P Action - P2P Presence Response"); 38278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 38288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (p2p_parse(data, len, &msg) < 0) { 38298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG, 38308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "P2P: Failed to parse P2P Presence Response"); 38318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; 38328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 38338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 38348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (msg.status == NULL || msg.noa == NULL) { 38358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG, 38368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "P2P: No Status or NoA attribute in P2P Presence " 38378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "Response"); 38388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_parse_free(&msg); 38398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; 38408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 38418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 38428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (*msg.status) { 38438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG, 38448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "P2P: P2P Presence Request was rejected: status %u", 38458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt *msg.status); 38468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_parse_free(&msg); 38478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; 38488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 38498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 38508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG, 38518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "P2P: P2P Presence Request was accepted"); 38528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_hexdump(MSG_DEBUG, "P2P: P2P Presence Response - NoA", 38538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt msg.noa, msg.noa_len); 38548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* TODO: process NoA */ 38558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_parse_free(&msg); 38568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 38578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 38588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 38598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic void p2p_ext_listen_timeout(void *eloop_ctx, void *timeout_ctx) 38608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 38618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct p2p_data *p2p = eloop_ctx; 38628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 38638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (p2p->ext_listen_interval) { 38648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* Schedule next extended listen timeout */ 38658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt eloop_register_timeout(p2p->ext_listen_interval_sec, 38668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p->ext_listen_interval_usec, 38678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_ext_listen_timeout, p2p, NULL); 38688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 38698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 38708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (p2p->state == P2P_LISTEN_ONLY && p2p->ext_listen_only) { 38718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* 38728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * This should not really happen, but it looks like the Listen 38738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * command may fail is something else (e.g., a scan) was 38748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * running at an inconvenient time. As a workaround, allow new 38758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * Extended Listen operation to be started. 38768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */ 38778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG, "P2P: Previous " 38788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "Extended Listen operation had not been completed - " 38798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "try again"); 38808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p->ext_listen_only = 0; 38818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_set_state(p2p, P2P_IDLE); 38828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 38838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 38848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (p2p->state != P2P_IDLE) { 38858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG, "P2P: Skip Extended " 38868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "Listen timeout in active state (%s)", 38878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_state_txt(p2p->state)); 38888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; 38898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 38908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 38918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG, "P2P: Extended Listen timeout"); 38928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p->ext_listen_only = 1; 38938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (p2p_listen(p2p, p2p->ext_listen_period) < 0) { 38948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG, "P2P: Failed to start " 38958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "Listen state for Extended Listen Timing"); 38968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p->ext_listen_only = 0; 38978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 38988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 38998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 39008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 39018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtint p2p_ext_listen(struct p2p_data *p2p, unsigned int period, 39028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt unsigned int interval) 39038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 39048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (period > 65535 || interval > 65535 || period > interval || 39058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt (period == 0 && interval > 0) || (period > 0 && interval == 0)) { 39068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG, 39078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "P2P: Invalid Extended Listen Timing request: " 39088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "period=%u interval=%u", period, interval); 39098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 39108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 39118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 39128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt eloop_cancel_timeout(p2p_ext_listen_timeout, p2p, NULL); 39138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 39148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (interval == 0) { 39158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG, 39168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "P2P: Disabling Extended Listen Timing"); 39178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p->ext_listen_period = 0; 39188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p->ext_listen_interval = 0; 39198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 39208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 39218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 39228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG, 39238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "P2P: Enabling Extended Listen Timing: period %u msec, " 39248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "interval %u msec", period, interval); 39258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p->ext_listen_period = period; 39268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p->ext_listen_interval = interval; 39278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p->ext_listen_interval_sec = interval / 1000; 39288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p->ext_listen_interval_usec = (interval % 1000) * 1000; 39298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 39308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt eloop_register_timeout(p2p->ext_listen_interval_sec, 39318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p->ext_listen_interval_usec, 39328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_ext_listen_timeout, p2p, NULL); 39338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 39348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 39358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 39368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 39378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 39388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtvoid p2p_deauth_notif(struct p2p_data *p2p, const u8 *bssid, u16 reason_code, 39398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt const u8 *ie, size_t ie_len) 39408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 39418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct p2p_message msg; 39428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 39438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (bssid == NULL || ie == NULL) 39448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; 39458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 39468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memset(&msg, 0, sizeof(msg)); 39478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (p2p_parse_ies(ie, ie_len, &msg)) 39488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; 39498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (msg.minor_reason_code == NULL) 39508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; 39518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 39528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_msg(p2p->cfg->msg_ctx, MSG_INFO, 39538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "P2P: Deauthentication notification BSSID " MACSTR 39548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt " reason_code=%u minor_reason_code=%u", 39558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt MAC2STR(bssid), reason_code, *msg.minor_reason_code); 39568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 39578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_parse_free(&msg); 39588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 39598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 39608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 39618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtvoid p2p_disassoc_notif(struct p2p_data *p2p, const u8 *bssid, u16 reason_code, 39628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt const u8 *ie, size_t ie_len) 39638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 39648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct p2p_message msg; 39658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 39668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (bssid == NULL || ie == NULL) 39678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; 39688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 39698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memset(&msg, 0, sizeof(msg)); 39708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (p2p_parse_ies(ie, ie_len, &msg)) 39718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; 39728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (msg.minor_reason_code == NULL) 39738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; 39748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 39758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_msg(p2p->cfg->msg_ctx, MSG_INFO, 39768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "P2P: Disassociation notification BSSID " MACSTR 39778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt " reason_code=%u minor_reason_code=%u", 39788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt MAC2STR(bssid), reason_code, *msg.minor_reason_code); 39798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 39808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_parse_free(&msg); 39818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 39828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 39838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 39848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtvoid p2p_set_managed_oper(struct p2p_data *p2p, int enabled) 39858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 39868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (enabled) { 39878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG, "P2P: Managed P2P " 39888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "Device operations enabled"); 39898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p->dev_capab |= P2P_DEV_CAPAB_INFRA_MANAGED; 39908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } else { 39918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG, "P2P: Managed P2P " 39928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "Device operations disabled"); 39938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p->dev_capab &= ~P2P_DEV_CAPAB_INFRA_MANAGED; 39948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 39958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 39968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 39978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 39988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtint p2p_set_listen_channel(struct p2p_data *p2p, u8 reg_class, u8 channel) 39998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 40008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (p2p_channel_to_freq(p2p->cfg->country, reg_class, channel) < 0) 40018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 40028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 40038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG, "P2P: Set Listen channel: " 40048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "reg_class %u channel %u", reg_class, channel); 40058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p->cfg->reg_class = reg_class; 40068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p->cfg->channel = channel; 40078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 40088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 40098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 40108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 40118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 40128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtint p2p_set_ssid_postfix(struct p2p_data *p2p, const u8 *postfix, size_t len) 40138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 40148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_hexdump_ascii(MSG_DEBUG, "P2P: New SSID postfix", postfix, len); 40158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (postfix == NULL) { 40168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p->cfg->ssid_postfix_len = 0; 40178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 40188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 40198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (len > sizeof(p2p->cfg->ssid_postfix)) 40208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 40218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memcpy(p2p->cfg->ssid_postfix, postfix, len); 40228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p->cfg->ssid_postfix_len = len; 40238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 40248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 40258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 40268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 402775ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinenint p2p_set_oper_channel(struct p2p_data *p2p, u8 op_reg_class, u8 op_channel, 402875ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen int cfg_op_channel) 402975ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen{ 403075ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen if (p2p_channel_to_freq(p2p->cfg->country, op_reg_class, op_channel) 403175ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen < 0) 403275ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen return -1; 403375ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen 403475ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen wpa_msg(p2p->cfg->msg_ctx, MSG_INFO, "P2P: Set Operating channel: " 403575ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen "reg_class %u channel %u", op_reg_class, op_channel); 403675ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen p2p->cfg->op_reg_class = op_reg_class; 403775ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen p2p->cfg->op_channel = op_channel; 403875ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen p2p->cfg->cfg_op_channel = cfg_op_channel; 403975ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen return 0; 404075ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen} 404175ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen 404275ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen 404304949598a23f501be6eec21697465fd46a28840aDmitry Shmidtint p2p_set_pref_chan(struct p2p_data *p2p, unsigned int num_pref_chan, 404404949598a23f501be6eec21697465fd46a28840aDmitry Shmidt const struct p2p_channel *pref_chan) 404504949598a23f501be6eec21697465fd46a28840aDmitry Shmidt{ 404604949598a23f501be6eec21697465fd46a28840aDmitry Shmidt struct p2p_channel *n; 404704949598a23f501be6eec21697465fd46a28840aDmitry Shmidt 404804949598a23f501be6eec21697465fd46a28840aDmitry Shmidt if (pref_chan) { 404904949598a23f501be6eec21697465fd46a28840aDmitry Shmidt n = os_malloc(num_pref_chan * sizeof(struct p2p_channel)); 405004949598a23f501be6eec21697465fd46a28840aDmitry Shmidt if (n == NULL) 405104949598a23f501be6eec21697465fd46a28840aDmitry Shmidt return -1; 405204949598a23f501be6eec21697465fd46a28840aDmitry Shmidt os_memcpy(n, pref_chan, 405304949598a23f501be6eec21697465fd46a28840aDmitry Shmidt num_pref_chan * sizeof(struct p2p_channel)); 405404949598a23f501be6eec21697465fd46a28840aDmitry Shmidt } else 405504949598a23f501be6eec21697465fd46a28840aDmitry Shmidt n = NULL; 405604949598a23f501be6eec21697465fd46a28840aDmitry Shmidt 405704949598a23f501be6eec21697465fd46a28840aDmitry Shmidt os_free(p2p->cfg->pref_chan); 405804949598a23f501be6eec21697465fd46a28840aDmitry Shmidt p2p->cfg->pref_chan = n; 405904949598a23f501be6eec21697465fd46a28840aDmitry Shmidt p2p->cfg->num_pref_chan = num_pref_chan; 406004949598a23f501be6eec21697465fd46a28840aDmitry Shmidt 406104949598a23f501be6eec21697465fd46a28840aDmitry Shmidt return 0; 406204949598a23f501be6eec21697465fd46a28840aDmitry Shmidt} 406304949598a23f501be6eec21697465fd46a28840aDmitry Shmidt 406404949598a23f501be6eec21697465fd46a28840aDmitry Shmidt 40658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtint p2p_get_interface_addr(struct p2p_data *p2p, const u8 *dev_addr, 40668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt u8 *iface_addr) 40678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 40688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct p2p_device *dev = p2p_get_device(p2p, dev_addr); 40698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (dev == NULL || is_zero_ether_addr(dev->interface_addr)) 40708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 40718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memcpy(iface_addr, dev->interface_addr, ETH_ALEN); 40728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 40738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 40748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 40758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 40768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtint p2p_get_dev_addr(struct p2p_data *p2p, const u8 *iface_addr, 40778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt u8 *dev_addr) 40788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 40798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct p2p_device *dev = p2p_get_device_interface(p2p, iface_addr); 40808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (dev == NULL) 40818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 40828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memcpy(dev_addr, dev->info.p2p_device_addr, ETH_ALEN); 40838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 40848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 40858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 40868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 40878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtvoid p2p_set_peer_filter(struct p2p_data *p2p, const u8 *addr) 40888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 40898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memcpy(p2p->peer_filter, addr, ETH_ALEN); 40908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (is_zero_ether_addr(p2p->peer_filter)) 40918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG, "P2P: Disable peer " 40928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "filter"); 40938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt else 40948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG, "P2P: Enable peer " 40958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "filter for " MACSTR, MAC2STR(p2p->peer_filter)); 40968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 40978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 40988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 40998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtvoid p2p_set_cross_connect(struct p2p_data *p2p, int enabled) 41008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 41018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG, "P2P: Cross connection %s", 41028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt enabled ? "enabled" : "disabled"); 41038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (p2p->cross_connect == enabled) 41048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; 41058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p->cross_connect = enabled; 41068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* TODO: may need to tear down any action group where we are GO(?) */ 41078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 41088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 41098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 41108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtint p2p_get_oper_freq(struct p2p_data *p2p, const u8 *iface_addr) 41118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 41128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct p2p_device *dev = p2p_get_device_interface(p2p, iface_addr); 41138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (dev == NULL) 41148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 41158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (dev->oper_freq <= 0) 41168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 41178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return dev->oper_freq; 41188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 41198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 41208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 41218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtvoid p2p_set_intra_bss_dist(struct p2p_data *p2p, int enabled) 41228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 41238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG, "P2P: Intra BSS distribution %s", 41248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt enabled ? "enabled" : "disabled"); 41258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p->cfg->p2p_intra_bss = enabled; 41268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 41278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 41288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 41298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtvoid p2p_update_channel_list(struct p2p_data *p2p, struct p2p_channels *chan) 41308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 41318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG, "P2P: Update channel list"); 41328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memcpy(&p2p->cfg->channels, chan, sizeof(struct p2p_channels)); 41338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 41348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 41358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 41368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtint p2p_send_action(struct p2p_data *p2p, unsigned int freq, const u8 *dst, 41378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt const u8 *src, const u8 *bssid, const u8 *buf, 41388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt size_t len, unsigned int wait_time) 41398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 41408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (p2p->p2p_scan_running) { 41418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG, "P2P: Delay Action " 41428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "frame TX until p2p_scan completes"); 41438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (p2p->after_scan_tx) { 41448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG, "P2P: Dropped " 41458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "previous pending Action frame TX"); 41468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_free(p2p->after_scan_tx); 41478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 41488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p->after_scan_tx = os_malloc(sizeof(*p2p->after_scan_tx) + 41498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt len); 41508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (p2p->after_scan_tx == NULL) 41518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 41528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p->after_scan_tx->freq = freq; 41538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memcpy(p2p->after_scan_tx->dst, dst, ETH_ALEN); 41548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memcpy(p2p->after_scan_tx->src, src, ETH_ALEN); 41558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memcpy(p2p->after_scan_tx->bssid, bssid, ETH_ALEN); 41568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p->after_scan_tx->len = len; 41578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p->after_scan_tx->wait_time = wait_time; 41588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memcpy(p2p->after_scan_tx + 1, buf, len); 41598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 41608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 41618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 41628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return p2p->cfg->send_action(p2p->cfg->cb_ctx, freq, dst, src, bssid, 41638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt buf, len, wait_time); 41648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 41658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 41668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 41678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtvoid p2p_set_best_channels(struct p2p_data *p2p, int freq_24, int freq_5, 41688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt int freq_overall) 41698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 41708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG, "P2P: Best channel: 2.4 GHz: %d," 41718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt " 5 GHz: %d, overall: %d", freq_24, freq_5, freq_overall); 41728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p->best_freq_24 = freq_24; 41738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p->best_freq_5 = freq_5; 41748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p->best_freq_overall = freq_overall; 41758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 41768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 41778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 41788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtconst u8 * p2p_get_go_neg_peer(struct p2p_data *p2p) 41798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 41808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (p2p == NULL || p2p->go_neg_peer == NULL) 41818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return NULL; 41828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return p2p->go_neg_peer->info.p2p_device_addr; 41838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 41848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 41858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 41868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtconst struct p2p_peer_info * 41878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtp2p_get_peer_found(struct p2p_data *p2p, const u8 *addr, int next) 41888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 41898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct p2p_device *dev; 41908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 41918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (addr) { 41928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt dev = p2p_get_device(p2p, addr); 41938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (!dev) 41948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return NULL; 41958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 41968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (!next) { 41978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (dev->flags & P2P_DEV_PROBE_REQ_ONLY) 41988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return NULL; 41998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 42008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return &dev->info; 42018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } else { 42028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt do { 42038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt dev = dl_list_first(&dev->list, 42048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct p2p_device, 42058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt list); 42068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (&dev->list == &p2p->devices) 42078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return NULL; 42088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } while (dev->flags & P2P_DEV_PROBE_REQ_ONLY); 42098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 42108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } else { 42118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt dev = dl_list_first(&p2p->devices, struct p2p_device, list); 42128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (!dev) 42138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return NULL; 42148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt while (dev->flags & P2P_DEV_PROBE_REQ_ONLY) { 42158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt dev = dl_list_first(&dev->list, 42168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct p2p_device, 42178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt list); 42188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (&dev->list == &p2p->devices) 42198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return NULL; 42208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 42218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 42228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 42238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return &dev->info; 42248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 42251f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt 42261f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt#ifdef ANDROID_P2P 42271f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidtint p2p_search_in_progress(struct p2p_data *p2p) 42281f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt{ 42291f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt if (p2p == NULL) 42301f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt return 0; 42311f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt 42321f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt return p2p->state == P2P_SEARCH; 42331f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt} 42341f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt#endif 42351f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt 42361f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidtint p2p_in_progress(struct p2p_data *p2p) 42371f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt{ 42381f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt if (p2p == NULL) 42391f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt return 0; 424061d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt if (p2p->state == P2P_SEARCH || p2p->state == P2P_SEARCH_WHEN_READY || 424161d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt p2p->state == P2P_CONTINUE_SEARCH_WHEN_READY) 424261d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt return 2; 42431f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt return p2p->state != P2P_IDLE && p2p->state != P2P_PROVISIONING; 42441f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt} 424561d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt 424661d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt 424761d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidtvoid p2p_set_config_timeout(struct p2p_data *p2p, u8 go_timeout, 424861d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt u8 client_timeout) 424961d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt{ 425061d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt if (p2p) { 425161d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt p2p->go_timeout = go_timeout; 425261d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt p2p->client_timeout = client_timeout; 425361d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt } 425461d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt} 425561d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt 425661d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt 425761d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidtvoid p2p_increase_search_delay(struct p2p_data *p2p, unsigned int delay) 425861d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt{ 425961d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt if (p2p && p2p->search_delay < delay) 426061d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt p2p->search_delay = delay; 426161d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt} 426261d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt 426361d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt 426461d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt#ifdef CONFIG_WIFI_DISPLAY 426561d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt 426661d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidtstatic void p2p_update_wfd_ie_groups(struct p2p_data *p2p) 426761d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt{ 426861d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt size_t g; 426961d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt struct p2p_group *group; 427061d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt 427161d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt for (g = 0; g < p2p->num_groups; g++) { 427261d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt group = p2p->groups[g]; 427361d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt p2p_group_update_ies(group); 427461d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt } 427561d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt} 427661d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt 427761d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt 427861d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidtint p2p_set_wfd_ie_beacon(struct p2p_data *p2p, struct wpabuf *ie) 427961d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt{ 428061d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt wpabuf_free(p2p->wfd_ie_beacon); 428161d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt p2p->wfd_ie_beacon = ie; 428261d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt p2p_update_wfd_ie_groups(p2p); 428361d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt return 0; 428461d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt} 428561d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt 428661d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt 428761d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidtint p2p_set_wfd_ie_probe_req(struct p2p_data *p2p, struct wpabuf *ie) 428861d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt{ 428961d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt wpabuf_free(p2p->wfd_ie_probe_req); 429061d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt p2p->wfd_ie_probe_req = ie; 429161d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt return 0; 429261d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt} 429361d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt 429461d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt 429561d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidtint p2p_set_wfd_ie_probe_resp(struct p2p_data *p2p, struct wpabuf *ie) 429661d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt{ 429761d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt wpabuf_free(p2p->wfd_ie_probe_resp); 429861d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt p2p->wfd_ie_probe_resp = ie; 429961d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt p2p_update_wfd_ie_groups(p2p); 430061d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt return 0; 430161d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt} 430261d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt 430361d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt 430461d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidtint p2p_set_wfd_ie_assoc_req(struct p2p_data *p2p, struct wpabuf *ie) 430561d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt{ 430661d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt wpabuf_free(p2p->wfd_ie_assoc_req); 430761d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt p2p->wfd_ie_assoc_req = ie; 430861d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt return 0; 430961d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt} 431061d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt 431161d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt 431261d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidtint p2p_set_wfd_ie_invitation(struct p2p_data *p2p, struct wpabuf *ie) 431361d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt{ 431461d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt wpabuf_free(p2p->wfd_ie_invitation); 431561d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt p2p->wfd_ie_invitation = ie; 431661d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt return 0; 431761d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt} 431861d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt 431961d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt 432061d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidtint p2p_set_wfd_ie_prov_disc_req(struct p2p_data *p2p, struct wpabuf *ie) 432161d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt{ 432261d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt wpabuf_free(p2p->wfd_ie_prov_disc_req); 432361d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt p2p->wfd_ie_prov_disc_req = ie; 432461d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt return 0; 432561d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt} 432661d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt 432761d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt 432861d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidtint p2p_set_wfd_ie_prov_disc_resp(struct p2p_data *p2p, struct wpabuf *ie) 432961d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt{ 433061d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt wpabuf_free(p2p->wfd_ie_prov_disc_resp); 433161d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt p2p->wfd_ie_prov_disc_resp = ie; 433261d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt return 0; 433361d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt} 433461d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt 433561d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt 433661d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidtint p2p_set_wfd_ie_go_neg(struct p2p_data *p2p, struct wpabuf *ie) 433761d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt{ 433861d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt wpabuf_free(p2p->wfd_ie_go_neg); 433961d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt p2p->wfd_ie_go_neg = ie; 434061d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt return 0; 434161d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt} 434261d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt 434361d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt 434461d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidtint p2p_set_wfd_dev_info(struct p2p_data *p2p, const struct wpabuf *elem) 434561d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt{ 434661d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt wpabuf_free(p2p->wfd_dev_info); 434761d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt if (elem) { 434861d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt p2p->wfd_dev_info = wpabuf_dup(elem); 434961d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt if (p2p->wfd_dev_info == NULL) 435061d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt return -1; 435161d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt } else 435261d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt p2p->wfd_dev_info = NULL; 435361d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt 435461d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt return 0; 435561d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt} 435661d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt 435761d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt 435861d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidtint p2p_set_wfd_assoc_bssid(struct p2p_data *p2p, const struct wpabuf *elem) 435961d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt{ 436061d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt wpabuf_free(p2p->wfd_assoc_bssid); 436161d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt if (elem) { 436261d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt p2p->wfd_assoc_bssid = wpabuf_dup(elem); 436361d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt if (p2p->wfd_assoc_bssid == NULL) 436461d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt return -1; 436561d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt } else 436661d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt p2p->wfd_assoc_bssid = NULL; 436761d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt 436861d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt return 0; 436961d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt} 437061d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt 437161d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt 437261d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidtint p2p_set_wfd_coupled_sink_info(struct p2p_data *p2p, 437361d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt const struct wpabuf *elem) 437461d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt{ 437561d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt wpabuf_free(p2p->wfd_coupled_sink_info); 437661d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt if (elem) { 437761d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt p2p->wfd_coupled_sink_info = wpabuf_dup(elem); 437861d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt if (p2p->wfd_coupled_sink_info == NULL) 437961d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt return -1; 438061d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt } else 438161d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt p2p->wfd_coupled_sink_info = NULL; 438261d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt 438361d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt return 0; 438461d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt} 438561d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt 438661d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt#endif /* CONFIG_WIFI_DISPLAY */ 4387