p2p.c revision 1f69aa52ea2e0a73ac502565df8c666ee49cab6a
18d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt/* 28d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * Wi-Fi Direct - P2P module 38d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * Copyright (c) 2009-2010, Atheros Communications 48d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * 58d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * This program is free software; you can redistribute it and/or modify 68d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * it under the terms of the GNU General Public License version 2 as 78d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * published by the Free Software Foundation. 88d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * 98d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * Alternatively, this software may be distributed under the terms of BSD 108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * license. 118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * 128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * See README and COPYING for more details. 138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */ 148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include "includes.h" 168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include "common.h" 188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include "eloop.h" 198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include "common/ieee802_11_defs.h" 201f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt#ifdef ANDROID_P2P 211f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt#include "common/wpa_ctrl.h" 221f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt#endif 238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include "common/ieee802_11_common.h" 248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include "wps/wps_i.h" 258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include "p2p_i.h" 268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include "p2p.h" 278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic void p2p_state_timeout(void *eloop_ctx, void *timeout_ctx); 308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic void p2p_device_free(struct p2p_data *p2p, struct p2p_device *dev); 318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic void p2p_process_presence_req(struct p2p_data *p2p, const u8 *da, 328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt const u8 *sa, const u8 *data, size_t len, 338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt int rx_freq); 348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic void p2p_process_presence_resp(struct p2p_data *p2p, const u8 *da, 358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt const u8 *sa, const u8 *data, 368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt size_t len); 378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic void p2p_ext_listen_timeout(void *eloop_ctx, void *timeout_ctx); 388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic void p2p_scan_timeout(void *eloop_ctx, void *timeout_ctx); 398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt/* 428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * p2p_scan recovery timeout 438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * 448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * Many drivers are using 30 second timeout on scan results. Allow a bit larger 458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * timeout for this to avoid hitting P2P timeout unnecessarily. 468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */ 478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#define P2P_SCAN_TIMEOUT 35 488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt/** 508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * P2P_PEER_EXPIRATION_AGE - Number of seconds after which inactive peer 518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * entries will be removed 528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */ 538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#define P2P_PEER_EXPIRATION_AGE 300 548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#define P2P_PEER_EXPIRATION_INTERVAL (P2P_PEER_EXPIRATION_AGE / 2) 568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic void p2p_expire_peers(struct p2p_data *p2p) 588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct p2p_device *dev, *n; 608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct os_time now; 618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_get_time(&now); 638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt dl_list_for_each_safe(dev, n, &p2p->devices, struct p2p_device, list) { 648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (dev->last_seen.sec + P2P_PEER_EXPIRATION_AGE >= now.sec) 658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt continue; 668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG, "P2P: Expiring old peer " 678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "entry " MACSTR, MAC2STR(dev->info.p2p_device_addr)); 688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt dl_list_del(&dev->list); 698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_device_free(p2p, dev); 708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic void p2p_expiration_timeout(void *eloop_ctx, void *timeout_ctx) 758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct p2p_data *p2p = eloop_ctx; 778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_expire_peers(p2p); 788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt eloop_register_timeout(P2P_PEER_EXPIRATION_INTERVAL, 0, 798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_expiration_timeout, p2p, NULL); 808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic const char * p2p_state_txt(int state) 848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt switch (state) { 868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case P2P_IDLE: 878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return "IDLE"; 888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case P2P_SEARCH: 898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return "SEARCH"; 908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case P2P_CONNECT: 918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return "CONNECT"; 928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case P2P_CONNECT_LISTEN: 938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return "CONNECT_LISTEN"; 948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case P2P_GO_NEG: 958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return "GO_NEG"; 968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case P2P_LISTEN_ONLY: 978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return "LISTEN_ONLY"; 988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case P2P_WAIT_PEER_CONNECT: 998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return "WAIT_PEER_CONNECT"; 1008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case P2P_WAIT_PEER_IDLE: 1018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return "WAIT_PEER_IDLE"; 1028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case P2P_SD_DURING_FIND: 1038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return "SD_DURING_FIND"; 1048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case P2P_PROVISIONING: 1058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return "PROVISIONING"; 1068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case P2P_PD_DURING_FIND: 1078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return "PD_DURING_FIND"; 1088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case P2P_INVITE: 1098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return "INVITE"; 1108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case P2P_INVITE_LISTEN: 1118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return "INVITE_LISTEN"; 1121f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt case P2P_SEARCH_WHEN_READY: 1131f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt return "SEARCH_WHEN_READY"; 1148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt default: 1158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return "?"; 1168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 1178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 1188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1201f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidtu16 p2p_get_provisioning_info(struct p2p_data *p2p, const u8 *addr) 1211f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt{ 1221f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt struct p2p_device *dev = NULL; 1231f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt 1241f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt if (!addr || !p2p) 1251f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt return 0; 1261f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt 1271f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt dev = p2p_get_device(p2p, addr); 1281f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt if (dev) 1291f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt return dev->wps_prov_info; 1301f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt else 1311f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt return 0; 1321f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt} 1331f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt 1341f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt 1351f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidtvoid p2p_clear_provisioning_info(struct p2p_data *p2p, const u8 *iface_addr) 1361f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt{ 1371f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt struct p2p_device *dev = NULL; 1381f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt 1391f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt if (!iface_addr || !p2p) 1401f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt return; 1411f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt 1421f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt dev = p2p_get_device_interface(p2p, iface_addr); 1431f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt if (dev) 1441f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt dev->wps_prov_info = 0; 1451f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt} 1461f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt 1471f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt 1488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtvoid p2p_set_state(struct p2p_data *p2p, int new_state) 1498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 1508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG, "P2P: State %s -> %s", 1518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_state_txt(p2p->state), p2p_state_txt(new_state)); 1528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p->state = new_state; 1538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 1548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtvoid p2p_set_timeout(struct p2p_data *p2p, unsigned int sec, unsigned int usec) 1578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 1588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG, 1598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "P2P: Set timeout (state=%s): %u.%06u sec", 1608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_state_txt(p2p->state), sec, usec); 1618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt eloop_cancel_timeout(p2p_state_timeout, p2p, NULL); 1628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt eloop_register_timeout(sec, usec, p2p_state_timeout, p2p, NULL); 1638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 1648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtvoid p2p_clear_timeout(struct p2p_data *p2p) 1678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 1688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG, "P2P: Clear timeout (state=%s)", 1698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_state_txt(p2p->state)); 1708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt eloop_cancel_timeout(p2p_state_timeout, p2p, NULL); 1718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 1728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtvoid p2p_go_neg_failed(struct p2p_data *p2p, struct p2p_device *peer, 1758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt int status) 1768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 1778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct p2p_go_neg_results res; 1788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_clear_timeout(p2p); 1798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_set_state(p2p, P2P_IDLE); 1801f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt if (p2p->go_neg_peer) 1811f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt p2p->go_neg_peer->wps_method = WPS_NOT_READY; 1828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p->go_neg_peer = NULL; 1838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memset(&res, 0, sizeof(res)); 1858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt res.status = status; 1868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (peer) { 1878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memcpy(res.peer_device_addr, peer->info.p2p_device_addr, 1888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ETH_ALEN); 1898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memcpy(res.peer_interface_addr, peer->intended_addr, 1908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ETH_ALEN); 1918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 1928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p->cfg->go_neg_completed(p2p->cfg->cb_ctx, &res); 1938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 1948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic void p2p_listen_in_find(struct p2p_data *p2p) 1978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 1988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt unsigned int r, tu; 1998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt int freq; 2008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct wpabuf *ies; 2018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG, 2038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "P2P: Starting short listen state (state=%s)", 2048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_state_txt(p2p->state)); 2058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt freq = p2p_channel_to_freq(p2p->cfg->country, p2p->cfg->reg_class, 2078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p->cfg->channel); 2088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (freq < 0) { 2098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG, 2108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "P2P: Unknown regulatory class/channel"); 2118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; 2128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 2138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_get_random((u8 *) &r, sizeof(r)); 2158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt tu = (r % ((p2p->max_disc_int - p2p->min_disc_int) + 1) + 2168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p->min_disc_int) * 100; 2178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p->pending_listen_freq = freq; 2198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p->pending_listen_sec = 0; 2208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p->pending_listen_usec = 1024 * tu; 2218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ies = p2p_build_probe_resp_ies(p2p); 2238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (ies == NULL) 2248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; 2258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (p2p->cfg->start_listen(p2p->cfg->cb_ctx, freq, 1024 * tu / 1000, 2278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ies) < 0) { 2288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG, 2298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "P2P: Failed to start listen mode"); 2308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p->pending_listen_freq = 0; 2318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 2328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpabuf_free(ies); 2338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 2348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtint p2p_listen(struct p2p_data *p2p, unsigned int timeout) 2378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 2388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt int freq; 2398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct wpabuf *ies; 2408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG, 2428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "P2P: Going to listen(only) state"); 2438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt freq = p2p_channel_to_freq(p2p->cfg->country, p2p->cfg->reg_class, 2458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p->cfg->channel); 2468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (freq < 0) { 2478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG, 2488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "P2P: Unknown regulatory class/channel"); 2498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 2508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 2518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p->pending_listen_freq = freq; 2538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p->pending_listen_sec = timeout / 1000; 2548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p->pending_listen_usec = (timeout % 1000) * 1000; 2558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (p2p->p2p_scan_running) { 2571f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt if (p2p->start_after_scan == P2P_AFTER_SCAN_NOTHING) { 2581f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG, 2591f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt "P2P: p2p_scan running - connect is already " 2601f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt "pending - skip listen"); 2611f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt return 0; 2621f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt } 2638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG, 2648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "P2P: p2p_scan running - delay start of listen state"); 2658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p->start_after_scan = P2P_AFTER_SCAN_LISTEN; 2668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 2678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 2688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ies = p2p_build_probe_resp_ies(p2p); 2708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (ies == NULL) 2718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 2728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (p2p->cfg->start_listen(p2p->cfg->cb_ctx, freq, timeout, ies) < 0) { 2748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG, 2758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "P2P: Failed to start listen mode"); 2768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p->pending_listen_freq = 0; 2778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpabuf_free(ies); 2788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 2798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 2808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpabuf_free(ies); 2818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_set_state(p2p, P2P_LISTEN_ONLY); 2838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 2858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 2868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic void p2p_device_clear_reported(struct p2p_data *p2p) 2898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 2908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct p2p_device *dev; 2918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt dl_list_for_each(dev, &p2p->devices, struct p2p_device, list) 2928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt dev->flags &= ~P2P_DEV_REPORTED; 2938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 2948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt/** 2978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * p2p_get_device - Fetch a peer entry 2988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @p2p: P2P module context from p2p_init() 2998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @addr: P2P Device Address of the peer 3008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * Returns: Pointer to the device entry or %NULL if not found 3018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */ 3028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstruct p2p_device * p2p_get_device(struct p2p_data *p2p, const u8 *addr) 3038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 3048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct p2p_device *dev; 3058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt dl_list_for_each(dev, &p2p->devices, struct p2p_device, list) { 3068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (os_memcmp(dev->info.p2p_device_addr, addr, ETH_ALEN) == 0) 3078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return dev; 3088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 3098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return NULL; 3108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 3118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 3128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 3138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt/** 3148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * p2p_get_device_interface - Fetch a peer entry based on P2P Interface Address 3158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @p2p: P2P module context from p2p_init() 3168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @addr: P2P Interface Address of the peer 3178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * Returns: Pointer to the device entry or %NULL if not found 3188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */ 3198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstruct p2p_device * p2p_get_device_interface(struct p2p_data *p2p, 3208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt const u8 *addr) 3218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 3228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct p2p_device *dev; 3238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt dl_list_for_each(dev, &p2p->devices, struct p2p_device, list) { 3248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (os_memcmp(dev->interface_addr, addr, ETH_ALEN) == 0) 3258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return dev; 3268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 3278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return NULL; 3288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 3298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 3308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 3318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt/** 3328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * p2p_create_device - Create a peer entry 3338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @p2p: P2P module context from p2p_init() 3348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @addr: P2P Device Address of the peer 3358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * Returns: Pointer to the device entry or %NULL on failure 3368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * 3378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * If there is already an entry for the peer, it will be returned instead of 3388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * creating a new one. 3398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */ 3408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic struct p2p_device * p2p_create_device(struct p2p_data *p2p, 3418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt const u8 *addr) 3428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 3438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct p2p_device *dev, *oldest = NULL; 3448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt size_t count = 0; 3458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 3468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt dev = p2p_get_device(p2p, addr); 3478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (dev) 3488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return dev; 3498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 3508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt dl_list_for_each(dev, &p2p->devices, struct p2p_device, list) { 3518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt count++; 3528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (oldest == NULL || 3538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_time_before(&dev->last_seen, &oldest->last_seen)) 3548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt oldest = dev; 3558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 3568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (count + 1 > p2p->cfg->max_peers && oldest) { 3578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG, 3588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "P2P: Remove oldest peer entry to make room for a new " 3598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "peer"); 3608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt dl_list_del(&oldest->list); 3618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_device_free(p2p, oldest); 3628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 3638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 3648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt dev = os_zalloc(sizeof(*dev)); 3658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (dev == NULL) 3668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return NULL; 3678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt dl_list_add(&p2p->devices, &dev->list); 3688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memcpy(dev->info.p2p_device_addr, addr, ETH_ALEN); 3698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 3708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return dev; 3718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 3728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 3738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 3748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic void p2p_copy_client_info(struct p2p_device *dev, 3758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct p2p_client_info *cli) 3768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 3778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memcpy(dev->info.device_name, cli->dev_name, cli->dev_name_len); 3788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt dev->info.device_name[cli->dev_name_len] = '\0'; 3798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt dev->info.dev_capab = cli->dev_capab; 3808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt dev->info.config_methods = cli->config_methods; 3818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memcpy(dev->info.pri_dev_type, cli->pri_dev_type, 8); 3828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt dev->info.wps_sec_dev_type_list_len = 8 * cli->num_sec_dev_types; 3838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memcpy(dev->info.wps_sec_dev_type_list, cli->sec_dev_types, 3848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt dev->info.wps_sec_dev_type_list_len); 3858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 3868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 3878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 3888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic int p2p_add_group_clients(struct p2p_data *p2p, const u8 *go_dev_addr, 3898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt const u8 *go_interface_addr, int freq, 3908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt const u8 *gi, size_t gi_len) 3918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 3928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct p2p_group_info info; 3938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt size_t c; 3948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct p2p_device *dev; 3958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 3968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (gi == NULL) 3978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 3988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 3998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (p2p_group_info_parse(gi, gi_len, &info) < 0) 4008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 4018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 4028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* 4038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * Clear old data for this group; if the devices are still in the 4048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * group, the information will be restored in the loop following this. 4058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */ 4068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt dl_list_for_each(dev, &p2p->devices, struct p2p_device, list) { 4071f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt if (os_memcmp(dev->member_in_go_iface, go_interface_addr, 4088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ETH_ALEN) == 0) { 4098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memset(dev->member_in_go_iface, 0, ETH_ALEN); 4108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memset(dev->member_in_go_dev, 0, ETH_ALEN); 4118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 4128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 4138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 4148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt for (c = 0; c < info.num_clients; c++) { 4158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct p2p_client_info *cli = &info.client[c]; 4161f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt if (os_memcmp(cli->p2p_device_addr, p2p->cfg->dev_addr, 4171f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt ETH_ALEN) == 0) 4181f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt continue; /* ignore our own entry */ 4198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt dev = p2p_get_device(p2p, cli->p2p_device_addr); 4208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (dev) { 4218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* 4228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * Update information only if we have not received this 4238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * directly from the client. 4248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */ 4258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (dev->flags & (P2P_DEV_GROUP_CLIENT_ONLY | 4268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt P2P_DEV_PROBE_REQ_ONLY)) 4278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_copy_client_info(dev, cli); 4288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (dev->flags & P2P_DEV_PROBE_REQ_ONLY) { 4298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt dev->flags &= ~P2P_DEV_PROBE_REQ_ONLY; 4308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 4318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } else { 4328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt dev = p2p_create_device(p2p, cli->p2p_device_addr); 4338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (dev == NULL) 4348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt continue; 4358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt dev->flags |= P2P_DEV_GROUP_CLIENT_ONLY; 4368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_copy_client_info(dev, cli); 4378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt dev->oper_freq = freq; 4388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p->cfg->dev_found(p2p->cfg->cb_ctx, 4398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt dev->info.p2p_device_addr, 4408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt &dev->info, 1); 4418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt dev->flags |= P2P_DEV_REPORTED | P2P_DEV_REPORTED_ONCE; 4428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 4438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 4448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memcpy(dev->interface_addr, cli->p2p_interface_addr, 4458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ETH_ALEN); 4468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_get_time(&dev->last_seen); 4478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memcpy(dev->member_in_go_dev, go_dev_addr, ETH_ALEN); 4488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memcpy(dev->member_in_go_iface, go_interface_addr, 4498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ETH_ALEN); 4508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 4518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 4528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 4538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 4548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 4558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 4568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic void p2p_copy_wps_info(struct p2p_device *dev, int probe_req, 4578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt const struct p2p_message *msg) 4588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 4598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memcpy(dev->info.device_name, msg->device_name, 4608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sizeof(dev->info.device_name)); 4618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 4628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (msg->manufacturer && 4638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt msg->manufacturer_len < sizeof(dev->info.manufacturer)) { 4648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memset(dev->info.manufacturer, 0, 4658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sizeof(dev->info.manufacturer)); 4668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memcpy(dev->info.manufacturer, msg->manufacturer, 4678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt msg->manufacturer_len); 4688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 4698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 4708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (msg->model_name && 4718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt msg->model_name_len < sizeof(dev->info.model_name)) { 4728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memset(dev->info.model_name, 0, 4738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sizeof(dev->info.model_name)); 4748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memcpy(dev->info.model_name, msg->model_name, 4758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt msg->model_name_len); 4768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 4778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 4788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (msg->model_number && 4798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt msg->model_number_len < sizeof(dev->info.model_number)) { 4808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memset(dev->info.model_number, 0, 4818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sizeof(dev->info.model_number)); 4828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memcpy(dev->info.model_number, msg->model_number, 4838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt msg->model_number_len); 4848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 4858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 4868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (msg->serial_number && 4878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt msg->serial_number_len < sizeof(dev->info.serial_number)) { 4888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memset(dev->info.serial_number, 0, 4898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sizeof(dev->info.serial_number)); 4908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memcpy(dev->info.serial_number, msg->serial_number, 4918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt msg->serial_number_len); 4928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 4938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 4948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (msg->pri_dev_type) 4958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memcpy(dev->info.pri_dev_type, msg->pri_dev_type, 4968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sizeof(dev->info.pri_dev_type)); 4978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt else if (msg->wps_pri_dev_type) 4988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memcpy(dev->info.pri_dev_type, msg->wps_pri_dev_type, 4998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sizeof(dev->info.pri_dev_type)); 5008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 5018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (msg->wps_sec_dev_type_list) { 5028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memcpy(dev->info.wps_sec_dev_type_list, 5038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt msg->wps_sec_dev_type_list, 5048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt msg->wps_sec_dev_type_list_len); 5058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt dev->info.wps_sec_dev_type_list_len = 5068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt msg->wps_sec_dev_type_list_len; 5078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 5088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 5098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (msg->capability) { 5108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt dev->info.dev_capab = msg->capability[0]; 5118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt dev->info.group_capab = msg->capability[1]; 5128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 5138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 5148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (msg->ext_listen_timing) { 5158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt dev->ext_listen_period = WPA_GET_LE16(msg->ext_listen_timing); 5168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt dev->ext_listen_interval = 5178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt WPA_GET_LE16(msg->ext_listen_timing + 2); 5188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 5198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 5208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (!probe_req) { 5218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt dev->info.config_methods = msg->config_methods ? 5228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt msg->config_methods : msg->wps_config_methods; 5238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 5248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 5258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 5268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 5278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt/** 5288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * p2p_add_device - Add peer entries based on scan results 5298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @p2p: P2P module context from p2p_init() 5308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @addr: Source address of Beacon or Probe Response frame (may be either 5318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * P2P Device Address or P2P Interface Address) 5328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @level: Signal level (signal strength of the received frame from the peer) 5338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @freq: Frequency on which the Beacon or Probe Response frame was received 5348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @ies: IEs from the Beacon or Probe Response frame 5358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @ies_len: Length of ies buffer in octets 5368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * Returns: 0 on success, -1 on failure 5378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * 5388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * If the scan result is for a GO, the clients in the group will also be added 5398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * to the peer table. This function can also be used with some other frames 5408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * like Provision Discovery Request that contains P2P Capability and P2P Device 5418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * Info attributes. 5428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */ 5438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtint p2p_add_device(struct p2p_data *p2p, const u8 *addr, int freq, int level, 5448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt const u8 *ies, size_t ies_len) 5458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 5468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct p2p_device *dev; 5478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct p2p_message msg; 5488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt const u8 *p2p_dev_addr; 5498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt int i; 5508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 5518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memset(&msg, 0, sizeof(msg)); 5528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (p2p_parse_ies(ies, ies_len, &msg)) { 5538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG, 5548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "P2P: Failed to parse P2P IE for a device entry"); 5558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_parse_free(&msg); 5568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 5578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 5588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 5598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (msg.p2p_device_addr) 5608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_dev_addr = msg.p2p_device_addr; 5618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt else if (msg.device_id) 5628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_dev_addr = msg.device_id; 5638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt else { 5648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG, 5658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "P2P: Ignore scan data without P2P Device Info or " 5668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "P2P Device Id"); 5678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_parse_free(&msg); 5688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 5698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 5708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 5718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (!is_zero_ether_addr(p2p->peer_filter) && 5728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memcmp(p2p_dev_addr, p2p->peer_filter, ETH_ALEN) != 0) { 5738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG, "P2P: Do not add peer " 5748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "filter for " MACSTR " due to peer filter", 5758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt MAC2STR(p2p_dev_addr)); 5768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 5778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 5788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 5798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt dev = p2p_create_device(p2p, p2p_dev_addr); 5808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (dev == NULL) { 5818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_parse_free(&msg); 5828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 5838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 5848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_get_time(&dev->last_seen); 5858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt dev->flags &= ~(P2P_DEV_PROBE_REQ_ONLY | P2P_DEV_GROUP_CLIENT_ONLY); 5868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 5878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (os_memcmp(addr, p2p_dev_addr, ETH_ALEN) != 0) 5888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memcpy(dev->interface_addr, addr, ETH_ALEN); 5898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (msg.ssid && 5908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt (msg.ssid[1] != P2P_WILDCARD_SSID_LEN || 5918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memcmp(msg.ssid + 2, P2P_WILDCARD_SSID, P2P_WILDCARD_SSID_LEN) 5928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt != 0)) { 5938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memcpy(dev->oper_ssid, msg.ssid + 2, msg.ssid[1]); 5948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt dev->oper_ssid_len = msg.ssid[1]; 5958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 5968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 5978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (freq >= 2412 && freq <= 2484 && msg.ds_params && 5988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt *msg.ds_params >= 1 && *msg.ds_params <= 14) { 5998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt int ds_freq; 6008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (*msg.ds_params == 14) 6018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ds_freq = 2484; 6028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt else 6038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ds_freq = 2407 + *msg.ds_params * 5; 6048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (freq != ds_freq) { 6058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG, 6068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "P2P: Update Listen frequency based on DS " 6078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "Parameter Set IE: %d -> %d MHz", 6088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt freq, ds_freq); 6098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt freq = ds_freq; 6108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 6118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 6128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 6138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (dev->listen_freq && dev->listen_freq != freq) { 6148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG, 6158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "P2P: Update Listen frequency based on scan " 6168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "results (" MACSTR " %d -> %d MHz (DS param %d)", 6178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt MAC2STR(dev->info.p2p_device_addr), dev->listen_freq, 6188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt freq, msg.ds_params ? *msg.ds_params : -1); 6198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 6208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt dev->listen_freq = freq; 6218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (msg.group_info) 6228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt dev->oper_freq = freq; 62375ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen dev->info.level = level; 6248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 6258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_copy_wps_info(dev, 0, &msg); 6268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 6278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt for (i = 0; i < P2P_MAX_WPS_VENDOR_EXT; i++) { 6288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpabuf_free(dev->info.wps_vendor_ext[i]); 6298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt dev->info.wps_vendor_ext[i] = NULL; 6308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 6318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 6328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt for (i = 0; i < P2P_MAX_WPS_VENDOR_EXT; i++) { 6338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (msg.wps_vendor_ext[i] == NULL) 6348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 6358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt dev->info.wps_vendor_ext[i] = wpabuf_alloc_copy( 6368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt msg.wps_vendor_ext[i], msg.wps_vendor_ext_len[i]); 6378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (dev->info.wps_vendor_ext[i] == NULL) 6388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 6398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 6408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 6418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_add_group_clients(p2p, p2p_dev_addr, addr, freq, msg.group_info, 6428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt msg.group_info_len); 6438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 6448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_parse_free(&msg); 6458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 6468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (p2p_pending_sd_req(p2p, dev)) 6478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt dev->flags |= P2P_DEV_SD_SCHEDULE; 6488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 6498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (dev->flags & P2P_DEV_REPORTED) 6508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 6518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 6528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG, 6538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "P2P: Peer found with Listen frequency %d MHz", freq); 6548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (dev->flags & P2P_DEV_USER_REJECTED) { 6558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG, 6568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "P2P: Do not report rejected device"); 6578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 6588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 6598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 6608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p->cfg->dev_found(p2p->cfg->cb_ctx, addr, &dev->info, 6618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt !(dev->flags & P2P_DEV_REPORTED_ONCE)); 6628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt dev->flags |= P2P_DEV_REPORTED | P2P_DEV_REPORTED_ONCE; 6638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 6648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 6658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 6668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 6678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 6688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic void p2p_device_free(struct p2p_data *p2p, struct p2p_device *dev) 6698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 6708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt int i; 6718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 672497c1d5e50162d6b3c1cce5dbd9c5fd9da69aaefDmitry Shmidt if (p2p->go_neg_peer == dev) { 6731f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt /* 6741f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt * If GO Negotiation is in progress, report that it has failed. 6751f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt */ 676497c1d5e50162d6b3c1cce5dbd9c5fd9da69aaefDmitry Shmidt p2p_go_neg_failed(p2p, dev, -1); 6778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p->go_neg_peer = NULL; 678497c1d5e50162d6b3c1cce5dbd9c5fd9da69aaefDmitry Shmidt } 6798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (p2p->invite_peer == dev) 6808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p->invite_peer = NULL; 6818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (p2p->sd_peer == dev) 6828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p->sd_peer = NULL; 6838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (p2p->pending_client_disc_go == dev) 6848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p->pending_client_disc_go = NULL; 6858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 686c55524ad84d13014e8019491c2b17e5dcf13545aDmitry Shmidt /* dev_lost() device, but only if it was previously dev_found() */ 687c55524ad84d13014e8019491c2b17e5dcf13545aDmitry Shmidt if (dev->flags & P2P_DEV_REPORTED_ONCE) 688c55524ad84d13014e8019491c2b17e5dcf13545aDmitry Shmidt p2p->cfg->dev_lost(p2p->cfg->cb_ctx, 689c55524ad84d13014e8019491c2b17e5dcf13545aDmitry Shmidt dev->info.p2p_device_addr); 6908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 6918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt for (i = 0; i < P2P_MAX_WPS_VENDOR_EXT; i++) { 6928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpabuf_free(dev->info.wps_vendor_ext[i]); 6938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt dev->info.wps_vendor_ext[i] = NULL; 6948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 6958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 6968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_free(dev); 6978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 6988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 6998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 7008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic int p2p_get_next_prog_freq(struct p2p_data *p2p) 7018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 7028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct p2p_channels *c; 7038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct p2p_reg_class *cla; 7048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt size_t cl, ch; 7058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt int found = 0; 7068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt u8 reg_class; 7078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt u8 channel; 7088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt int freq; 7098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 7108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt c = &p2p->cfg->channels; 7118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt for (cl = 0; cl < c->reg_classes; cl++) { 7128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt cla = &c->reg_class[cl]; 7138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (cla->reg_class != p2p->last_prog_scan_class) 7148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt continue; 7158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt for (ch = 0; ch < cla->channels; ch++) { 7168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (cla->channel[ch] == p2p->last_prog_scan_chan) { 7178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt found = 1; 7188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 7198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 7208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 7218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (found) 7228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 7238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 7248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 7258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (!found) { 7268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* Start from beginning */ 7278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt reg_class = c->reg_class[0].reg_class; 7288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt channel = c->reg_class[0].channel[0]; 7298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } else { 7308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* Pick the next channel */ 7318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ch++; 7328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (ch == cla->channels) { 7338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt cl++; 7348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (cl == c->reg_classes) 7358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt cl = 0; 7368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ch = 0; 7378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 7388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt reg_class = c->reg_class[cl].reg_class; 7398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt channel = c->reg_class[cl].channel[ch]; 7408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 7418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 7428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt freq = p2p_channel_to_freq(p2p->cfg->country, reg_class, channel); 7438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG, "P2P: Next progressive search " 7448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "channel: reg_class %u channel %u -> %d MHz", 7458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt reg_class, channel, freq); 7468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p->last_prog_scan_class = reg_class; 7478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p->last_prog_scan_chan = channel; 7488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 7498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (freq == 2412 || freq == 2437 || freq == 2462) 7508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; /* No need to add social channels */ 7518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return freq; 7528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 7538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 7548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 7558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic void p2p_search(struct p2p_data *p2p) 7568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 7578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt int freq = 0; 7588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt enum p2p_scan_type type; 7598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 7608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (p2p->drv_in_listen) { 7618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG, "P2P: Driver is still " 7628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "in Listen state - wait for it to end before " 7638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "continuing"); 7648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; 7658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 7668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p->cfg->stop_listen(p2p->cfg->cb_ctx); 7678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 7688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (p2p->go_neg_peer) { 7698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* 7708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * Only scan the known listen frequency of the peer 7718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * during GO Negotiation start. 7728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */ 7738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt freq = p2p->go_neg_peer->listen_freq; 7748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (freq <= 0) 7758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt freq = p2p->go_neg_peer->oper_freq; 7768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt type = P2P_SCAN_SPECIFIC; 7778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG, "P2P: Starting search " 7788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "for freq %u (GO Neg)", freq); 7798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } else if (p2p->invite_peer) { 7808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* 7818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * Only scan the known listen frequency of the peer 7828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * during Invite start. 7838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */ 7848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt freq = p2p->invite_peer->listen_freq; 7858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (freq <= 0) 7868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt freq = p2p->invite_peer->oper_freq; 7878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt type = P2P_SCAN_SPECIFIC; 7888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG, "P2P: Starting search " 7898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "for freq %u (Invite)", freq); 7908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } else if (p2p->find_type == P2P_FIND_PROGRESSIVE && 7918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt (freq = p2p_get_next_prog_freq(p2p)) > 0) { 7928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt type = P2P_SCAN_SOCIAL_PLUS_ONE; 7938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG, "P2P: Starting search " 7948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "(+ freq %u)", freq); 7958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } else { 7968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt type = P2P_SCAN_SOCIAL; 7978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG, "P2P: Starting search"); 7988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 7998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 8008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (p2p->cfg->p2p_scan(p2p->cfg->cb_ctx, type, freq, 8018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p->num_req_dev_types, p2p->req_dev_types) < 0) 8028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt { 8038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG, 8048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "P2P: Scan request failed"); 8058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_continue_find(p2p); 8068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } else { 8078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG, "P2P: Running p2p_scan"); 8088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p->p2p_scan_running = 1; 8098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt eloop_cancel_timeout(p2p_scan_timeout, p2p, NULL); 8108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt eloop_register_timeout(P2P_SCAN_TIMEOUT, 0, p2p_scan_timeout, 8118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p, NULL); 8128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 8138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 8148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 8158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 8168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic void p2p_find_timeout(void *eloop_ctx, void *timeout_ctx) 8178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 8188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct p2p_data *p2p = eloop_ctx; 8198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG, "P2P: Find timeout -> stop"); 8208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_stop_find(p2p); 8218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 8228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 8238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 8248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic int p2p_run_after_scan(struct p2p_data *p2p) 8258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 8268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct p2p_device *dev; 8278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt enum p2p_after_scan op; 8288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 8298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (p2p->after_scan_tx) { 8308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* TODO: schedule p2p_run_after_scan to be called from TX 8318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * status callback(?) */ 8328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG, "P2P: Send pending " 8338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "Action frame at p2p_scan completion"); 8341f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt p2p->cfg->send_action(p2p->cfg->cb_ctx, 8351f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt p2p->after_scan_tx->freq, 8361f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt p2p->after_scan_tx->dst, 8371f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt p2p->after_scan_tx->src, 8381f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt p2p->after_scan_tx->bssid, 8391f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt (u8 *) (p2p->after_scan_tx + 1), 8401f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt p2p->after_scan_tx->len, 8411f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt p2p->after_scan_tx->wait_time); 8428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_free(p2p->after_scan_tx); 8438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p->after_scan_tx = NULL; 8448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 1; 8458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 8468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 8478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt op = p2p->start_after_scan; 8488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p->start_after_scan = P2P_AFTER_SCAN_NOTHING; 8498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt switch (op) { 8508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case P2P_AFTER_SCAN_NOTHING: 8518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 8528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case P2P_AFTER_SCAN_LISTEN: 8538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG, "P2P: Start previously " 8548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "requested Listen state"); 8558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_listen(p2p, p2p->pending_listen_sec * 1000 + 8568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p->pending_listen_usec / 1000); 8578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 1; 8588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case P2P_AFTER_SCAN_CONNECT: 8598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG, "P2P: Start previously " 8608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "requested connect with " MACSTR, 8618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt MAC2STR(p2p->after_scan_peer)); 8628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt dev = p2p_get_device(p2p, p2p->after_scan_peer); 8638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (dev == NULL) { 8648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG, "P2P: Peer not " 8658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "known anymore"); 8668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 8678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 8688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_connect_send(p2p, dev); 8698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 1; 8708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 8718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 8728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 8738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 8748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 8758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 8768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic void p2p_scan_timeout(void *eloop_ctx, void *timeout_ctx) 8778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 8788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct p2p_data *p2p = eloop_ctx; 8798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt int running; 8808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG, "P2P: p2p_scan timeout " 8818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "(running=%d)", p2p->p2p_scan_running); 8828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt running = p2p->p2p_scan_running; 8838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* Make sure we recover from missed scan results callback */ 8848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p->p2p_scan_running = 0; 8858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 8868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (running) 8878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_run_after_scan(p2p); 8888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 8898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 8908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 8918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic void p2p_free_req_dev_types(struct p2p_data *p2p) 8928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 8938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p->num_req_dev_types = 0; 8948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_free(p2p->req_dev_types); 8958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p->req_dev_types = NULL; 8968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 8978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 8988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 8998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtint p2p_find(struct p2p_data *p2p, unsigned int timeout, 9008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt enum p2p_discovery_type type, 9018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt unsigned int num_req_dev_types, const u8 *req_dev_types) 9028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 9038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt int res; 9048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 9058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG, "P2P: Starting find (type=%d)", 9068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt type); 9078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (p2p->p2p_scan_running) { 9088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG, "P2P: p2p_scan is " 9098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "already running"); 9108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 9118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 9128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_free_req_dev_types(p2p); 9138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (req_dev_types && num_req_dev_types) { 9148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p->req_dev_types = os_malloc(num_req_dev_types * 9158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt WPS_DEV_TYPE_LEN); 9168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (p2p->req_dev_types == NULL) 9178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 9188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memcpy(p2p->req_dev_types, req_dev_types, 9198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt num_req_dev_types * WPS_DEV_TYPE_LEN); 9208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p->num_req_dev_types = num_req_dev_types; 9218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 9228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 9238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p->start_after_scan = P2P_AFTER_SCAN_NOTHING; 9248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_clear_timeout(p2p); 9258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p->cfg->stop_listen(p2p->cfg->cb_ctx); 9268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p->find_type = type; 9278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_device_clear_reported(p2p); 9288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_set_state(p2p, P2P_SEARCH); 9298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt eloop_cancel_timeout(p2p_find_timeout, p2p, NULL); 9301f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt p2p->last_p2p_find_timeout = timeout; 9318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (timeout) 9328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt eloop_register_timeout(timeout, 0, p2p_find_timeout, 9338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p, NULL); 9348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt switch (type) { 9358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case P2P_FIND_START_WITH_FULL: 9368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case P2P_FIND_PROGRESSIVE: 9378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt res = p2p->cfg->p2p_scan(p2p->cfg->cb_ctx, P2P_SCAN_FULL, 0, 9388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p->num_req_dev_types, 9398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p->req_dev_types); 9408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 9418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case P2P_FIND_ONLY_SOCIAL: 9428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt res = p2p->cfg->p2p_scan(p2p->cfg->cb_ctx, P2P_SCAN_SOCIAL, 0, 9438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p->num_req_dev_types, 9448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p->req_dev_types); 9458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 9468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt default: 9478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 9488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 9498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 9508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (res == 0) { 9518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG, "P2P: Running p2p_scan"); 9528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p->p2p_scan_running = 1; 9538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt eloop_cancel_timeout(p2p_scan_timeout, p2p, NULL); 9548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt eloop_register_timeout(P2P_SCAN_TIMEOUT, 0, p2p_scan_timeout, 9558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p, NULL); 9561f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt } else if (res == 1) { 9571f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG, "P2P: Could not start " 9581f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt "p2p_scan at this point - will try again after " 9591f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt "previous scan completes"); 9601f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt res = 0; 9611f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt p2p_set_state(p2p, P2P_SEARCH_WHEN_READY); 9621f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt eloop_cancel_timeout(p2p_find_timeout, p2p, NULL); 9638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } else { 9648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG, "P2P: Failed to start " 9658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "p2p_scan"); 9661f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt p2p_set_state(p2p, P2P_IDLE); 9671f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt eloop_cancel_timeout(p2p_find_timeout, p2p, NULL); 9688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 9698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 9708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return res; 9718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 9728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 9738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 9741f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidtint p2p_other_scan_completed(struct p2p_data *p2p) 9751f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt{ 9761f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt if (p2p->state != P2P_SEARCH_WHEN_READY) 9771f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt return 0; 9781f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG, "P2P: Starting pending P2P find " 9791f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt "now that previous scan was completed"); 9801f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt if (p2p_find(p2p, p2p->last_p2p_find_timeout, p2p->find_type, 9811f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt p2p->num_req_dev_types, p2p->req_dev_types) < 0) 9821f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt return 0; 9831f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt return 1; 9841f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt} 9851f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt 9861f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt 9878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtvoid p2p_stop_find_for_freq(struct p2p_data *p2p, int freq) 9888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 9898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG, "P2P: Stopping find"); 9908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt eloop_cancel_timeout(p2p_find_timeout, p2p, NULL); 9918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_clear_timeout(p2p); 9928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_set_state(p2p, P2P_IDLE); 9931f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt#ifdef ANDROID_P2P 9941f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt wpa_msg(p2p->cfg->msg_ctx, MSG_INFO, P2P_EVENT_FIND_STOPPED); 9951f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt#endif 9961f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt 9978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_free_req_dev_types(p2p); 9988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p->start_after_scan = P2P_AFTER_SCAN_NOTHING; 9998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p->go_neg_peer = NULL; 10008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p->sd_peer = NULL; 10018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p->invite_peer = NULL; 10028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (freq > 0 && p2p->drv_in_listen == freq && p2p->in_listen) { 10038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG, "P2P: Skip stop_listen " 10048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "since we are on correct channel for response"); 10058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; 10068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 10071f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt if (p2p->drv_in_listen) { 10081f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt /* 10091f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt * The driver may not deliver callback to p2p_listen_end() 10101f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt * when the operation gets canceled, so clear the internal 10111f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt * variable that is tracking driver state. 10121f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt */ 10131f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG, "P2P: Clear " 10141f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt "drv_in_listen (%d)", p2p->drv_in_listen); 10151f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt p2p->drv_in_listen = 0; 10161f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt } 10178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p->cfg->stop_listen(p2p->cfg->cb_ctx); 10188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 10198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 10208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 10218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtvoid p2p_stop_find(struct p2p_data *p2p) 10228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 10238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_stop_find_for_freq(p2p, 0); 10248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 10258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 10268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 10278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic int p2p_prepare_channel(struct p2p_data *p2p, unsigned int force_freq) 10288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 10298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (force_freq) { 10308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt u8 op_reg_class, op_channel; 10318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (p2p_freq_to_channel(p2p->cfg->country, force_freq, 10328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt &op_reg_class, &op_channel) < 0) { 10338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG, 10348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "P2P: Unsupported frequency %u MHz", 10358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt force_freq); 10368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 10378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 10388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (!p2p_channels_includes(&p2p->cfg->channels, op_reg_class, 10398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt op_channel)) { 10408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG, 10418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "P2P: Frequency %u MHz (oper_class %u " 10428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "channel %u) not allowed for P2P", 10438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt force_freq, op_reg_class, op_channel); 10448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 10458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 10468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p->op_reg_class = op_reg_class; 10478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p->op_channel = op_channel; 10488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p->channels.reg_classes = 1; 10498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p->channels.reg_class[0].channels = 1; 10508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p->channels.reg_class[0].reg_class = p2p->op_reg_class; 10518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p->channels.reg_class[0].channel[0] = p2p->op_channel; 10528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } else { 10538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt u8 op_reg_class, op_channel; 10548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 10558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (!p2p->cfg->cfg_op_channel && p2p->best_freq_overall > 0 && 10568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_supported_freq(p2p, p2p->best_freq_overall) && 10578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_freq_to_channel(p2p->cfg->country, 10588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p->best_freq_overall, 10598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt &op_reg_class, &op_channel) == 0) { 10608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG, 10618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "P2P: Select best overall channel as " 10628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "operating channel preference"); 10638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p->op_reg_class = op_reg_class; 10648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p->op_channel = op_channel; 10658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } else if (!p2p->cfg->cfg_op_channel && p2p->best_freq_5 > 0 && 10668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_supported_freq(p2p, p2p->best_freq_5) && 10678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_freq_to_channel(p2p->cfg->country, 10688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p->best_freq_5, 10698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt &op_reg_class, &op_channel) == 10708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 0) { 10718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG, 10728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "P2P: Select best 5 GHz channel as " 10738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "operating channel preference"); 10748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p->op_reg_class = op_reg_class; 10758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p->op_channel = op_channel; 10768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } else if (!p2p->cfg->cfg_op_channel && 10778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p->best_freq_24 > 0 && 10788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_supported_freq(p2p, p2p->best_freq_24) && 10798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_freq_to_channel(p2p->cfg->country, 10808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p->best_freq_24, 10818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt &op_reg_class, &op_channel) == 10828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 0) { 10838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG, 10848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "P2P: Select best 2.4 GHz channel as " 10858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "operating channel preference"); 10868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p->op_reg_class = op_reg_class; 10878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p->op_channel = op_channel; 10888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } else { 10898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p->op_reg_class = p2p->cfg->op_reg_class; 10908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p->op_channel = p2p->cfg->op_channel; 10918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 10928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 10938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memcpy(&p2p->channels, &p2p->cfg->channels, 10948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sizeof(struct p2p_channels)); 10958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 10968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG, 10978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "P2P: Own preference for operation channel: " 10988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "Operating Class %u Channel %u%s", 10998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p->op_reg_class, p2p->op_channel, 11008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt force_freq ? " (forced)" : ""); 11018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 11028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 11038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 11048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 11058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 11061f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidtstatic void p2p_set_dev_persistent(struct p2p_device *dev, 11071f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt int persistent_group) 11081f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt{ 11091f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt switch (persistent_group) { 11101f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt case 0: 11111f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt dev->flags &= ~(P2P_DEV_PREFER_PERSISTENT_GROUP | 11121f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt P2P_DEV_PREFER_PERSISTENT_RECONN); 11131f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt break; 11141f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt case 1: 11151f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt dev->flags |= P2P_DEV_PREFER_PERSISTENT_GROUP; 11161f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt dev->flags &= ~P2P_DEV_PREFER_PERSISTENT_RECONN; 11171f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt break; 11181f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt case 2: 11191f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt dev->flags |= P2P_DEV_PREFER_PERSISTENT_GROUP | 11201f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt P2P_DEV_PREFER_PERSISTENT_RECONN; 11211f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt break; 11221f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt } 11231f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt} 11241f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt 11251f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt 11268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtint p2p_connect(struct p2p_data *p2p, const u8 *peer_addr, 11278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt enum p2p_wps_method wps_method, 11288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt int go_intent, const u8 *own_interface_addr, 11298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt unsigned int force_freq, int persistent_group) 11308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 11318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct p2p_device *dev; 11328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 11338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG, 11348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "P2P: Request to start group negotiation - peer=" MACSTR 11358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt " GO Intent=%d Intended Interface Address=" MACSTR 11368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt " wps_method=%d persistent_group=%d", 11378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt MAC2STR(peer_addr), go_intent, MAC2STR(own_interface_addr), 11388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wps_method, persistent_group); 11398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 11408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (p2p_prepare_channel(p2p, force_freq) < 0) 11418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 11428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 11431f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt p2p->ssid_set = 0; 11448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt dev = p2p_get_device(p2p, peer_addr); 11458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (dev == NULL || (dev->flags & P2P_DEV_PROBE_REQ_ONLY)) { 11468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG, 11478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "P2P: Cannot connect to unknown P2P Device " MACSTR, 11488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt MAC2STR(peer_addr)); 11498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 11508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 11518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 11528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (dev->flags & P2P_DEV_GROUP_CLIENT_ONLY) { 11538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (!(dev->info.dev_capab & 11548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt P2P_DEV_CAPAB_CLIENT_DISCOVERABILITY)) { 11558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG, 11568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "P2P: Cannot connect to P2P Device " MACSTR 11578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt " that is in a group and is not discoverable", 11588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt MAC2STR(peer_addr)); 11598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 11608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 11618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (dev->oper_freq <= 0) { 11628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG, 11638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "P2P: Cannot connect to P2P Device " MACSTR 11648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt " with incomplete information", 11658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt MAC2STR(peer_addr)); 11668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 11678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 11688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 11698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* 11708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * First, try to connect directly. If the peer does not 11718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * acknowledge frames, assume it is sleeping and use device 11728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * discoverability via the GO at that point. 11738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */ 11748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 11758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 11768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt dev->flags &= ~P2P_DEV_NOT_YET_READY; 11778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt dev->flags &= ~P2P_DEV_USER_REJECTED; 11788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt dev->flags &= ~P2P_DEV_WAIT_GO_NEG_RESPONSE; 11798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt dev->flags &= ~P2P_DEV_WAIT_GO_NEG_CONFIRM; 11808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt dev->connect_reqs = 0; 11818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt dev->go_neg_req_sent = 0; 11828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt dev->go_state = UNKNOWN_GO; 11831f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt p2p_set_dev_persistent(dev, persistent_group); 11848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p->go_intent = go_intent; 11858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memcpy(p2p->intended_addr, own_interface_addr, ETH_ALEN); 11868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 11878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (p2p->state != P2P_IDLE) 11888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_stop_find(p2p); 11898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 11908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (p2p->after_scan_tx) { 11918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* 11928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * We need to drop the pending frame to avoid issues with the 11938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * new GO Negotiation, e.g., when the pending frame was from a 11948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * previous attempt at starting a GO Negotiation. 11958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */ 11968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG, "P2P: Dropped " 11978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "previous pending Action frame TX that was waiting " 11988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "for p2p_scan completion"); 11998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_free(p2p->after_scan_tx); 12008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p->after_scan_tx = NULL; 12018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 12028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 12038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt dev->wps_method = wps_method; 12048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt dev->status = P2P_SC_SUCCESS; 12058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 12068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (force_freq) 12078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt dev->flags |= P2P_DEV_FORCE_FREQ; 12088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt else 12098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt dev->flags &= ~P2P_DEV_FORCE_FREQ; 12108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 12118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (p2p->p2p_scan_running) { 12128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG, 12138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "P2P: p2p_scan running - delay connect send"); 12148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p->start_after_scan = P2P_AFTER_SCAN_CONNECT; 12158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memcpy(p2p->after_scan_peer, peer_addr, ETH_ALEN); 12168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 12178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 12188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p->start_after_scan = P2P_AFTER_SCAN_NOTHING; 12198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 12208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return p2p_connect_send(p2p, dev); 12218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 12228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 12238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 12248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtint p2p_authorize(struct p2p_data *p2p, const u8 *peer_addr, 12258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt enum p2p_wps_method wps_method, 12268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt int go_intent, const u8 *own_interface_addr, 12278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt unsigned int force_freq, int persistent_group) 12288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 12298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct p2p_device *dev; 12308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 12318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG, 12328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "P2P: Request to authorize group negotiation - peer=" MACSTR 12338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt " GO Intent=%d Intended Interface Address=" MACSTR 12348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt " wps_method=%d persistent_group=%d", 12358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt MAC2STR(peer_addr), go_intent, MAC2STR(own_interface_addr), 12368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wps_method, persistent_group); 12378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 12388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (p2p_prepare_channel(p2p, force_freq) < 0) 12398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 12408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 12418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt dev = p2p_get_device(p2p, peer_addr); 12428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (dev == NULL) { 12438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG, 12448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "P2P: Cannot authorize unknown P2P Device " MACSTR, 12458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt MAC2STR(peer_addr)); 12468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 12478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 12488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 12498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt dev->flags &= ~P2P_DEV_NOT_YET_READY; 12508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt dev->flags &= ~P2P_DEV_USER_REJECTED; 12518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt dev->go_neg_req_sent = 0; 12528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt dev->go_state = UNKNOWN_GO; 12531f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt p2p_set_dev_persistent(dev, persistent_group); 12548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p->go_intent = go_intent; 12558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memcpy(p2p->intended_addr, own_interface_addr, ETH_ALEN); 12568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 12578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt dev->wps_method = wps_method; 12588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt dev->status = P2P_SC_SUCCESS; 12598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 12608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (force_freq) 12618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt dev->flags |= P2P_DEV_FORCE_FREQ; 12628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt else 12638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt dev->flags &= ~P2P_DEV_FORCE_FREQ; 12648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 12658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 12668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 12678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 12688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 12698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtvoid p2p_add_dev_info(struct p2p_data *p2p, const u8 *addr, 12708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct p2p_device *dev, struct p2p_message *msg) 12718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 12728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_get_time(&dev->last_seen); 12738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 12748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_copy_wps_info(dev, 0, msg); 12758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 12768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (msg->listen_channel) { 12778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt int freq; 12788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt freq = p2p_channel_to_freq((char *) msg->listen_channel, 12798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt msg->listen_channel[3], 12808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt msg->listen_channel[4]); 12818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (freq < 0) { 12828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG, 12838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "P2P: Unknown peer Listen channel: " 12848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "country=%c%c(0x%02x) reg_class=%u channel=%u", 12858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt msg->listen_channel[0], 12868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt msg->listen_channel[1], 12878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt msg->listen_channel[2], 12888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt msg->listen_channel[3], 12898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt msg->listen_channel[4]); 12908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } else { 12918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG, "P2P: Update " 12928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "peer " MACSTR " Listen channel: %u -> %u MHz", 12938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt MAC2STR(dev->info.p2p_device_addr), 12948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt dev->listen_freq, freq); 12958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt dev->listen_freq = freq; 12968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 12978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 12988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 12998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (dev->flags & P2P_DEV_PROBE_REQ_ONLY) { 13008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt dev->flags &= ~P2P_DEV_PROBE_REQ_ONLY; 13018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG, 13028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "P2P: Completed device entry based on data from " 13038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "GO Negotiation Request"); 13048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } else { 13058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG, 13068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "P2P: Created device entry based on GO Neg Req: " 13078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt MACSTR " dev_capab=0x%x group_capab=0x%x name='%s' " 13088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "listen_freq=%d", 13098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt MAC2STR(dev->info.p2p_device_addr), 13108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt dev->info.dev_capab, dev->info.group_capab, 13118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt dev->info.device_name, dev->listen_freq); 13128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 13138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 13148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt dev->flags &= ~P2P_DEV_GROUP_CLIENT_ONLY; 13158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 13168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (dev->flags & P2P_DEV_USER_REJECTED) { 13178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG, 13188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "P2P: Do not report rejected device"); 13198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; 13208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 13218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 13228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p->cfg->dev_found(p2p->cfg->cb_ctx, addr, &dev->info, 13238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt !(dev->flags & P2P_DEV_REPORTED_ONCE)); 13248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt dev->flags |= P2P_DEV_REPORTED | P2P_DEV_REPORTED_ONCE; 13258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 13268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 13278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 13288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtvoid p2p_build_ssid(struct p2p_data *p2p, u8 *ssid, size_t *ssid_len) 13298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 13308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memcpy(ssid, P2P_WILDCARD_SSID, P2P_WILDCARD_SSID_LEN); 13318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_random((char *) &ssid[P2P_WILDCARD_SSID_LEN], 2); 13328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memcpy(&ssid[P2P_WILDCARD_SSID_LEN + 2], 13338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p->cfg->ssid_postfix, p2p->cfg->ssid_postfix_len); 13348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt *ssid_len = P2P_WILDCARD_SSID_LEN + 2 + p2p->cfg->ssid_postfix_len; 13358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 13368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 13378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 13388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtint p2p_go_params(struct p2p_data *p2p, struct p2p_go_neg_results *params) 13398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 13408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_build_ssid(p2p, params->ssid, ¶ms->ssid_len); 13418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_random(params->passphrase, 8); 13428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 13438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 13448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 13458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 13468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtvoid p2p_go_complete(struct p2p_data *p2p, struct p2p_device *peer) 13478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 13488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct p2p_go_neg_results res; 13498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt int go = peer->go_state == LOCAL_GO; 13508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct p2p_channels intersection; 13518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt int freqs; 13528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt size_t i, j; 13538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 13548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG, 13558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "P2P: GO Negotiation with " MACSTR " completed (%s will be " 13568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "GO)", MAC2STR(peer->info.p2p_device_addr), 13578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt go ? "local end" : "peer"); 13588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 13598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memset(&res, 0, sizeof(res)); 13608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt res.role_go = go; 13618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memcpy(res.peer_device_addr, peer->info.p2p_device_addr, ETH_ALEN); 13628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memcpy(res.peer_interface_addr, peer->intended_addr, ETH_ALEN); 13638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt res.wps_method = peer->wps_method; 13641f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt if (peer->flags & P2P_DEV_PREFER_PERSISTENT_GROUP) { 13651f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt if (peer->flags & P2P_DEV_PREFER_PERSISTENT_RECONN) 13661f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt res.persistent_group = 2; 13671f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt else 13681f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt res.persistent_group = 1; 13691f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt } 13708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 13718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (go) { 13728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* Setup AP mode for WPS provisioning */ 13738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt res.freq = p2p_channel_to_freq(p2p->cfg->country, 13748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p->op_reg_class, 13758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p->op_channel); 13768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memcpy(res.ssid, p2p->ssid, p2p->ssid_len); 13778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt res.ssid_len = p2p->ssid_len; 13788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_random(res.passphrase, 8); 13798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } else { 13808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt res.freq = peer->oper_freq; 13818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (p2p->ssid_len) { 13828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memcpy(res.ssid, p2p->ssid, p2p->ssid_len); 13838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt res.ssid_len = p2p->ssid_len; 13848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 13858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 13868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 13878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_channels_intersect(&p2p->channels, &peer->channels, 13888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt &intersection); 13898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt freqs = 0; 13908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt for (i = 0; i < intersection.reg_classes; i++) { 13918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct p2p_reg_class *c = &intersection.reg_class[i]; 13928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (freqs + 1 == P2P_MAX_CHANNELS) 13938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 13948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt for (j = 0; j < c->channels; j++) { 13958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt int freq; 13968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (freqs + 1 == P2P_MAX_CHANNELS) 13978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 13988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt freq = p2p_channel_to_freq(peer->country, c->reg_class, 13998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt c->channel[j]); 14008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (freq < 0) 14018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt continue; 14028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt res.freq_list[freqs++] = freq; 14038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 14048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 14058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 14068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt res.peer_config_timeout = go ? peer->client_timeout : peer->go_timeout; 14078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 14088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_clear_timeout(p2p); 14091f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt p2p->ssid_set = 0; 14108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt peer->go_neg_req_sent = 0; 14118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt peer->wps_method = WPS_NOT_READY; 14128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 14138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_set_state(p2p, P2P_PROVISIONING); 14148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p->cfg->go_neg_completed(p2p->cfg->cb_ctx, &res); 14158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 14168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 14178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 14188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic void p2p_rx_p2p_action(struct p2p_data *p2p, const u8 *sa, 14198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt const u8 *data, size_t len, int rx_freq) 14208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 14218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG, 14228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "P2P: RX P2P Public Action from " MACSTR, MAC2STR(sa)); 14238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_hexdump(MSG_MSGDUMP, "P2P: P2P Public Action contents", data, len); 14248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 14258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (len < 1) 14268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; 14278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 14288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt switch (data[0]) { 14298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case P2P_GO_NEG_REQ: 14308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_process_go_neg_req(p2p, sa, data + 1, len - 1, rx_freq); 14318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 14328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case P2P_GO_NEG_RESP: 14338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_process_go_neg_resp(p2p, sa, data + 1, len - 1, rx_freq); 14348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 14358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case P2P_GO_NEG_CONF: 14368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_process_go_neg_conf(p2p, sa, data + 1, len - 1); 14378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 14388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case P2P_INVITATION_REQ: 14398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_process_invitation_req(p2p, sa, data + 1, len - 1, 14408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt rx_freq); 14418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 14428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case P2P_INVITATION_RESP: 14438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_process_invitation_resp(p2p, sa, data + 1, len - 1); 14448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 14458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case P2P_PROV_DISC_REQ: 14468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_process_prov_disc_req(p2p, sa, data + 1, len - 1, rx_freq); 14478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 14488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case P2P_PROV_DISC_RESP: 14498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_process_prov_disc_resp(p2p, sa, data + 1, len - 1); 14508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 14518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case P2P_DEV_DISC_REQ: 14528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_process_dev_disc_req(p2p, sa, data + 1, len - 1, rx_freq); 14538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 14548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case P2P_DEV_DISC_RESP: 14558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_process_dev_disc_resp(p2p, sa, data + 1, len - 1); 14568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 14578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt default: 14588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG, 14598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "P2P: Unsupported P2P Public Action frame type %d", 14608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt data[0]); 14618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 14628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 14638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 14648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 14658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 14661f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidtstatic void p2p_rx_action_public(struct p2p_data *p2p, const u8 *da, 14671f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt const u8 *sa, const u8 *bssid, const u8 *data, 14681f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt size_t len, int freq) 14698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 14708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (len < 1) 14718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; 14728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 14738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt switch (data[0]) { 14748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case WLAN_PA_VENDOR_SPECIFIC: 14758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt data++; 14768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt len--; 14778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (len < 3) 14788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; 14798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (WPA_GET_BE24(data) != OUI_WFA) 14808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; 14818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 14828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt data += 3; 14838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt len -= 3; 14848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (len < 1) 14858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; 14868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 14878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (*data != P2P_OUI_TYPE) 14888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; 14898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 14908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_rx_p2p_action(p2p, sa, data + 1, len - 1, freq); 14918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 14928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case WLAN_PA_GAS_INITIAL_REQ: 14938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_rx_gas_initial_req(p2p, sa, data + 1, len - 1, freq); 14948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 14958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case WLAN_PA_GAS_INITIAL_RESP: 14968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_rx_gas_initial_resp(p2p, sa, data + 1, len - 1, freq); 14978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 14988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case WLAN_PA_GAS_COMEBACK_REQ: 14998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_rx_gas_comeback_req(p2p, sa, data + 1, len - 1, freq); 15008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 15018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case WLAN_PA_GAS_COMEBACK_RESP: 15028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_rx_gas_comeback_resp(p2p, sa, data + 1, len - 1, freq); 15038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 15048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 15058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 15068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 15078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 15088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtvoid p2p_rx_action(struct p2p_data *p2p, const u8 *da, const u8 *sa, 15098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt const u8 *bssid, u8 category, 15108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt const u8 *data, size_t len, int freq) 15118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 15128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (category == WLAN_ACTION_PUBLIC) { 15138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_rx_action_public(p2p, da, sa, bssid, data, len, freq); 15148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; 15158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 15168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 15178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (category != WLAN_ACTION_VENDOR_SPECIFIC) 15188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; 15198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 15208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (len < 4) 15218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; 15228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 15238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (WPA_GET_BE24(data) != OUI_WFA) 15248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; 15258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt data += 3; 15268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt len -= 3; 15278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 15288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (*data != P2P_OUI_TYPE) 15298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; 15308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt data++; 15318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt len--; 15328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 15338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* P2P action frame */ 15348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG, 15358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "P2P: RX P2P Action from " MACSTR, MAC2STR(sa)); 15368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_hexdump(MSG_MSGDUMP, "P2P: P2P Action contents", data, len); 15378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 15388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (len < 1) 15398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; 15408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt switch (data[0]) { 15418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case P2P_NOA: 15428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG, 15438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "P2P: Received P2P Action - Notice of Absence"); 15448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* TODO */ 15458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 15468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case P2P_PRESENCE_REQ: 15478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_process_presence_req(p2p, da, sa, data + 1, len - 1, freq); 15488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 15498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case P2P_PRESENCE_RESP: 15508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_process_presence_resp(p2p, da, sa, data + 1, len - 1); 15518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 15528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case P2P_GO_DISC_REQ: 15538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_process_go_disc_req(p2p, da, sa, data + 1, len - 1, freq); 15548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 15558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt default: 15568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG, 15578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "P2P: Received P2P Action - unknown type %u", data[0]); 15588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 15598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 15608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 15618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 15628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 15638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic void p2p_go_neg_start(void *eloop_ctx, void *timeout_ctx) 15648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 15658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct p2p_data *p2p = eloop_ctx; 15668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (p2p->go_neg_peer == NULL) 15678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; 15688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p->cfg->stop_listen(p2p->cfg->cb_ctx); 15698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p->go_neg_peer->status = P2P_SC_SUCCESS; 15708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_connect_send(p2p, p2p->go_neg_peer); 15718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 15728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 15738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 15748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic void p2p_invite_start(void *eloop_ctx, void *timeout_ctx) 15758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 15768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct p2p_data *p2p = eloop_ctx; 15778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (p2p->invite_peer == NULL) 15788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; 15798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p->cfg->stop_listen(p2p->cfg->cb_ctx); 15808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_invite_send(p2p, p2p->invite_peer, p2p->invite_go_dev_addr); 15818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 15828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 15838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 15848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic void p2p_add_dev_from_probe_req(struct p2p_data *p2p, const u8 *addr, 15858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt const u8 *ie, size_t ie_len) 15868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 15878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct p2p_message msg; 15888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct p2p_device *dev; 15898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 15908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memset(&msg, 0, sizeof(msg)); 15918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (p2p_parse_ies(ie, ie_len, &msg) < 0 || msg.p2p_attributes == NULL) 15928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt { 15938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_parse_free(&msg); 15948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; /* not a P2P probe */ 15958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 15968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 15978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (msg.ssid == NULL || msg.ssid[1] != P2P_WILDCARD_SSID_LEN || 15988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memcmp(msg.ssid + 2, P2P_WILDCARD_SSID, P2P_WILDCARD_SSID_LEN) 15998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt != 0) { 16008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* The Probe Request is not part of P2P Device Discovery. It is 16018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * not known whether the source address of the frame is the P2P 16028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * Device Address or P2P Interface Address. Do not add a new 16038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * peer entry based on this frames. 16048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */ 16058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_parse_free(&msg); 16068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; 16078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 16088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 16098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt dev = p2p_get_device(p2p, addr); 16108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (dev) { 16118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (dev->country[0] == 0 && msg.listen_channel) 16128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memcpy(dev->country, msg.listen_channel, 3); 16131f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt os_get_time(&dev->last_seen); 16148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_parse_free(&msg); 16158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; /* already known */ 16168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 16178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 16188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt dev = p2p_create_device(p2p, addr); 16198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (dev == NULL) { 16208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_parse_free(&msg); 16218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; 16228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 16238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 16248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_get_time(&dev->last_seen); 16258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt dev->flags |= P2P_DEV_PROBE_REQ_ONLY; 16268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 16278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (msg.listen_channel) { 16288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memcpy(dev->country, msg.listen_channel, 3); 16298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt dev->listen_freq = p2p_channel_to_freq(dev->country, 16308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt msg.listen_channel[3], 16318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt msg.listen_channel[4]); 16328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 16338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 16348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_copy_wps_info(dev, 1, &msg); 16358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 16368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_parse_free(&msg); 16378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 16388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG, 16398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "P2P: Created device entry based on Probe Req: " MACSTR 16408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt " dev_capab=0x%x group_capab=0x%x name='%s' listen_freq=%d", 16418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt MAC2STR(dev->info.p2p_device_addr), dev->info.dev_capab, 16428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt dev->info.group_capab, dev->info.device_name, 16438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt dev->listen_freq); 16448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 16458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 16468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 16478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstruct p2p_device * p2p_add_dev_from_go_neg_req(struct p2p_data *p2p, 16488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt const u8 *addr, 16498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct p2p_message *msg) 16508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 16518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct p2p_device *dev; 16528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 16538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt dev = p2p_get_device(p2p, addr); 16548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (dev) { 16558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_get_time(&dev->last_seen); 16568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return dev; /* already known */ 16578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 16588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 16598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt dev = p2p_create_device(p2p, addr); 16608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (dev == NULL) 16618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return NULL; 16628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 16638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_add_dev_info(p2p, addr, dev, msg); 16648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 16658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return dev; 16668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 16678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 16688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 16698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic int dev_type_match(const u8 *dev_type, const u8 *req_dev_type) 16708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 16718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (os_memcmp(dev_type, req_dev_type, WPS_DEV_TYPE_LEN) == 0) 16728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 1; 16738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (os_memcmp(dev_type, req_dev_type, 2) == 0 && 16748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt WPA_GET_BE32(&req_dev_type[2]) == 0 && 16758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt WPA_GET_BE16(&req_dev_type[6]) == 0) 16768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 1; /* Category match with wildcard OUI/sub-category */ 16778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 16788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 16798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 16808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 16818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtint dev_type_list_match(const u8 *dev_type, const u8 *req_dev_type[], 16828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt size_t num_req_dev_type) 16838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 16848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt size_t i; 16858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt for (i = 0; i < num_req_dev_type; i++) { 16868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (dev_type_match(dev_type, req_dev_type[i])) 16878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 1; 16888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 16898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 16908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 16918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 16928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 16938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt/** 16948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * p2p_match_dev_type - Match local device type with requested type 16958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @p2p: P2P module context from p2p_init() 16968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @wps: WPS TLVs from Probe Request frame (concatenated WPS IEs) 16978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * Returns: 1 on match, 0 on mismatch 16988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * 16998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * This function can be used to match the Requested Device Type attribute in 17008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * WPS IE with the local device types for deciding whether to reply to a Probe 17018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * Request frame. 17028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */ 17038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtint p2p_match_dev_type(struct p2p_data *p2p, struct wpabuf *wps) 17048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 17058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct wps_parse_attr attr; 17068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt size_t i; 17078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 17088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (wps_parse_msg(wps, &attr)) 17098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 1; /* assume no Requested Device Type attributes */ 17108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 17118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (attr.num_req_dev_type == 0) 17128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 1; /* no Requested Device Type attributes -> match */ 17138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 17148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (dev_type_list_match(p2p->cfg->pri_dev_type, attr.req_dev_type, 17158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt attr.num_req_dev_type)) 17168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 1; /* Own Primary Device Type matches */ 17178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 17188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt for (i = 0; i < p2p->cfg->num_sec_dev_types; i++) 17198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (dev_type_list_match(p2p->cfg->sec_dev_type[i], 17208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt attr.req_dev_type, 17218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt attr.num_req_dev_type)) 17228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 1; /* Own Secondary Device Type matches */ 17238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 17248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* No matching device type found */ 17258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 17268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 17278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 17288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 17298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstruct wpabuf * p2p_build_probe_resp_ies(struct p2p_data *p2p) 17308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 17318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct wpabuf *buf; 17328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt u8 *len; 17338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 17348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt buf = wpabuf_alloc(1000); 17358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (buf == NULL) 17368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return NULL; 17378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 17388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_build_wps_ie(p2p, buf, DEV_PW_DEFAULT, 1); 17398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 17408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* P2P IE */ 17418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt len = p2p_buf_add_ie_hdr(buf); 17428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_buf_add_capability(buf, p2p->dev_capab, 0); 17438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (p2p->ext_listen_interval) 17448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_buf_add_ext_listen_timing(buf, p2p->ext_listen_period, 17458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p->ext_listen_interval); 17468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_buf_add_device_info(buf, p2p, NULL); 17478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_buf_update_ie_hdr(buf, len); 17488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 17498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return buf; 17508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 17518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 17528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 17531f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidtstatic int is_11b(u8 rate) 17541f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt{ 17551f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt return rate == 0x02 || rate == 0x04 || rate == 0x0b || rate == 0x16; 17561f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt} 17571f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt 17581f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt 17591f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidtstatic int supp_rates_11b_only(struct ieee802_11_elems *elems) 17601f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt{ 17611f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt int num_11b = 0, num_others = 0; 17621f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt int i; 17631f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt 17641f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt if (elems->supp_rates == NULL && elems->ext_supp_rates == NULL) 17651f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt return 0; 17661f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt 17671f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt for (i = 0; elems->supp_rates && i < elems->supp_rates_len; i++) { 17681f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt if (is_11b(elems->supp_rates[i])) 17691f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt num_11b++; 17701f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt else 17711f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt num_others++; 17721f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt } 17731f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt 17741f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt for (i = 0; elems->ext_supp_rates && i < elems->ext_supp_rates_len; 17751f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt i++) { 17761f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt if (is_11b(elems->ext_supp_rates[i])) 17771f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt num_11b++; 17781f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt else 17791f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt num_others++; 17801f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt } 17811f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt 17821f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt return num_11b > 0 && num_others == 0; 17831f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt} 17841f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt 17851f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt 17861f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidtstatic void p2p_reply_probe(struct p2p_data *p2p, const u8 *addr, 17871f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt const u8 *dst, const u8 *bssid, const u8 *ie, 17888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt size_t ie_len) 17898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 17908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct ieee802_11_elems elems; 17918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct wpabuf *buf; 17928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct ieee80211_mgmt *resp; 17931f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt struct p2p_message msg; 17948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct wpabuf *ies; 17958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 17968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (!p2p->in_listen || !p2p->drv_in_listen) { 17978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* not in Listen state - ignore Probe Request */ 17988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; 17998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 18008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 18018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (ieee802_11_parse_elems((u8 *) ie, ie_len, &elems, 0) == 18028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ParseFailed) { 18038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* Ignore invalid Probe Request frames */ 18048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; 18058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 18068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 18078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (elems.p2p == NULL) { 18088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* not a P2P probe - ignore it */ 18098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; 18108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 18118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 18121f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt if (dst && !is_broadcast_ether_addr(dst) && 18131f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt os_memcmp(dst, p2p->cfg->dev_addr, ETH_ALEN) != 0) { 18141f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt /* Not sent to the broadcast address or our P2P Device Address 18151f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt */ 18161f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt return; 18171f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt } 18181f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt 18191f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt if (bssid && !is_broadcast_ether_addr(bssid)) { 18201f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt /* Not sent to the Wildcard BSSID */ 18211f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt return; 18221f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt } 18231f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt 18248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (elems.ssid == NULL || elems.ssid_len != P2P_WILDCARD_SSID_LEN || 18258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memcmp(elems.ssid, P2P_WILDCARD_SSID, P2P_WILDCARD_SSID_LEN) != 18268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 0) { 18278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* not using P2P Wildcard SSID - ignore */ 18288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; 18298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 18308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 18311f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt if (supp_rates_11b_only(&elems)) { 18321f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt /* Indicates support for 11b rates only */ 18331f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt return; 18341f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt } 18351f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt 18361f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt os_memset(&msg, 0, sizeof(msg)); 18371f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt if (p2p_parse_ies(ie, ie_len, &msg) < 0) { 18381f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt /* Could not parse P2P attributes */ 18391f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt return; 18401f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt } 18411f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt 18421f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt if (msg.device_id && 18431f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt os_memcmp(msg.device_id, p2p->cfg->dev_addr, ETH_ALEN != 0)) { 18441f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt /* Device ID did not match */ 18451f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt p2p_parse_free(&msg); 18461f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt return; 18471f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt } 18481f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt 18498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* Check Requested Device Type match */ 18501f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt if (msg.wps_attributes && 18511f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt !p2p_match_dev_type(p2p, msg.wps_attributes)) { 18528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* No match with Requested Device Type */ 18531f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt p2p_parse_free(&msg); 18548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; 18558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 18561f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt p2p_parse_free(&msg); 18578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 18588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (!p2p->cfg->send_probe_resp) 18598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; /* Response generated elsewhere */ 18608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 18618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG, 18628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "P2P: Reply to P2P Probe Request in Listen state"); 18638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 18648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* 18658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * We do not really have a specific BSS that this frame is advertising, 18668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * so build a frame that has some information in valid format. This is 18678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * really only used for discovery purposes, not to learn exact BSS 18688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * parameters. 18698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */ 18708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ies = p2p_build_probe_resp_ies(p2p); 18718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (ies == NULL) 18728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; 18738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 18748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt buf = wpabuf_alloc(200 + wpabuf_len(ies)); 18758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (buf == NULL) { 18768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpabuf_free(ies); 18778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; 18788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 18798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 18808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt resp = NULL; 18818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt resp = wpabuf_put(buf, resp->u.probe_resp.variable - (u8 *) resp); 18828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 18838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt resp->frame_control = host_to_le16((WLAN_FC_TYPE_MGMT << 2) | 18848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt (WLAN_FC_STYPE_PROBE_RESP << 4)); 18858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memcpy(resp->da, addr, ETH_ALEN); 18868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memcpy(resp->sa, p2p->cfg->dev_addr, ETH_ALEN); 18878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memcpy(resp->bssid, p2p->cfg->dev_addr, ETH_ALEN); 18888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt resp->u.probe_resp.beacon_int = host_to_le16(100); 18898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* hardware or low-level driver will setup seq_ctrl and timestamp */ 18908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt resp->u.probe_resp.capab_info = 18918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt host_to_le16(WLAN_CAPABILITY_SHORT_PREAMBLE | 18928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt WLAN_CAPABILITY_PRIVACY | 18938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt WLAN_CAPABILITY_SHORT_SLOT_TIME); 18948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 18958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpabuf_put_u8(buf, WLAN_EID_SSID); 18968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpabuf_put_u8(buf, P2P_WILDCARD_SSID_LEN); 18978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpabuf_put_data(buf, P2P_WILDCARD_SSID, P2P_WILDCARD_SSID_LEN); 18988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 18998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpabuf_put_u8(buf, WLAN_EID_SUPP_RATES); 19008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpabuf_put_u8(buf, 8); 19018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpabuf_put_u8(buf, (60 / 5) | 0x80); 19028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpabuf_put_u8(buf, 90 / 5); 19038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpabuf_put_u8(buf, (120 / 5) | 0x80); 19048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpabuf_put_u8(buf, 180 / 5); 19058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpabuf_put_u8(buf, (240 / 5) | 0x80); 19068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpabuf_put_u8(buf, 360 / 5); 19078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpabuf_put_u8(buf, 480 / 5); 19088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpabuf_put_u8(buf, 540 / 5); 19098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 19108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpabuf_put_u8(buf, WLAN_EID_DS_PARAMS); 19118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpabuf_put_u8(buf, 1); 19128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpabuf_put_u8(buf, p2p->cfg->channel); 19138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 19148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpabuf_put_buf(buf, ies); 19158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpabuf_free(ies); 19168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 19178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p->cfg->send_probe_resp(p2p->cfg->cb_ctx, buf); 19188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 19198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpabuf_free(buf); 19208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 19218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 19228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 19231f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidtint p2p_probe_req_rx(struct p2p_data *p2p, const u8 *addr, const u8 *dst, 19241f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt const u8 *bssid, const u8 *ie, size_t ie_len) 19258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 19268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_add_dev_from_probe_req(p2p, addr, ie, ie_len); 19278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 19281f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt p2p_reply_probe(p2p, addr, dst, bssid, ie, ie_len); 19298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 19308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if ((p2p->state == P2P_CONNECT || p2p->state == P2P_CONNECT_LISTEN) && 19318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p->go_neg_peer && 19328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memcmp(addr, p2p->go_neg_peer->info.p2p_device_addr, ETH_ALEN) 19338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt == 0) { 19348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* Received a Probe Request from GO Negotiation peer */ 19358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG, 19368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "P2P: Found GO Negotiation peer - try to start GO " 19378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "negotiation from timeout"); 19388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt eloop_register_timeout(0, 0, p2p_go_neg_start, p2p, NULL); 19398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 1; 19408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 19418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 19428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if ((p2p->state == P2P_INVITE || p2p->state == P2P_INVITE_LISTEN) && 19438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p->invite_peer && 19448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memcmp(addr, p2p->invite_peer->info.p2p_device_addr, ETH_ALEN) 19458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt == 0) { 19468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* Received a Probe Request from Invite peer */ 19478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG, 19488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "P2P: Found Invite peer - try to start Invite from " 19498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "timeout"); 19508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt eloop_register_timeout(0, 0, p2p_invite_start, p2p, NULL); 19518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 1; 19528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 19538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 19548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 19558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 19568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 19578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 19588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic int p2p_assoc_req_ie_wlan_ap(struct p2p_data *p2p, const u8 *bssid, 19598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt u8 *buf, size_t len, struct wpabuf *p2p_ie) 19608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 19618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct wpabuf *tmp; 19628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt u8 *lpos; 19638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt size_t tmplen; 19648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt int res; 19658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt u8 group_capab; 19668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 19678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (p2p_ie == NULL) 19688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; /* WLAN AP is not a P2P manager */ 19698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 19708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* 19718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * (Re)Association Request - P2P IE 19728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * P2P Capability attribute (shall be present) 19738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * P2P Interface attribute (present if concurrent device and 19748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * P2P Management is enabled) 19758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */ 19768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt tmp = wpabuf_alloc(200); 19778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (tmp == NULL) 19788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 19798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 19808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt lpos = p2p_buf_add_ie_hdr(tmp); 19818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt group_capab = 0; 19828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (p2p->num_groups > 0) { 19838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt group_capab |= P2P_GROUP_CAPAB_GROUP_OWNER; 19848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if ((p2p->dev_capab & P2P_DEV_CAPAB_CONCURRENT_OPER) && 19858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt (p2p->dev_capab & P2P_DEV_CAPAB_INFRA_MANAGED) && 19868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p->cross_connect) 19878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt group_capab |= P2P_GROUP_CAPAB_CROSS_CONN; 19888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 19898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_buf_add_capability(tmp, p2p->dev_capab, group_capab); 19908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if ((p2p->dev_capab & P2P_DEV_CAPAB_CONCURRENT_OPER) && 19918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt (p2p->dev_capab & P2P_DEV_CAPAB_INFRA_MANAGED)) 19928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_buf_add_p2p_interface(tmp, p2p); 19938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_buf_update_ie_hdr(tmp, lpos); 19948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 19958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt tmplen = wpabuf_len(tmp); 19968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (tmplen > len) 19978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt res = -1; 19988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt else { 19998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memcpy(buf, wpabuf_head(tmp), tmplen); 20008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt res = tmplen; 20018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 20028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpabuf_free(tmp); 20038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 20048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return res; 20058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 20068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 20078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 20088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtint p2p_assoc_req_ie(struct p2p_data *p2p, const u8 *bssid, u8 *buf, 20098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt size_t len, int p2p_group, struct wpabuf *p2p_ie) 20108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 20118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct wpabuf *tmp; 20128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt u8 *lpos; 20138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct p2p_device *peer; 20148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt size_t tmplen; 20158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt int res; 20168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 20178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (!p2p_group) 20188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return p2p_assoc_req_ie_wlan_ap(p2p, bssid, buf, len, p2p_ie); 20198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 20208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* 20218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * (Re)Association Request - P2P IE 20228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * P2P Capability attribute (shall be present) 20238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * Extended Listen Timing (may be present) 20248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * P2P Device Info attribute (shall be present) 20258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */ 20268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt tmp = wpabuf_alloc(200); 20278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (tmp == NULL) 20288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 20298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 20308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt peer = bssid ? p2p_get_device(p2p, bssid) : NULL; 20318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 20328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt lpos = p2p_buf_add_ie_hdr(tmp); 20338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_buf_add_capability(tmp, p2p->dev_capab, 0); 20348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (p2p->ext_listen_interval) 20358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_buf_add_ext_listen_timing(tmp, p2p->ext_listen_period, 20368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p->ext_listen_interval); 20378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_buf_add_device_info(tmp, p2p, peer); 20388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_buf_update_ie_hdr(tmp, lpos); 20398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 20408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt tmplen = wpabuf_len(tmp); 20418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (tmplen > len) 20428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt res = -1; 20438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt else { 20448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memcpy(buf, wpabuf_head(tmp), tmplen); 20458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt res = tmplen; 20468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 20478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpabuf_free(tmp); 20488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 20498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return res; 20508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 20518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 20528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 20538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtint p2p_scan_result_text(const u8 *ies, size_t ies_len, char *buf, char *end) 20548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 20558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct wpabuf *p2p_ie; 20568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt int ret; 20578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 20588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_ie = ieee802_11_vendor_ie_concat(ies, ies_len, P2P_IE_VENDOR_TYPE); 20598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (p2p_ie == NULL) 20608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 20618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 20628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ret = p2p_attr_text(p2p_ie, buf, end); 20638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpabuf_free(p2p_ie); 20648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return ret; 20658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 20668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 20678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 20688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic void p2p_clear_go_neg(struct p2p_data *p2p) 20698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 20708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p->go_neg_peer = NULL; 20718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_clear_timeout(p2p); 20728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_set_state(p2p, P2P_IDLE); 20738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 20748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 20758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 20768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtvoid p2p_wps_success_cb(struct p2p_data *p2p, const u8 *mac_addr) 20778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 20788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (p2p->go_neg_peer == NULL) { 20798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG, 20808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "P2P: No pending Group Formation - " 20818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "ignore WPS registration success notification"); 20828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; /* No pending Group Formation */ 20838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 20848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 20858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (os_memcmp(mac_addr, p2p->go_neg_peer->intended_addr, ETH_ALEN) != 20868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 0) { 20878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG, 20888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "P2P: Ignore WPS registration success notification " 20898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "for " MACSTR " (GO Negotiation peer " MACSTR ")", 20908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt MAC2STR(mac_addr), 20918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt MAC2STR(p2p->go_neg_peer->intended_addr)); 20928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; /* Ignore unexpected peer address */ 20938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 20948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 20958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG, 20968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "P2P: Group Formation completed successfully with " MACSTR, 20978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt MAC2STR(mac_addr)); 20988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 20998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_clear_go_neg(p2p); 21008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 21018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 21028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 21038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtvoid p2p_group_formation_failed(struct p2p_data *p2p) 21048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 21058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (p2p->go_neg_peer == NULL) { 21068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG, 21078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "P2P: No pending Group Formation - " 21088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "ignore group formation failure notification"); 21098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; /* No pending Group Formation */ 21108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 21118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 21128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG, 21138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "P2P: Group Formation failed with " MACSTR, 21148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt MAC2STR(p2p->go_neg_peer->intended_addr)); 21158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 21168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_clear_go_neg(p2p); 21178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 21188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 21198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 21208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstruct p2p_data * p2p_init(const struct p2p_config *cfg) 21218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 21228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct p2p_data *p2p; 21238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 21248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (cfg->max_peers < 1) 21258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return NULL; 21268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 21278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p = os_zalloc(sizeof(*p2p) + sizeof(*cfg)); 21288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (p2p == NULL) 21298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return NULL; 21308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p->cfg = (struct p2p_config *) (p2p + 1); 21318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memcpy(p2p->cfg, cfg, sizeof(*cfg)); 21328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (cfg->dev_name) 21338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p->cfg->dev_name = os_strdup(cfg->dev_name); 21348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (cfg->manufacturer) 21358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p->cfg->manufacturer = os_strdup(cfg->manufacturer); 21368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (cfg->model_name) 21378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p->cfg->model_name = os_strdup(cfg->model_name); 21388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (cfg->model_number) 21398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p->cfg->model_number = os_strdup(cfg->model_number); 21408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (cfg->serial_number) 21418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p->cfg->serial_number = os_strdup(cfg->serial_number); 21428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 21438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p->min_disc_int = 1; 21448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p->max_disc_int = 3; 21458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 21468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_get_random(&p2p->next_tie_breaker, 1); 21478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p->next_tie_breaker &= 0x01; 21488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (cfg->sd_request) 21498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p->dev_capab |= P2P_DEV_CAPAB_SERVICE_DISCOVERY; 21508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p->dev_capab |= P2P_DEV_CAPAB_INVITATION_PROCEDURE; 21518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (cfg->concurrent_operations) 21528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p->dev_capab |= P2P_DEV_CAPAB_CONCURRENT_OPER; 21538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p->dev_capab |= P2P_DEV_CAPAB_CLIENT_DISCOVERABILITY; 21548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 21558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt dl_list_init(&p2p->devices); 21568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 21578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt eloop_register_timeout(P2P_PEER_EXPIRATION_INTERVAL, 0, 21588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_expiration_timeout, p2p, NULL); 21598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 21608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return p2p; 21618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 21628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 21638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 21648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtvoid p2p_deinit(struct p2p_data *p2p) 21658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 21668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt eloop_cancel_timeout(p2p_expiration_timeout, p2p, NULL); 21678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt eloop_cancel_timeout(p2p_ext_listen_timeout, p2p, NULL); 21688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt eloop_cancel_timeout(p2p_scan_timeout, p2p, NULL); 21698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_flush(p2p); 21708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_free_req_dev_types(p2p); 21718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_free(p2p->cfg->dev_name); 21728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_free(p2p->cfg->manufacturer); 21738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_free(p2p->cfg->model_name); 21748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_free(p2p->cfg->model_number); 21758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_free(p2p->cfg->serial_number); 21768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_free(p2p->groups); 21778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpabuf_free(p2p->sd_resp); 21788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_free(p2p->after_scan_tx); 21798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_remove_wps_vendor_extensions(p2p); 21808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_free(p2p); 21818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 21828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 21838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 21848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtvoid p2p_flush(struct p2p_data *p2p) 21858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 21868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct p2p_device *dev, *prev; 21878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_clear_timeout(p2p); 21888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_set_state(p2p, P2P_IDLE); 21898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p->start_after_scan = P2P_AFTER_SCAN_NOTHING; 21908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p->go_neg_peer = NULL; 21918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt eloop_cancel_timeout(p2p_find_timeout, p2p, NULL); 21928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt dl_list_for_each_safe(dev, prev, &p2p->devices, struct p2p_device, 21938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt list) { 21948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt dl_list_del(&dev->list); 21958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_device_free(p2p, dev); 21968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 21978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_free_sd_queries(p2p); 21988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_free(p2p->after_scan_tx); 21998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p->after_scan_tx = NULL; 22008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 22018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 22028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 22038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtint p2p_unauthorize(struct p2p_data *p2p, const u8 *addr) 22048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 22058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct p2p_device *dev; 22068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 22078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt dev = p2p_get_device(p2p, addr); 22088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (dev == NULL) 22098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 22108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 22118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG, "P2P: Unauthorizing " MACSTR, 22128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt MAC2STR(addr)); 22138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 22148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (p2p->go_neg_peer == dev) 22158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p->go_neg_peer = NULL; 22168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 22178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt dev->wps_method = WPS_NOT_READY; 22188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt dev->flags &= ~P2P_DEV_WAIT_GO_NEG_RESPONSE; 22198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt dev->flags &= ~P2P_DEV_WAIT_GO_NEG_CONFIRM; 22208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 22218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* Check if after_scan_tx is for this peer. If so free it */ 22228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (p2p->after_scan_tx && 22238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memcmp(addr, p2p->after_scan_tx->dst, ETH_ALEN) == 0) { 22248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_free(p2p->after_scan_tx); 22258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p->after_scan_tx = NULL; 22268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 22278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 22288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 22298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 22308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 22318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 22328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtint p2p_set_dev_name(struct p2p_data *p2p, const char *dev_name) 22338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 22348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_free(p2p->cfg->dev_name); 22358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (dev_name) { 22368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p->cfg->dev_name = os_strdup(dev_name); 22378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (p2p->cfg->dev_name == NULL) 22388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 22398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } else 22408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p->cfg->dev_name = NULL; 22418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 22428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 22438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 22448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 22458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtint p2p_set_manufacturer(struct p2p_data *p2p, const char *manufacturer) 22468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 22478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_free(p2p->cfg->manufacturer); 22488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p->cfg->manufacturer = NULL; 22498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (manufacturer) { 22508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p->cfg->manufacturer = os_strdup(manufacturer); 22518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (p2p->cfg->manufacturer == NULL) 22528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 22538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 22548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 22558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 22568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 22578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 22588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 22598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtint p2p_set_model_name(struct p2p_data *p2p, const char *model_name) 22608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 22618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_free(p2p->cfg->model_name); 22628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p->cfg->model_name = NULL; 22638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (model_name) { 22648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p->cfg->model_name = os_strdup(model_name); 22658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (p2p->cfg->model_name == NULL) 22668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 22678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 22688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 22698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 22708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 22718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 22728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 22738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtint p2p_set_model_number(struct p2p_data *p2p, const char *model_number) 22748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 22758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_free(p2p->cfg->model_number); 22768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p->cfg->model_number = NULL; 22778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (model_number) { 22788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p->cfg->model_number = os_strdup(model_number); 22798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (p2p->cfg->model_number == NULL) 22808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 22818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 22828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 22838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 22848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 22858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 22868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 22878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtint p2p_set_serial_number(struct p2p_data *p2p, const char *serial_number) 22888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 22898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_free(p2p->cfg->serial_number); 22908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p->cfg->serial_number = NULL; 22918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (serial_number) { 22928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p->cfg->serial_number = os_strdup(serial_number); 22938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (p2p->cfg->serial_number == NULL) 22948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 22958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 22968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 22978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 22988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 22998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 23008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 23018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtvoid p2p_set_config_methods(struct p2p_data *p2p, u16 config_methods) 23028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 23038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p->cfg->config_methods = config_methods; 23048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 23058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 23068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 23078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtvoid p2p_set_uuid(struct p2p_data *p2p, const u8 *uuid) 23088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 23098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memcpy(p2p->cfg->uuid, uuid, 16); 23108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 23118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 23128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 23138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtint p2p_set_pri_dev_type(struct p2p_data *p2p, const u8 *pri_dev_type) 23148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 23158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memcpy(p2p->cfg->pri_dev_type, pri_dev_type, 8); 23168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 23178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 23188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 23198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 23208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtint p2p_set_sec_dev_types(struct p2p_data *p2p, const u8 dev_types[][8], 23218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt size_t num_dev_types) 23228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 23238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (num_dev_types > P2P_SEC_DEVICE_TYPES) 23248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt num_dev_types = P2P_SEC_DEVICE_TYPES; 23258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p->cfg->num_sec_dev_types = num_dev_types; 23268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memcpy(p2p->cfg->sec_dev_type, dev_types, num_dev_types * 8); 23278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 23288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 23298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 23308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 23318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtvoid p2p_remove_wps_vendor_extensions(struct p2p_data *p2p) 23328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 23338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt int i; 23348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 23358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt for (i = 0; i < P2P_MAX_WPS_VENDOR_EXT; i++) { 23368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpabuf_free(p2p->wps_vendor_ext[i]); 23378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p->wps_vendor_ext[i] = NULL; 23388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 23398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 23408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 23418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 23428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtint p2p_add_wps_vendor_extension(struct p2p_data *p2p, 23438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt const struct wpabuf *vendor_ext) 23448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 23458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt int i; 23468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 23478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (vendor_ext == NULL) 23488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 23498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 23508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt for (i = 0; i < P2P_MAX_WPS_VENDOR_EXT; i++) { 23518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (p2p->wps_vendor_ext[i] == NULL) 23528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 23538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 23548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (i >= P2P_MAX_WPS_VENDOR_EXT) 23558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 23568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 23578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p->wps_vendor_ext[i] = wpabuf_dup(vendor_ext); 23588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (p2p->wps_vendor_ext[i] == NULL) 23598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 23608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 23618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 23628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 23638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 23648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 23658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtint p2p_set_country(struct p2p_data *p2p, const char *country) 23668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 23678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memcpy(p2p->cfg->country, country, 3); 23688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 23698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 23708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 23718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 23728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtvoid p2p_continue_find(struct p2p_data *p2p) 23738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 23748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct p2p_device *dev; 23758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_set_state(p2p, P2P_SEARCH); 23768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt dl_list_for_each(dev, &p2p->devices, struct p2p_device, list) { 23778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (dev->flags & P2P_DEV_SD_SCHEDULE) { 23788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (p2p_start_sd(p2p, dev) == 0) 23798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; 23808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt else 23818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 23828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } else if (dev->req_config_methods && 23838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt !(dev->flags & P2P_DEV_PD_FOR_JOIN)) { 23848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG, "P2P: Send " 23851f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt "pending Provision Discovery Request to " 23868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt MACSTR " (config methods 0x%x)", 23878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt MAC2STR(dev->info.p2p_device_addr), 23888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt dev->req_config_methods); 23891f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt if (p2p_send_prov_disc_req(p2p, dev, 0, 0) == 0) 23908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; 23918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 23928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 23938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 23948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_listen_in_find(p2p); 23958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 23968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 23978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 23988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic void p2p_sd_cb(struct p2p_data *p2p, int success) 23998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 24008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG, 24018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "P2P: Service Discovery Query TX callback: success=%d", 24028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt success); 24038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p->pending_action_state = P2P_NO_PENDING_ACTION; 24048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 24058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (!success) { 24068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (p2p->sd_peer) { 24078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p->sd_peer->flags &= ~P2P_DEV_SD_SCHEDULE; 24088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p->sd_peer = NULL; 24098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 24108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_continue_find(p2p); 24118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; 24128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 24138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 24148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (p2p->sd_peer == NULL) { 24158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG, 24168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "P2P: No SD peer entry known"); 24178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_continue_find(p2p); 24188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; 24198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 24208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 24218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* Wait for response from the peer */ 24228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_set_state(p2p, P2P_SD_DURING_FIND); 24238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_set_timeout(p2p, 0, 200000); 24248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 24258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 242675ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen 242775ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen/** 242875ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen * p2p_retry_pd - Retry any pending provision disc requests in IDLE state 242975ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen * @p2p: P2P module context from p2p_init() 243075ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen */ 24311f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidtstatic void p2p_retry_pd(struct p2p_data *p2p) 243275ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen{ 243375ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen struct p2p_device *dev; 243475ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen 243575ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen if (p2p->state != P2P_IDLE) 243675ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen return; 243775ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen 243875ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen /* 243975ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen * Retry the prov disc req attempt only for the peer that the user had 244075ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen * requested for and provided a join has not been initiated on it 244175ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen * in the meantime. 244275ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen */ 244375ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen 244475ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen dl_list_for_each(dev, &p2p->devices, struct p2p_device, list) { 244575ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen if (os_memcmp(p2p->pending_pd_devaddr, 244675ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen dev->info.p2p_device_addr, ETH_ALEN) != 0) 244775ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen continue; 244875ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen if (!dev->req_config_methods) 244975ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen continue; 245075ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen if (dev->flags & P2P_DEV_PD_FOR_JOIN) 245175ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen continue; 245275ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen 245375ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG, "P2P: Send " 24541f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt "pending Provision Discovery Request to " 245575ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen MACSTR " (config methods 0x%x)", 245675ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen MAC2STR(dev->info.p2p_device_addr), 245775ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen dev->req_config_methods); 24581f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt p2p_send_prov_disc_req(p2p, dev, 0, 0); 245975ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen return; 246075ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen } 246175ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen} 246275ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen 246375ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen 24648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic void p2p_prov_disc_cb(struct p2p_data *p2p, int success) 24658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 24668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG, 24678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "P2P: Provision Discovery Request TX callback: success=%d", 24688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt success); 246975ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen 247075ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen /* 247175ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen * Postpone resetting the pending action state till after we actually 247275ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen * time out. This allows us to take some action like notifying any 247375ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen * interested parties about no response to the request. 247475ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen * 247575ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen * When the timer (below) goes off we check in IDLE, SEARCH, or 247675ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen * LISTEN_ONLY state, which are the only allowed states to issue a PD 247775ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen * requests in, if this was still pending and then raise notification. 247875ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen */ 24798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 24808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (!success) { 248175ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen p2p->pending_action_state = P2P_NO_PENDING_ACTION; 248275ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen 24838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (p2p->state != P2P_IDLE) 24848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_continue_find(p2p); 248575ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen else if (p2p->user_initiated_pd) { 248675ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen p2p->pending_action_state = P2P_PENDING_PD; 248775ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen p2p_set_timeout(p2p, 0, 300000); 248875ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen } 24898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; 24908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 24918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 249275ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen /* 249375ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen * This postponing, of resetting pending_action_state, needs to be 249475ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen * done only for user initiated PD requests and not internal ones. 249575ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen */ 249675ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen if (p2p->user_initiated_pd) 249775ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen p2p->pending_action_state = P2P_PENDING_PD; 249875ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen else 249975ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen p2p->pending_action_state = P2P_NO_PENDING_ACTION; 250075ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen 25018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* Wait for response from the peer */ 25028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (p2p->state == P2P_SEARCH) 25038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_set_state(p2p, P2P_PD_DURING_FIND); 25048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_set_timeout(p2p, 0, 200000); 25058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 25068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 25078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 25088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtint p2p_scan_res_handler(struct p2p_data *p2p, const u8 *bssid, int freq, 25098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt int level, const u8 *ies, size_t ies_len) 25108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 25118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_add_device(p2p, bssid, freq, level, ies, ies_len); 25128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 25138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (p2p->go_neg_peer && p2p->state == P2P_SEARCH && 25148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memcmp(p2p->go_neg_peer->info.p2p_device_addr, bssid, ETH_ALEN) 25158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt == 0) { 25168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG, 25178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "P2P: Found GO Negotiation peer - try to start GO " 25188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "negotiation"); 25198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_connect_send(p2p, p2p->go_neg_peer); 25208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 1; 25218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 25228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 25238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 25248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 25258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 25268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 25278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtvoid p2p_scan_res_handled(struct p2p_data *p2p) 25288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 25298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (!p2p->p2p_scan_running) { 25308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG, "P2P: p2p_scan was not " 25318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "running, but scan results received"); 25328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 25338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p->p2p_scan_running = 0; 25348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt eloop_cancel_timeout(p2p_scan_timeout, p2p, NULL); 25358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 25368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (p2p_run_after_scan(p2p)) 25378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; 25388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (p2p->state == P2P_SEARCH) 25398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_continue_find(p2p); 25408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 25418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 25428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 25438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtvoid p2p_scan_ie(struct p2p_data *p2p, struct wpabuf *ies) 25448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 25458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt u8 *len = p2p_buf_add_ie_hdr(ies); 25468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_buf_add_capability(ies, p2p->dev_capab, 0); 25478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (p2p->cfg->reg_class && p2p->cfg->channel) 25488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_buf_add_listen_channel(ies, p2p->cfg->country, 25498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p->cfg->reg_class, 25508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p->cfg->channel); 25518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (p2p->ext_listen_interval) 25528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_buf_add_ext_listen_timing(ies, p2p->ext_listen_period, 25538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p->ext_listen_interval); 25548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* TODO: p2p_buf_add_operating_channel() if GO */ 25558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_buf_update_ie_hdr(ies, len); 25568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 25578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 25588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 25591f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidtsize_t p2p_scan_ie_buf_len(struct p2p_data *p2p) 25601f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt{ 25611f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt return 100; 25621f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt} 25631f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt 25641f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt 25658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtint p2p_ie_text(struct wpabuf *p2p_ie, char *buf, char *end) 25668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 25678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return p2p_attr_text(p2p_ie, buf, end); 25688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 25698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 25708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 25718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic void p2p_go_neg_req_cb(struct p2p_data *p2p, int success) 25728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 25738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct p2p_device *dev = p2p->go_neg_peer; 25748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 25758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG, 25768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "P2P: GO Negotiation Request TX callback: success=%d", 25778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt success); 25788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 25798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (dev == NULL) { 25808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG, 25818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "P2P: No pending GO Negotiation"); 25828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; 25838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 25848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 25858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (success) { 25868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt dev->go_neg_req_sent++; 25878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (dev->flags & P2P_DEV_USER_REJECTED) { 25888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_set_state(p2p, P2P_IDLE); 25898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; 25908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 25918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 25928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 25938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (!success && 25948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt (dev->info.dev_capab & P2P_DEV_CAPAB_CLIENT_DISCOVERABILITY) && 25958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt !is_zero_ether_addr(dev->member_in_go_dev)) { 25968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG, 25978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "P2P: Peer " MACSTR " did not acknowledge request - " 25988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "try to use device discoverability through its GO", 25998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt MAC2STR(dev->info.p2p_device_addr)); 26008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p->cfg->send_action_done(p2p->cfg->cb_ctx); 26018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_send_dev_disc_req(p2p, dev); 26028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; 26038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 26048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 26058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* 26068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * Use P2P find, if needed, to find the other device from its listen 26078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * channel. 26088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */ 26098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_set_state(p2p, P2P_CONNECT); 26108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_set_timeout(p2p, 0, 100000); 26118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 26128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 26138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 26148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic void p2p_go_neg_resp_cb(struct p2p_data *p2p, int success) 26158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 26168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG, 26178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "P2P: GO Negotiation Response TX callback: success=%d", 26188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt success); 26198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (!p2p->go_neg_peer && p2p->state == P2P_PROVISIONING) { 26208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG, 26218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "P2P: Ignore TX callback event - GO Negotiation is " 26228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "not running anymore"); 26238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; 26248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 26258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_set_state(p2p, P2P_CONNECT); 26268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_set_timeout(p2p, 0, 100000); 26278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 26288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 26298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 26308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic void p2p_go_neg_resp_failure_cb(struct p2p_data *p2p, int success) 26318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 26328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG, 26338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "P2P: GO Negotiation Response (failure) TX callback: " 26348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "success=%d", success); 26358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (p2p->go_neg_peer && p2p->go_neg_peer->status != P2P_SC_SUCCESS) { 26368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_go_neg_failed(p2p, p2p->go_neg_peer, 26378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p->go_neg_peer->status); 26388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 26398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 26408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 26418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 26428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic void p2p_go_neg_conf_cb(struct p2p_data *p2p, 26438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt enum p2p_send_action_result result) 26448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 26458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct p2p_device *dev; 26468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 26478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG, 26488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "P2P: GO Negotiation Confirm TX callback: result=%d", 26498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt result); 26508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p->cfg->send_action_done(p2p->cfg->cb_ctx); 26518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (result == P2P_SEND_ACTION_FAILED) { 26528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_go_neg_failed(p2p, p2p->go_neg_peer, -1); 26538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; 26548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 26558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (result == P2P_SEND_ACTION_NO_ACK) { 26568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* 26578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * It looks like the TX status for GO Negotiation Confirm is 26588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * often showing failure even when the peer has actually 26598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * received the frame. Since the peer may change channels 26608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * immediately after having received the frame, we may not see 26618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * an Ack for retries, so just dropping a single frame may 26628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * trigger this. To allow the group formation to succeed if the 26638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * peer did indeed receive the frame, continue regardless of 26648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * the TX status. 26658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */ 26668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG, 26678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "P2P: Assume GO Negotiation Confirm TX was actually " 26688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "received by the peer even though Ack was not " 26698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "reported"); 26708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 26718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 26728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt dev = p2p->go_neg_peer; 26738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (dev == NULL) 26748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; 26758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 26768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_go_complete(p2p, dev); 26778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 26788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 26798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 26808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtvoid p2p_send_action_cb(struct p2p_data *p2p, unsigned int freq, const u8 *dst, 26818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt const u8 *src, const u8 *bssid, 26828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt enum p2p_send_action_result result) 26838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 26848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt enum p2p_pending_action_state state; 26858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt int success; 26868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 26878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG, 26888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "P2P: Action frame TX callback (state=%d freq=%u dst=" MACSTR 26898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt " src=" MACSTR " bssid=" MACSTR " result=%d", 26908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p->pending_action_state, freq, MAC2STR(dst), MAC2STR(src), 26918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt MAC2STR(bssid), result); 26928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt success = result == P2P_SEND_ACTION_SUCCESS; 26938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt state = p2p->pending_action_state; 26948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p->pending_action_state = P2P_NO_PENDING_ACTION; 26958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt switch (state) { 26968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case P2P_NO_PENDING_ACTION: 26978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 26988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case P2P_PENDING_GO_NEG_REQUEST: 26998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_go_neg_req_cb(p2p, success); 27008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 27018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case P2P_PENDING_GO_NEG_RESPONSE: 27028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_go_neg_resp_cb(p2p, success); 27038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 27048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case P2P_PENDING_GO_NEG_RESPONSE_FAILURE: 27058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_go_neg_resp_failure_cb(p2p, success); 27068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 27078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case P2P_PENDING_GO_NEG_CONFIRM: 27088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_go_neg_conf_cb(p2p, result); 27098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 27108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case P2P_PENDING_SD: 27118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_sd_cb(p2p, success); 27128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 27138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case P2P_PENDING_PD: 27148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_prov_disc_cb(p2p, success); 27158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 27168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case P2P_PENDING_INVITATION_REQUEST: 27178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_invitation_req_cb(p2p, success); 27188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 27198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case P2P_PENDING_INVITATION_RESPONSE: 27208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_invitation_resp_cb(p2p, success); 27218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 27228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case P2P_PENDING_DEV_DISC_REQUEST: 27238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_dev_disc_req_cb(p2p, success); 27248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 27258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case P2P_PENDING_DEV_DISC_RESPONSE: 27268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_dev_disc_resp_cb(p2p, success); 27278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 27288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case P2P_PENDING_GO_DISC_REQ: 27298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_go_disc_req_cb(p2p, success); 27308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 27318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 27328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 27338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 27348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 27358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtvoid p2p_listen_cb(struct p2p_data *p2p, unsigned int freq, 27368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt unsigned int duration) 27378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 27388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (freq == p2p->pending_client_disc_freq) { 27398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG, 27408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "P2P: Client discoverability remain-awake completed"); 27418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p->pending_client_disc_freq = 0; 27428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; 27438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 27448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 27458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (freq != p2p->pending_listen_freq) { 27468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG, 27478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "P2P: Unexpected listen callback for freq=%u " 27488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "duration=%u (pending_listen_freq=%u)", 27498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt freq, duration, p2p->pending_listen_freq); 27508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; 27518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 27528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 27538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG, 27548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "P2P: Starting Listen timeout(%u,%u) on freq=%u based on " 27558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "callback", 27568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p->pending_listen_sec, p2p->pending_listen_usec, 27578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p->pending_listen_freq); 27588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p->in_listen = 1; 27598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p->drv_in_listen = freq; 27608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (p2p->pending_listen_sec || p2p->pending_listen_usec) { 27618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* 27628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * Add 20 msec extra wait to avoid race condition with driver 27638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * remain-on-channel end event, i.e., give driver more time to 27648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * complete the operation before our timeout expires. 27658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */ 27668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_set_timeout(p2p, p2p->pending_listen_sec, 27678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p->pending_listen_usec + 20000); 27688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 27698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 27708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p->pending_listen_freq = 0; 27718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 27728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 27738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 27748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtint p2p_listen_end(struct p2p_data *p2p, unsigned int freq) 27758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 27768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG, "P2P: Driver ended Listen " 27778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "state (freq=%u)", freq); 27788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p->drv_in_listen = 0; 27798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (p2p->in_listen) 27808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; /* Internal timeout will trigger the next step */ 27818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 27828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (p2p->state == P2P_CONNECT_LISTEN && p2p->go_neg_peer) { 27838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (p2p->go_neg_peer->connect_reqs >= 120) { 27848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG, 27858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "P2P: Timeout on sending GO Negotiation " 27868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "Request without getting response"); 27878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_go_neg_failed(p2p, p2p->go_neg_peer, -1); 27888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 27898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 27908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 27918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_set_state(p2p, P2P_CONNECT); 27928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_connect_send(p2p, p2p->go_neg_peer); 27938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 1; 27948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } else if (p2p->state == P2P_SEARCH) { 27958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_search(p2p); 27968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 1; 27978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 27988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 27998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 28008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 28018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 28028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 28038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic void p2p_timeout_connect(struct p2p_data *p2p) 28048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 28058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p->cfg->send_action_done(p2p->cfg->cb_ctx); 28068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_set_state(p2p, P2P_CONNECT_LISTEN); 28078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_listen_in_find(p2p); 28088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 28098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 28108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 28118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic void p2p_timeout_connect_listen(struct p2p_data *p2p) 28128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 28138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (p2p->go_neg_peer) { 28148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (p2p->drv_in_listen) { 28158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG, "P2P: Driver is " 28168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "still in Listen state; wait for it to " 28178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "complete"); 28188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; 28198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 28208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 28218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (p2p->go_neg_peer->connect_reqs >= 120) { 28228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG, 28238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "P2P: Timeout on sending GO Negotiation " 28248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "Request without getting response"); 28258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_go_neg_failed(p2p, p2p->go_neg_peer, -1); 28268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; 28278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 28288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 28298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_set_state(p2p, P2P_CONNECT); 28308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_connect_send(p2p, p2p->go_neg_peer); 28318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } else 28328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_set_state(p2p, P2P_IDLE); 28338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 28348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 28358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 28368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic void p2p_timeout_wait_peer_connect(struct p2p_data *p2p) 28378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 28388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* 28398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * TODO: could remain constantly in Listen state for some time if there 28408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * are no other concurrent uses for the radio. For now, go to listen 28418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * state once per second to give other uses a chance to use the radio. 28428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */ 28438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_set_state(p2p, P2P_WAIT_PEER_IDLE); 28441f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt p2p_set_timeout(p2p, 0, 500000); 28458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 28468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 28478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 28488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic void p2p_timeout_wait_peer_idle(struct p2p_data *p2p) 28498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 28508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct p2p_device *dev = p2p->go_neg_peer; 28518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 28528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (dev == NULL) { 28538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG, 28548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "P2P: Unknown GO Neg peer - stop GO Neg wait"); 28558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; 28568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 28578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 28588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt dev->wait_count++; 28598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (dev->wait_count >= 120) { 28608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG, 28618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "P2P: Timeout on waiting peer to become ready for GO " 28628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "Negotiation"); 28638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_go_neg_failed(p2p, dev, -1); 28648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; 28658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 28668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 28678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG, 28688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "P2P: Go to Listen state while waiting for the peer to become " 28698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "ready for GO Negotiation"); 28708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_set_state(p2p, P2P_WAIT_PEER_CONNECT); 28718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_listen_in_find(p2p); 28728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 28738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 28748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 28758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic void p2p_timeout_sd_during_find(struct p2p_data *p2p) 28768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 28778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG, 28788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "P2P: Service Discovery Query timeout"); 28798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (p2p->sd_peer) { 28808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p->cfg->send_action_done(p2p->cfg->cb_ctx); 28818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p->sd_peer->flags &= ~P2P_DEV_SD_SCHEDULE; 28828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p->sd_peer = NULL; 28838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 28848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_continue_find(p2p); 28858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 28868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 28878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 28888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic void p2p_timeout_prov_disc_during_find(struct p2p_data *p2p) 28898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 28908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG, 28918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "P2P: Provision Discovery Request timeout"); 28928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p->cfg->send_action_done(p2p->cfg->cb_ctx); 28938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_continue_find(p2p); 28948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 28958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 28968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 289775ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinenstatic void p2p_timeout_prov_disc_req(struct p2p_data *p2p) 289875ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen{ 289975ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen p2p->pending_action_state = P2P_NO_PENDING_ACTION; 290075ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen 290175ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen /* 290275ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen * For user initiated PD requests that we have not gotten any responses 290375ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen * for while in IDLE state, we retry them a couple of times before 290475ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen * giving up. 290575ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen */ 290675ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen if (!p2p->user_initiated_pd) 290775ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen return; 290875ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen 290975ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG, 291075ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen "P2P: User initiated Provision Discovery Request timeout"); 291175ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen 291275ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen if (p2p->pd_retries) { 291375ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen p2p->pd_retries--; 291475ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen p2p_retry_pd(p2p); 291575ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen } else { 291675ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen if (p2p->cfg->prov_disc_fail) 291775ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen p2p->cfg->prov_disc_fail(p2p->cfg->cb_ctx, 291875ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen p2p->pending_pd_devaddr, 291975ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen P2P_PROV_DISC_TIMEOUT); 292075ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen p2p_reset_pending_pd(p2p); 292175ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen } 292275ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen} 292375ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen 292475ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen 29258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic void p2p_timeout_invite(struct p2p_data *p2p) 29268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 29278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p->cfg->send_action_done(p2p->cfg->cb_ctx); 29288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_set_state(p2p, P2P_INVITE_LISTEN); 29298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (p2p->inv_role == P2P_INVITE_ROLE_ACTIVE_GO) { 29308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* 29318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * Better remain on operating channel instead of listen channel 29328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * when running a group. 29338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */ 29348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG, "P2P: Inviting in " 29358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "active GO role - wait on operating channel"); 29368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_set_timeout(p2p, 0, 100000); 29378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; 29388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 29398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_listen_in_find(p2p); 29408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 29418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 29428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 29438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic void p2p_timeout_invite_listen(struct p2p_data *p2p) 29448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 29458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (p2p->invite_peer && p2p->invite_peer->invitation_reqs < 100) { 29468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_set_state(p2p, P2P_INVITE); 29478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_invite_send(p2p, p2p->invite_peer, 29488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p->invite_go_dev_addr); 29498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } else { 29508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (p2p->invite_peer) { 29518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG, 29528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "P2P: Invitation Request retry limit reached"); 29538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (p2p->cfg->invitation_result) 29548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p->cfg->invitation_result( 29558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p->cfg->cb_ctx, -1, NULL); 29568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 29578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_set_state(p2p, P2P_IDLE); 29588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 29598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 29608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 29618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 29628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic void p2p_state_timeout(void *eloop_ctx, void *timeout_ctx) 29638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 29648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct p2p_data *p2p = eloop_ctx; 29658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 29668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG, "P2P: Timeout (state=%s)", 29678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_state_txt(p2p->state)); 29688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 29698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p->in_listen = 0; 29708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 29718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt switch (p2p->state) { 29728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case P2P_IDLE: 297375ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen /* Check if we timed out waiting for PD req */ 297475ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen if (p2p->pending_action_state == P2P_PENDING_PD) 297575ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen p2p_timeout_prov_disc_req(p2p); 29768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 29778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case P2P_SEARCH: 297875ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen /* Check if we timed out waiting for PD req */ 297975ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen if (p2p->pending_action_state == P2P_PENDING_PD) 298075ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen p2p_timeout_prov_disc_req(p2p); 29818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_search(p2p); 29828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 29838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case P2P_CONNECT: 29848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_timeout_connect(p2p); 29858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 29868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case P2P_CONNECT_LISTEN: 29878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_timeout_connect_listen(p2p); 29888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 29898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case P2P_GO_NEG: 29908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 29918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case P2P_LISTEN_ONLY: 299275ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen /* Check if we timed out waiting for PD req */ 299375ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen if (p2p->pending_action_state == P2P_PENDING_PD) 299475ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen p2p_timeout_prov_disc_req(p2p); 299575ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen 29968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (p2p->ext_listen_only) { 29978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG, 29988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "P2P: Extended Listen Timing - Listen State " 29998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "completed"); 30008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p->ext_listen_only = 0; 30018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_set_state(p2p, P2P_IDLE); 30028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 30038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 30048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case P2P_WAIT_PEER_CONNECT: 30058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_timeout_wait_peer_connect(p2p); 30068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 30078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case P2P_WAIT_PEER_IDLE: 30088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_timeout_wait_peer_idle(p2p); 30098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 30108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case P2P_SD_DURING_FIND: 30118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_timeout_sd_during_find(p2p); 30128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 30138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case P2P_PROVISIONING: 30148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 30158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case P2P_PD_DURING_FIND: 30168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_timeout_prov_disc_during_find(p2p); 30178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 30188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case P2P_INVITE: 30198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_timeout_invite(p2p); 30208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 30218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case P2P_INVITE_LISTEN: 30228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_timeout_invite_listen(p2p); 30238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 30241f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt case P2P_SEARCH_WHEN_READY: 30251f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt break; 30268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 30278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 30288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 30298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 30308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtint p2p_reject(struct p2p_data *p2p, const u8 *peer_addr) 30318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 30328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct p2p_device *dev; 30338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 30348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt dev = p2p_get_device(p2p, peer_addr); 30358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG, "P2P: Local request to reject " 30368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "connection attempts by peer " MACSTR, MAC2STR(peer_addr)); 30378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (dev == NULL) { 30388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG, "P2P: Peer " MACSTR 30398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt " unknown", MAC2STR(peer_addr)); 30408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 30418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 30428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt dev->status = P2P_SC_FAIL_REJECTED_BY_USER; 30438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt dev->flags |= P2P_DEV_USER_REJECTED; 30448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 30458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 30468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 30478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 30481f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidtconst char * p2p_wps_method_text(enum p2p_wps_method method) 30498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 30508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt switch (method) { 30518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case WPS_NOT_READY: 30528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return "not-ready"; 30538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case WPS_PIN_DISPLAY: 30548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return "Display"; 30558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case WPS_PIN_KEYPAD: 30568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return "Keypad"; 30578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case WPS_PBC: 30588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return "PBC"; 30598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 30608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 30618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return "??"; 30628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 30638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 30648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 30658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic const char * p2p_go_state_text(enum p2p_go_state go_state) 30668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 30678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt switch (go_state) { 30688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case UNKNOWN_GO: 30698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return "unknown"; 30708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case LOCAL_GO: 30718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return "local"; 30728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case REMOTE_GO: 30738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return "remote"; 30748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 30758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 30768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return "??"; 30778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 30788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 30798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 30801f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidtconst struct p2p_peer_info * p2p_get_peer_info(struct p2p_data *p2p, 30811f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt const u8 *addr, int next) 30828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 30838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct p2p_device *dev; 30848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 30858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (addr) 30868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt dev = p2p_get_device(p2p, addr); 30878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt else 30888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt dev = dl_list_first(&p2p->devices, struct p2p_device, list); 30898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 30908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (dev && next) { 30918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt dev = dl_list_first(&dev->list, struct p2p_device, list); 30928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (&dev->list == &p2p->devices) 30938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt dev = NULL; 30948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 30958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 30968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (dev == NULL) 30971f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt return NULL; 30981f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt 30991f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt return &dev->info; 31001f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt} 31011f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt 31021f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt 31031f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidtint p2p_get_peer_info_txt(const struct p2p_peer_info *info, 31041f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt char *buf, size_t buflen) 31051f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt{ 31061f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt struct p2p_device *dev; 31071f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt int res; 31081f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt char *pos, *end; 31091f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt struct os_time now; 31101f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt 31111f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt if (info == NULL) 31128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 31138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 31141f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt dev = (struct p2p_device *) (((u8 *) info) - 31151f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt offsetof(struct p2p_device, info)); 31161f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt 31178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt pos = buf; 31188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt end = buf + buflen; 31198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 31208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_get_time(&now); 31218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt res = os_snprintf(pos, end - pos, 31228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "age=%d\n" 31238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "listen_freq=%d\n" 31248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "wps_method=%s\n" 31258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "interface_addr=" MACSTR "\n" 31268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "member_in_go_dev=" MACSTR "\n" 31278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "member_in_go_iface=" MACSTR "\n" 31288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "go_neg_req_sent=%d\n" 31298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "go_state=%s\n" 31308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "dialog_token=%u\n" 31318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "intended_addr=" MACSTR "\n" 31328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "country=%c%c\n" 31338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "oper_freq=%d\n" 31348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "req_config_methods=0x%x\n" 31358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "flags=%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s\n" 31368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "status=%d\n" 31378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "wait_count=%u\n" 31388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "invitation_reqs=%u\n", 31398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt (int) (now.sec - dev->last_seen.sec), 31408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt dev->listen_freq, 31418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_wps_method_text(dev->wps_method), 31428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt MAC2STR(dev->interface_addr), 31438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt MAC2STR(dev->member_in_go_dev), 31448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt MAC2STR(dev->member_in_go_iface), 31458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt dev->go_neg_req_sent, 31468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_go_state_text(dev->go_state), 31478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt dev->dialog_token, 31488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt MAC2STR(dev->intended_addr), 31498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt dev->country[0] ? dev->country[0] : '_', 31508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt dev->country[1] ? dev->country[1] : '_', 31518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt dev->oper_freq, 31528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt dev->req_config_methods, 31538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt dev->flags & P2P_DEV_PROBE_REQ_ONLY ? 31548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "[PROBE_REQ_ONLY]" : "", 31558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt dev->flags & P2P_DEV_REPORTED ? "[REPORTED]" : "", 31568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt dev->flags & P2P_DEV_NOT_YET_READY ? 31578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "[NOT_YET_READY]" : "", 31588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt dev->flags & P2P_DEV_SD_INFO ? "[SD_INFO]" : "", 31598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt dev->flags & P2P_DEV_SD_SCHEDULE ? "[SD_SCHEDULE]" : 31608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "", 31618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt dev->flags & P2P_DEV_PD_PEER_DISPLAY ? 31628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "[PD_PEER_DISPLAY]" : "", 31638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt dev->flags & P2P_DEV_PD_PEER_KEYPAD ? 31648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "[PD_PEER_KEYPAD]" : "", 31658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt dev->flags & P2P_DEV_USER_REJECTED ? 31668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "[USER_REJECTED]" : "", 31678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt dev->flags & P2P_DEV_PEER_WAITING_RESPONSE ? 31688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "[PEER_WAITING_RESPONSE]" : "", 31698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt dev->flags & P2P_DEV_PREFER_PERSISTENT_GROUP ? 31708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "[PREFER_PERSISTENT_GROUP]" : "", 31718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt dev->flags & P2P_DEV_WAIT_GO_NEG_RESPONSE ? 31728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "[WAIT_GO_NEG_RESPONSE]" : "", 31738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt dev->flags & P2P_DEV_WAIT_GO_NEG_CONFIRM ? 31748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "[WAIT_GO_NEG_CONFIRM]" : "", 31758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt dev->flags & P2P_DEV_GROUP_CLIENT_ONLY ? 31768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "[GROUP_CLIENT_ONLY]" : "", 31778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt dev->flags & P2P_DEV_FORCE_FREQ ? 31788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "[FORCE_FREQ]" : "", 31798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt dev->flags & P2P_DEV_PD_FOR_JOIN ? 31808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "[PD_FOR_JOIN]" : "", 31818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt dev->status, 31828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt dev->wait_count, 31838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt dev->invitation_reqs); 31848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (res < 0 || res >= end - pos) 31858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return pos - buf; 31868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt pos += res; 31878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 31888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (dev->ext_listen_period) { 31898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt res = os_snprintf(pos, end - pos, 31908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "ext_listen_period=%u\n" 31918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "ext_listen_interval=%u\n", 31928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt dev->ext_listen_period, 31938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt dev->ext_listen_interval); 31948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (res < 0 || res >= end - pos) 31958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return pos - buf; 31968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt pos += res; 31978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 31988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 31998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (dev->oper_ssid_len) { 32008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt res = os_snprintf(pos, end - pos, 32018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "oper_ssid=%s\n", 32028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_ssid_txt(dev->oper_ssid, 32038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt dev->oper_ssid_len)); 32048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (res < 0 || res >= end - pos) 32058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return pos - buf; 32068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt pos += res; 32078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 32088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 32098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return pos - buf; 32108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 32118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 32128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 32131f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidtint p2p_peer_known(struct p2p_data *p2p, const u8 *addr) 32141f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt{ 32151f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt return p2p_get_device(p2p, addr) != NULL; 32161f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt} 32171f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt 32181f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt 32198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtvoid p2p_set_client_discoverability(struct p2p_data *p2p, int enabled) 32208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 32218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (enabled) { 32228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG, "P2P: Client " 32238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "discoverability enabled"); 32248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p->dev_capab |= P2P_DEV_CAPAB_CLIENT_DISCOVERABILITY; 32258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } else { 32268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG, "P2P: Client " 32278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "discoverability disabled"); 32288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p->dev_capab &= ~P2P_DEV_CAPAB_CLIENT_DISCOVERABILITY; 32298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 32308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 32318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 32328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 32338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic struct wpabuf * p2p_build_presence_req(u32 duration1, u32 interval1, 32348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt u32 duration2, u32 interval2) 32358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 32368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct wpabuf *req; 32378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct p2p_noa_desc desc1, desc2, *ptr1 = NULL, *ptr2 = NULL; 32388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt u8 *len; 32398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 32408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt req = wpabuf_alloc(100); 32418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (req == NULL) 32428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return NULL; 32438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 32448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (duration1 || interval1) { 32458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memset(&desc1, 0, sizeof(desc1)); 32468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt desc1.count_type = 1; 32478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt desc1.duration = duration1; 32488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt desc1.interval = interval1; 32498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ptr1 = &desc1; 32508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 32518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (duration2 || interval2) { 32528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memset(&desc2, 0, sizeof(desc2)); 32538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt desc2.count_type = 2; 32548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt desc2.duration = duration2; 32558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt desc2.interval = interval2; 32568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ptr2 = &desc2; 32578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 32588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 32598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 32608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_buf_add_action_hdr(req, P2P_PRESENCE_REQ, 1); 32618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt len = p2p_buf_add_ie_hdr(req); 32628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_buf_add_noa(req, 0, 0, 0, ptr1, ptr2); 32638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_buf_update_ie_hdr(req, len); 32648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 32658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return req; 32668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 32678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 32688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 32698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtint p2p_presence_req(struct p2p_data *p2p, const u8 *go_interface_addr, 32708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt const u8 *own_interface_addr, unsigned int freq, 32718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt u32 duration1, u32 interval1, u32 duration2, 32728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt u32 interval2) 32738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 32748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct wpabuf *req; 32758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 32768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG, "P2P: Send Presence Request to " 32778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "GO " MACSTR " (own interface " MACSTR ") freq=%u dur1=%u " 32788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "int1=%u dur2=%u int2=%u", 32798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt MAC2STR(go_interface_addr), MAC2STR(own_interface_addr), 32808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt freq, duration1, interval1, duration2, interval2); 32818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 32828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt req = p2p_build_presence_req(duration1, interval1, duration2, 32838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt interval2); 32848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (req == NULL) 32858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 32868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 32878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p->pending_action_state = P2P_NO_PENDING_ACTION; 32888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (p2p_send_action(p2p, freq, go_interface_addr, own_interface_addr, 32898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt go_interface_addr, 32908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpabuf_head(req), wpabuf_len(req), 200) < 0) { 32918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG, 32928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "P2P: Failed to send Action frame"); 32938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 32948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpabuf_free(req); 32958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 32968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 32978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 32988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 32998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 33008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic struct wpabuf * p2p_build_presence_resp(u8 status, const u8 *noa, 33018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt size_t noa_len, u8 dialog_token) 33028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 33038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct wpabuf *resp; 33048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt u8 *len; 33058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 33068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt resp = wpabuf_alloc(100 + noa_len); 33078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (resp == NULL) 33088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return NULL; 33098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 33108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_buf_add_action_hdr(resp, P2P_PRESENCE_RESP, dialog_token); 33118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt len = p2p_buf_add_ie_hdr(resp); 33128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_buf_add_status(resp, status); 33138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (noa) { 33148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpabuf_put_u8(resp, P2P_ATTR_NOTICE_OF_ABSENCE); 33158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpabuf_put_le16(resp, noa_len); 33168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpabuf_put_data(resp, noa, noa_len); 33178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } else 33188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_buf_add_noa(resp, 0, 0, 0, NULL, NULL); 33198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_buf_update_ie_hdr(resp, len); 33208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 33218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return resp; 33228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 33238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 33248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 33258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic void p2p_process_presence_req(struct p2p_data *p2p, const u8 *da, 33268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt const u8 *sa, const u8 *data, size_t len, 33278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt int rx_freq) 33288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 33298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct p2p_message msg; 33308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt u8 status; 33318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct wpabuf *resp; 33328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt size_t g; 33338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct p2p_group *group = NULL; 33348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt int parsed = 0; 33358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt u8 noa[50]; 33368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt int noa_len; 33378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 33388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG, 33398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "P2P: Received P2P Action - P2P Presence Request"); 33408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 33418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt for (g = 0; g < p2p->num_groups; g++) { 33428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (os_memcmp(da, p2p_group_get_interface_addr(p2p->groups[g]), 33438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ETH_ALEN) == 0) { 33448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt group = p2p->groups[g]; 33458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 33468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 33478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 33488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (group == NULL) { 33498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG, 33508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "P2P: Ignore P2P Presence Request for unknown group " 33518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt MACSTR, MAC2STR(da)); 33528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; 33538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 33548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 33558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (p2p_parse(data, len, &msg) < 0) { 33568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG, 33578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "P2P: Failed to parse P2P Presence Request"); 33588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt status = P2P_SC_FAIL_INVALID_PARAMS; 33598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt goto fail; 33608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 33618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt parsed = 1; 33628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 33638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (msg.noa == NULL) { 33648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG, 33658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "P2P: No NoA attribute in P2P Presence Request"); 33668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt status = P2P_SC_FAIL_INVALID_PARAMS; 33678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt goto fail; 33688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 33698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 33708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt status = p2p_group_presence_req(group, sa, msg.noa, msg.noa_len); 33718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 33728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtfail: 33738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (p2p->cfg->get_noa) 33748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt noa_len = p2p->cfg->get_noa(p2p->cfg->cb_ctx, da, noa, 33758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sizeof(noa)); 33768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt else 33778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt noa_len = -1; 33788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt resp = p2p_build_presence_resp(status, noa_len > 0 ? noa : NULL, 33798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt noa_len > 0 ? noa_len : 0, 33808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt msg.dialog_token); 33818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (parsed) 33828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_parse_free(&msg); 33838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (resp == NULL) 33848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; 33858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 33868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p->pending_action_state = P2P_NO_PENDING_ACTION; 33878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (p2p_send_action(p2p, rx_freq, sa, da, da, 33888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpabuf_head(resp), wpabuf_len(resp), 200) < 0) { 33898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG, 33908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "P2P: Failed to send Action frame"); 33918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 33928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpabuf_free(resp); 33938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 33948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 33958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 33968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic void p2p_process_presence_resp(struct p2p_data *p2p, const u8 *da, 33978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt const u8 *sa, const u8 *data, size_t len) 33988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 33998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct p2p_message msg; 34008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 34018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG, 34028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "P2P: Received P2P Action - P2P Presence Response"); 34038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 34048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (p2p_parse(data, len, &msg) < 0) { 34058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG, 34068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "P2P: Failed to parse P2P Presence Response"); 34078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; 34088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 34098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 34108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (msg.status == NULL || msg.noa == NULL) { 34118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG, 34128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "P2P: No Status or NoA attribute in P2P Presence " 34138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "Response"); 34148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_parse_free(&msg); 34158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; 34168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 34178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 34188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (*msg.status) { 34198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG, 34208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "P2P: P2P Presence Request was rejected: status %u", 34218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt *msg.status); 34228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_parse_free(&msg); 34238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; 34248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 34258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 34268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG, 34278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "P2P: P2P Presence Request was accepted"); 34288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_hexdump(MSG_DEBUG, "P2P: P2P Presence Response - NoA", 34298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt msg.noa, msg.noa_len); 34308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* TODO: process NoA */ 34318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_parse_free(&msg); 34328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 34338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 34348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 34358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic void p2p_ext_listen_timeout(void *eloop_ctx, void *timeout_ctx) 34368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 34378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct p2p_data *p2p = eloop_ctx; 34388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 34398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (p2p->ext_listen_interval) { 34408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* Schedule next extended listen timeout */ 34418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt eloop_register_timeout(p2p->ext_listen_interval_sec, 34428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p->ext_listen_interval_usec, 34438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_ext_listen_timeout, p2p, NULL); 34448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 34458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 34468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (p2p->state == P2P_LISTEN_ONLY && p2p->ext_listen_only) { 34478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* 34488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * This should not really happen, but it looks like the Listen 34498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * command may fail is something else (e.g., a scan) was 34508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * running at an inconvenient time. As a workaround, allow new 34518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * Extended Listen operation to be started. 34528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */ 34538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG, "P2P: Previous " 34548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "Extended Listen operation had not been completed - " 34558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "try again"); 34568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p->ext_listen_only = 0; 34578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_set_state(p2p, P2P_IDLE); 34588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 34598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 34608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (p2p->state != P2P_IDLE) { 34618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG, "P2P: Skip Extended " 34628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "Listen timeout in active state (%s)", 34638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_state_txt(p2p->state)); 34648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; 34658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 34668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 34678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG, "P2P: Extended Listen timeout"); 34688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p->ext_listen_only = 1; 34698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (p2p_listen(p2p, p2p->ext_listen_period) < 0) { 34708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG, "P2P: Failed to start " 34718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "Listen state for Extended Listen Timing"); 34728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p->ext_listen_only = 0; 34738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 34748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 34758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 34768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 34778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtint p2p_ext_listen(struct p2p_data *p2p, unsigned int period, 34788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt unsigned int interval) 34798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 34808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (period > 65535 || interval > 65535 || period > interval || 34818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt (period == 0 && interval > 0) || (period > 0 && interval == 0)) { 34828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG, 34838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "P2P: Invalid Extended Listen Timing request: " 34848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "period=%u interval=%u", period, interval); 34858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 34868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 34878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 34888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt eloop_cancel_timeout(p2p_ext_listen_timeout, p2p, NULL); 34898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 34908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (interval == 0) { 34918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG, 34928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "P2P: Disabling Extended Listen Timing"); 34938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p->ext_listen_period = 0; 34948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p->ext_listen_interval = 0; 34958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 34968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 34978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 34988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG, 34998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "P2P: Enabling Extended Listen Timing: period %u msec, " 35008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "interval %u msec", period, interval); 35018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p->ext_listen_period = period; 35028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p->ext_listen_interval = interval; 35038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p->ext_listen_interval_sec = interval / 1000; 35048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p->ext_listen_interval_usec = (interval % 1000) * 1000; 35058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 35068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt eloop_register_timeout(p2p->ext_listen_interval_sec, 35078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p->ext_listen_interval_usec, 35088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_ext_listen_timeout, p2p, NULL); 35098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 35108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 35118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 35128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 35138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 35148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtvoid p2p_deauth_notif(struct p2p_data *p2p, const u8 *bssid, u16 reason_code, 35158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt const u8 *ie, size_t ie_len) 35168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 35178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct p2p_message msg; 35188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 35198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (bssid == NULL || ie == NULL) 35208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; 35218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 35228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memset(&msg, 0, sizeof(msg)); 35238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (p2p_parse_ies(ie, ie_len, &msg)) 35248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; 35258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (msg.minor_reason_code == NULL) 35268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; 35278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 35288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_msg(p2p->cfg->msg_ctx, MSG_INFO, 35298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "P2P: Deauthentication notification BSSID " MACSTR 35308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt " reason_code=%u minor_reason_code=%u", 35318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt MAC2STR(bssid), reason_code, *msg.minor_reason_code); 35328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 35338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_parse_free(&msg); 35348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 35358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 35368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 35378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtvoid p2p_disassoc_notif(struct p2p_data *p2p, const u8 *bssid, u16 reason_code, 35388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt const u8 *ie, size_t ie_len) 35398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 35408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct p2p_message msg; 35418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 35428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (bssid == NULL || ie == NULL) 35438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; 35448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 35458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memset(&msg, 0, sizeof(msg)); 35468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (p2p_parse_ies(ie, ie_len, &msg)) 35478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; 35488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (msg.minor_reason_code == NULL) 35498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; 35508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 35518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_msg(p2p->cfg->msg_ctx, MSG_INFO, 35528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "P2P: Disassociation notification BSSID " MACSTR 35538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt " reason_code=%u minor_reason_code=%u", 35548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt MAC2STR(bssid), reason_code, *msg.minor_reason_code); 35558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 35568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_parse_free(&msg); 35578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 35588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 35598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 35608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtvoid p2p_set_managed_oper(struct p2p_data *p2p, int enabled) 35618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 35628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (enabled) { 35638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG, "P2P: Managed P2P " 35648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "Device operations enabled"); 35658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p->dev_capab |= P2P_DEV_CAPAB_INFRA_MANAGED; 35668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } else { 35678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG, "P2P: Managed P2P " 35688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "Device operations disabled"); 35698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p->dev_capab &= ~P2P_DEV_CAPAB_INFRA_MANAGED; 35708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 35718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 35728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 35738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 35748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtint p2p_set_listen_channel(struct p2p_data *p2p, u8 reg_class, u8 channel) 35758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 35768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (p2p_channel_to_freq(p2p->cfg->country, reg_class, channel) < 0) 35778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 35788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 35798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG, "P2P: Set Listen channel: " 35808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "reg_class %u channel %u", reg_class, channel); 35818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p->cfg->reg_class = reg_class; 35828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p->cfg->channel = channel; 35838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 35848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 35858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 35868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 35878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 35888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtint p2p_set_ssid_postfix(struct p2p_data *p2p, const u8 *postfix, size_t len) 35898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 35908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_hexdump_ascii(MSG_DEBUG, "P2P: New SSID postfix", postfix, len); 35918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (postfix == NULL) { 35928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p->cfg->ssid_postfix_len = 0; 35938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 35948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 35958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (len > sizeof(p2p->cfg->ssid_postfix)) 35968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 35978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memcpy(p2p->cfg->ssid_postfix, postfix, len); 35988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p->cfg->ssid_postfix_len = len; 35998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 36008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 36018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 36028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 360375ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinenint p2p_set_oper_channel(struct p2p_data *p2p, u8 op_reg_class, u8 op_channel, 360475ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen int cfg_op_channel) 360575ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen{ 360675ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen if (p2p_channel_to_freq(p2p->cfg->country, op_reg_class, op_channel) 360775ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen < 0) 360875ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen return -1; 360975ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen 361075ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen wpa_msg(p2p->cfg->msg_ctx, MSG_INFO, "P2P: Set Operating channel: " 361175ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen "reg_class %u channel %u", op_reg_class, op_channel); 361275ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen p2p->cfg->op_reg_class = op_reg_class; 361375ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen p2p->cfg->op_channel = op_channel; 361475ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen p2p->cfg->cfg_op_channel = cfg_op_channel; 361575ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen return 0; 361675ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen} 361775ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen 361875ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen 36198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtint p2p_get_interface_addr(struct p2p_data *p2p, const u8 *dev_addr, 36208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt u8 *iface_addr) 36218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 36228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct p2p_device *dev = p2p_get_device(p2p, dev_addr); 36238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (dev == NULL || is_zero_ether_addr(dev->interface_addr)) 36248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 36258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memcpy(iface_addr, dev->interface_addr, ETH_ALEN); 36268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 36278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 36288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 36298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 36308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtint p2p_get_dev_addr(struct p2p_data *p2p, const u8 *iface_addr, 36318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt u8 *dev_addr) 36328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 36338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct p2p_device *dev = p2p_get_device_interface(p2p, iface_addr); 36348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (dev == NULL) 36358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 36368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memcpy(dev_addr, dev->info.p2p_device_addr, ETH_ALEN); 36378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 36388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 36398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 36408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 36418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtvoid p2p_set_peer_filter(struct p2p_data *p2p, const u8 *addr) 36428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 36438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memcpy(p2p->peer_filter, addr, ETH_ALEN); 36448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (is_zero_ether_addr(p2p->peer_filter)) 36458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG, "P2P: Disable peer " 36468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "filter"); 36478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt else 36488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG, "P2P: Enable peer " 36498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "filter for " MACSTR, MAC2STR(p2p->peer_filter)); 36508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 36518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 36528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 36538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtvoid p2p_set_cross_connect(struct p2p_data *p2p, int enabled) 36548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 36558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG, "P2P: Cross connection %s", 36568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt enabled ? "enabled" : "disabled"); 36578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (p2p->cross_connect == enabled) 36588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; 36598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p->cross_connect = enabled; 36608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* TODO: may need to tear down any action group where we are GO(?) */ 36618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 36628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 36638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 36648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtint p2p_get_oper_freq(struct p2p_data *p2p, const u8 *iface_addr) 36658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 36668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct p2p_device *dev = p2p_get_device_interface(p2p, iface_addr); 36678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (dev == NULL) 36688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 36698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (dev->oper_freq <= 0) 36708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 36718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return dev->oper_freq; 36728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 36738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 36748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 36758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtvoid p2p_set_intra_bss_dist(struct p2p_data *p2p, int enabled) 36768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 36778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG, "P2P: Intra BSS distribution %s", 36788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt enabled ? "enabled" : "disabled"); 36798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p->cfg->p2p_intra_bss = enabled; 36808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 36818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 36828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 36838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtvoid p2p_update_channel_list(struct p2p_data *p2p, struct p2p_channels *chan) 36848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 36858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG, "P2P: Update channel list"); 36868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memcpy(&p2p->cfg->channels, chan, sizeof(struct p2p_channels)); 36878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 36888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 36898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 36908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtint p2p_send_action(struct p2p_data *p2p, unsigned int freq, const u8 *dst, 36918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt const u8 *src, const u8 *bssid, const u8 *buf, 36928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt size_t len, unsigned int wait_time) 36938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 36948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (p2p->p2p_scan_running) { 36958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG, "P2P: Delay Action " 36968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "frame TX until p2p_scan completes"); 36978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (p2p->after_scan_tx) { 36988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG, "P2P: Dropped " 36998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "previous pending Action frame TX"); 37008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_free(p2p->after_scan_tx); 37018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 37028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p->after_scan_tx = os_malloc(sizeof(*p2p->after_scan_tx) + 37038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt len); 37048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (p2p->after_scan_tx == NULL) 37058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 37068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p->after_scan_tx->freq = freq; 37078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memcpy(p2p->after_scan_tx->dst, dst, ETH_ALEN); 37088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memcpy(p2p->after_scan_tx->src, src, ETH_ALEN); 37098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memcpy(p2p->after_scan_tx->bssid, bssid, ETH_ALEN); 37108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p->after_scan_tx->len = len; 37118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p->after_scan_tx->wait_time = wait_time; 37128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memcpy(p2p->after_scan_tx + 1, buf, len); 37138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 37148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 37158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 37168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return p2p->cfg->send_action(p2p->cfg->cb_ctx, freq, dst, src, bssid, 37178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt buf, len, wait_time); 37188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 37198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 37208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 37218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtvoid p2p_set_best_channels(struct p2p_data *p2p, int freq_24, int freq_5, 37228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt int freq_overall) 37238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 37248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG, "P2P: Best channel: 2.4 GHz: %d," 37258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt " 5 GHz: %d, overall: %d", freq_24, freq_5, freq_overall); 37268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p->best_freq_24 = freq_24; 37278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p->best_freq_5 = freq_5; 37288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p->best_freq_overall = freq_overall; 37298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 37308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 37318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 37328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtconst u8 * p2p_get_go_neg_peer(struct p2p_data *p2p) 37338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 37348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (p2p == NULL || p2p->go_neg_peer == NULL) 37358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return NULL; 37368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return p2p->go_neg_peer->info.p2p_device_addr; 37378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 37388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 37398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 37408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtconst struct p2p_peer_info * 37418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtp2p_get_peer_found(struct p2p_data *p2p, const u8 *addr, int next) 37428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 37438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct p2p_device *dev; 37448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 37458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (addr) { 37468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt dev = p2p_get_device(p2p, addr); 37478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (!dev) 37488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return NULL; 37498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 37508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (!next) { 37518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (dev->flags & P2P_DEV_PROBE_REQ_ONLY) 37528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return NULL; 37538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 37548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return &dev->info; 37558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } else { 37568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt do { 37578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt dev = dl_list_first(&dev->list, 37588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct p2p_device, 37598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt list); 37608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (&dev->list == &p2p->devices) 37618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return NULL; 37628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } while (dev->flags & P2P_DEV_PROBE_REQ_ONLY); 37638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 37648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } else { 37658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt dev = dl_list_first(&p2p->devices, struct p2p_device, list); 37668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (!dev) 37678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return NULL; 37688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt while (dev->flags & P2P_DEV_PROBE_REQ_ONLY) { 37698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt dev = dl_list_first(&dev->list, 37708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct p2p_device, 37718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt list); 37728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (&dev->list == &p2p->devices) 37738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return NULL; 37748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 37758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 37768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 37778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return &dev->info; 37788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 37791f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt 37801f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt#ifdef ANDROID_P2P 37811f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidtint p2p_search_in_progress(struct p2p_data *p2p) 37821f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt{ 37831f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt if (p2p == NULL) 37841f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt return 0; 37851f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt 37861f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt return p2p->state == P2P_SEARCH; 37871f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt} 37881f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt#endif 37891f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt 37901f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidtint p2p_in_progress(struct p2p_data *p2p) 37911f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt{ 37921f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt if (p2p == NULL) 37931f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt return 0; 37941f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt return p2p->state != P2P_IDLE && p2p->state != P2P_PROVISIONING; 37951f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt} 3796