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