p2p.c revision 97a1e7d55662fa4a41b05b9fbd2e9e03e153266a
1b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru/* 2b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * Wi-Fi Direct - P2P module 3b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * Copyright (c) 2009-2010, Atheros Communications 4b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * 5b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * This software may be distributed under the terms of the BSD license. 6b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru * See README for more details. 7b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru */ 8b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 9b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#include "includes.h" 10b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 11b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#include "common.h" 12b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#include "eloop.h" 13b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#include "common/ieee802_11_defs.h" 14b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#include "common/ieee802_11_common.h" 15b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#include "wps/wps_i.h" 16b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#include "p2p_i.h" 17b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#include "p2p.h" 18b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 19b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 20b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Querustatic void p2p_state_timeout(void *eloop_ctx, void *timeout_ctx); 21b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Querustatic void p2p_device_free(struct p2p_data *p2p, struct p2p_device *dev); 22b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Querustatic void p2p_process_presence_req(struct p2p_data *p2p, const u8 *da, 23b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru const u8 *sa, const u8 *data, size_t len, 24b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru int rx_freq); 25b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Querustatic void p2p_process_presence_resp(struct p2p_data *p2p, const u8 *da, 26b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru const u8 *sa, const u8 *data, 27b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru size_t len); 28b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Querustatic void p2p_ext_listen_timeout(void *eloop_ctx, void *timeout_ctx); 29b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Querustatic void p2p_scan_timeout(void *eloop_ctx, void *timeout_ctx); 30b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 31b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 32b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru/* 33b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * p2p_scan recovery timeout 34b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * 35b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * Many drivers are using 30 second timeout on scan results. Allow a bit larger 36b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * timeout for this to avoid hitting P2P timeout unnecessarily. 37b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru */ 38b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#define P2P_SCAN_TIMEOUT 35 39b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 40b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru/** 41b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * P2P_PEER_EXPIRATION_AGE - Number of seconds after which inactive peer 42b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * entries will be removed 43b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru */ 44b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#ifdef ANDROID_P2P 45b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#define P2P_PEER_EXPIRATION_AGE 30 46b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#else 47b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#define P2P_PEER_EXPIRATION_AGE 300 48b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#endif 49b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 50b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#define P2P_PEER_EXPIRATION_INTERVAL (P2P_PEER_EXPIRATION_AGE / 2) 51b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 52b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#ifdef ANDROID_P2P 53b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queruint p2p_connection_in_progress(struct p2p_data *p2p) 54b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru{ 55b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru int ret = 0; 56b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 57b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru switch (p2p->state) { 58b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru case P2P_CONNECT: 59b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru case P2P_CONNECT_LISTEN: 60b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru case P2P_GO_NEG: 61b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru case P2P_WAIT_PEER_CONNECT: 62b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru case P2P_WAIT_PEER_IDLE: 63b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru case P2P_PROVISIONING: 64b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru case P2P_INVITE: 65b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru case P2P_INVITE_LISTEN: 66b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru ret = 1; 67b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru break; 68b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 69b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru default: 70b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru wpa_printf(MSG_DEBUG, "p2p_connection_in_progress state %d", p2p->state); 71b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru ret = 0; 72b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 73b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 74b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return ret; 75b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru} 76b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#endif 77b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 78b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Querustatic void p2p_expire_peers(struct p2p_data *p2p) 79b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru{ 80b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru struct p2p_device *dev, *n; 81b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru struct os_reltime now; 82b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru size_t i; 83b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 84b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru os_get_reltime(&now); 85b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru dl_list_for_each_safe(dev, n, &p2p->devices, struct p2p_device, list) { 86b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (dev->last_seen.sec + P2P_PEER_EXPIRATION_AGE >= now.sec) 87b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru continue; 88b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 89b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (p2p->cfg->go_connected && 90b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru p2p->cfg->go_connected(p2p->cfg->cb_ctx, 91b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru dev->info.p2p_device_addr)) { 92b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru /* 93b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * We are connected as a client to a group in which the 94b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * peer is the GO, so do not expire the peer entry. 95b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru */ 96b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru os_get_reltime(&dev->last_seen); 97b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru continue; 98b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 99b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 100b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru for (i = 0; i < p2p->num_groups; i++) { 101b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (p2p_group_is_client_connected( 102b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru p2p->groups[i], dev->info.p2p_device_addr)) 103b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru break; 104b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 105b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (i < p2p->num_groups) { 106b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru /* 107b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * The peer is connected as a client in a group where 108b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * we are the GO, so do not expire the peer entry. 109b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru */ 110b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru os_get_reltime(&dev->last_seen); 111b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru continue; 112b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 113b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 114b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#ifdef ANDROID_P2P 115b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru /* If Connection is in progress, don't expire the peer 116b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru */ 117b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru if (p2p_connection_in_progress(p2p)) 118b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru continue; 119b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#endif 120b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 121b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru p2p_dbg(p2p, "Expiring old peer entry " MACSTR, 122b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru MAC2STR(dev->info.p2p_device_addr)); 123b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru dl_list_del(&dev->list); 124b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru p2p_device_free(p2p, dev); 125b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 126b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru} 127b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 128b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru 129b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Querustatic void p2p_expiration_timeout(void *eloop_ctx, void *timeout_ctx) 130b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru{ 131b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru struct p2p_data *p2p = eloop_ctx; 132b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru p2p_expire_peers(p2p); 133b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru eloop_register_timeout(P2P_PEER_EXPIRATION_INTERVAL, 0, 134b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru p2p_expiration_timeout, p2p, NULL); 135b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru} 136b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru 137b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru 138b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Querustatic const char * p2p_state_txt(int state) 139b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru{ 140b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru switch (state) { 141b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru case P2P_IDLE: 142b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru return "IDLE"; 143b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru case P2P_SEARCH: 144b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru return "SEARCH"; 145b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru case P2P_CONNECT: 146b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru return "CONNECT"; 147b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru case P2P_CONNECT_LISTEN: 148b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru return "CONNECT_LISTEN"; 149b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru case P2P_GO_NEG: 150b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru return "GO_NEG"; 151b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru case P2P_LISTEN_ONLY: 152b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru return "LISTEN_ONLY"; 153b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru case P2P_WAIT_PEER_CONNECT: 154b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru return "WAIT_PEER_CONNECT"; 155b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru case P2P_WAIT_PEER_IDLE: 156b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru return "WAIT_PEER_IDLE"; 157b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru case P2P_SD_DURING_FIND: 158b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru return "SD_DURING_FIND"; 159b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru case P2P_PROVISIONING: 160b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru return "PROVISIONING"; 161b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru case P2P_PD_DURING_FIND: 162b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru return "PD_DURING_FIND"; 163b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru case P2P_INVITE: 164b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru return "INVITE"; 165b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru case P2P_INVITE_LISTEN: 166b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru return "INVITE_LISTEN"; 167b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru default: 168b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru return "?"; 169b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 170b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru} 171b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru 172b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru 173b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queruconst char * p2p_get_state_txt(struct p2p_data *p2p) 174b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru{ 175b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru return p2p_state_txt(p2p->state); 176b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru} 177b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru 178b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru 179b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queruu16 p2p_get_provisioning_info(struct p2p_data *p2p, const u8 *addr) 180b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru{ 181b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru struct p2p_device *dev = NULL; 182b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru 183b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru if (!addr || !p2p) 184b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru return 0; 185b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru 186b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru dev = p2p_get_device(p2p, addr); 187b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru if (dev) 188b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru return dev->wps_prov_info; 189b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru else 190b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return 0; 191b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru} 192b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 193b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 194b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queruvoid p2p_clear_provisioning_info(struct p2p_data *p2p, const u8 *addr) 195b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru{ 196b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru struct p2p_device *dev = NULL; 197b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 198b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (!addr || !p2p) 199b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return; 200b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 201b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru dev = p2p_get_device(p2p, addr); 202b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (dev) 203b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru dev->wps_prov_info = 0; 204b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru} 205b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 206b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 207b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queruvoid p2p_set_state(struct p2p_data *p2p, int new_state) 208b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru{ 209b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru p2p_dbg(p2p, "State %s -> %s", 210b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru p2p_state_txt(p2p->state), p2p_state_txt(new_state)); 211b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru p2p->state = new_state; 212b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru} 213b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 214b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 215b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queruvoid p2p_set_timeout(struct p2p_data *p2p, unsigned int sec, unsigned int usec) 216b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru{ 217b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru p2p_dbg(p2p, "Set timeout (state=%s): %u.%06u sec", 218b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru p2p_state_txt(p2p->state), sec, usec); 219b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru eloop_cancel_timeout(p2p_state_timeout, p2p, NULL); 220b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru eloop_register_timeout(sec, usec, p2p_state_timeout, p2p, NULL); 221b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru} 222b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 223b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 224b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queruvoid p2p_clear_timeout(struct p2p_data *p2p) 225b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru{ 226b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru p2p_dbg(p2p, "Clear timeout (state=%s)", p2p_state_txt(p2p->state)); 227b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru eloop_cancel_timeout(p2p_state_timeout, p2p, NULL); 228b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru} 229b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 230b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 231b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queruvoid p2p_go_neg_failed(struct p2p_data *p2p, struct p2p_device *peer, 232b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru int status) 233b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru{ 234b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru struct p2p_go_neg_results res; 235b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru p2p_clear_timeout(p2p); 236b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru p2p_set_state(p2p, P2P_IDLE); 237b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (p2p->go_neg_peer) { 238b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru p2p->go_neg_peer->flags &= ~P2P_DEV_PEER_WAITING_RESPONSE; 239b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru p2p->go_neg_peer->wps_method = WPS_NOT_READY; 240b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 241b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru p2p->go_neg_peer = NULL; 242b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 243b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru os_memset(&res, 0, sizeof(res)); 244b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru res.status = status; 245b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (peer) { 246b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru os_memcpy(res.peer_device_addr, peer->info.p2p_device_addr, 247b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru ETH_ALEN); 248b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru os_memcpy(res.peer_interface_addr, peer->intended_addr, 249b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru ETH_ALEN); 250b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 251b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru p2p->cfg->go_neg_completed(p2p->cfg->cb_ctx, &res); 252b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru} 253b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 254b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 255b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Querustatic void p2p_listen_in_find(struct p2p_data *p2p, int dev_disc) 256b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru{ 257b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru unsigned int r, tu; 258b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru int freq; 259b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru struct wpabuf *ies; 260b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 261b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru p2p_dbg(p2p, "Starting short listen state (state=%s)", 262b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru p2p_state_txt(p2p->state)); 263b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 264b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru freq = p2p_channel_to_freq(p2p->cfg->reg_class, p2p->cfg->channel); 265b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (freq < 0) { 266b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru p2p_dbg(p2p, "Unknown regulatory class/channel"); 267b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return; 268b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 269b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 270b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru os_get_random((u8 *) &r, sizeof(r)); 271b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru tu = (r % ((p2p->max_disc_int - p2p->min_disc_int) + 1) + 272b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru p2p->min_disc_int) * 100; 273b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (p2p->max_disc_tu >= 0 && tu > (unsigned int) p2p->max_disc_tu) 274b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru tu = p2p->max_disc_tu; 275b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (!dev_disc && tu < 100) 276b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru tu = 100; /* Need to wait in non-device discovery use cases */ 277b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (p2p->cfg->max_listen && 1024 * tu / 1000 > p2p->cfg->max_listen) 278b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru tu = p2p->cfg->max_listen * 1000 / 1024; 279b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 280b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (tu == 0) { 281b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru p2p_dbg(p2p, "Skip listen state since duration was 0 TU"); 282b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru p2p_set_timeout(p2p, 0, 0); 283b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return; 284b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 285b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 286b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru p2p->pending_listen_freq = freq; 287b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru p2p->pending_listen_sec = 0; 288b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru p2p->pending_listen_usec = 1024 * tu; 289b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 290b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru ies = p2p_build_probe_resp_ies(p2p); 291b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (ies == NULL) 292b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return; 293b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 294b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (p2p->cfg->start_listen(p2p->cfg->cb_ctx, freq, 1024 * tu / 1000, 295b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru ies) < 0) { 296b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru p2p_dbg(p2p, "Failed to start listen mode"); 297b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru p2p->pending_listen_freq = 0; 298b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 299b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru wpabuf_free(ies); 300b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru} 301b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 302b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 303b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queruint p2p_listen(struct p2p_data *p2p, unsigned int timeout) 304b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru{ 305b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru int freq; 306b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru struct wpabuf *ies; 307b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 308b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru p2p_dbg(p2p, "Going to listen(only) state"); 309b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 310b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru freq = p2p_channel_to_freq(p2p->cfg->reg_class, p2p->cfg->channel); 311b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (freq < 0) { 312b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru p2p_dbg(p2p, "Unknown regulatory class/channel"); 313b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return -1; 314b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 315b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 316b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru p2p->pending_listen_freq = freq; 317b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru p2p->pending_listen_sec = timeout / 1000; 318b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru p2p->pending_listen_usec = (timeout % 1000) * 1000; 319b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru 320b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru if (p2p->p2p_scan_running) { 321b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (p2p->start_after_scan == P2P_AFTER_SCAN_CONNECT) { 322b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru p2p_dbg(p2p, "p2p_scan running - connect is already pending - skip listen"); 323b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru return 0; 324b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru } 325b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru p2p_dbg(p2p, "p2p_scan running - delay start of listen state"); 326b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru p2p->start_after_scan = P2P_AFTER_SCAN_LISTEN; 327b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return 0; 328b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 329b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 330b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru ies = p2p_build_probe_resp_ies(p2p); 331b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (ies == NULL) 332b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return -1; 333b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 334b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (p2p->cfg->start_listen(p2p->cfg->cb_ctx, freq, timeout, ies) < 0) { 335b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru p2p_dbg(p2p, "Failed to start listen mode"); 336b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru p2p->pending_listen_freq = 0; 337b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru wpabuf_free(ies); 338b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return -1; 339b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 340b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru wpabuf_free(ies); 341b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 342b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru p2p_set_state(p2p, P2P_LISTEN_ONLY); 343b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 344b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return 0; 345b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru} 346b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 347b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 348b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Querustatic void p2p_device_clear_reported(struct p2p_data *p2p) 349b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru{ 350b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru struct p2p_device *dev; 351b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru dl_list_for_each(dev, &p2p->devices, struct p2p_device, list) 352b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru dev->flags &= ~P2P_DEV_REPORTED; 353b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru} 354b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 355b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 356b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru/** 357b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * p2p_get_device - Fetch a peer entry 358b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * @p2p: P2P module context from p2p_init() 359b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * @addr: P2P Device Address of the peer 360b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * Returns: Pointer to the device entry or %NULL if not found 361b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru */ 362b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Querustruct p2p_device * p2p_get_device(struct p2p_data *p2p, const u8 *addr) 363b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru{ 364b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru struct p2p_device *dev; 365b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru dl_list_for_each(dev, &p2p->devices, struct p2p_device, list) { 366b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (os_memcmp(dev->info.p2p_device_addr, addr, ETH_ALEN) == 0) 367b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return dev; 368b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 369b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return NULL; 370b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru} 371b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 372b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 373b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru/** 374b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * p2p_get_device_interface - Fetch a peer entry based on P2P Interface Address 375b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * @p2p: P2P module context from p2p_init() 376b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * @addr: P2P Interface Address of the peer 377b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * Returns: Pointer to the device entry or %NULL if not found 378b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru */ 379b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Querustruct p2p_device * p2p_get_device_interface(struct p2p_data *p2p, 380b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru const u8 *addr) 381b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru{ 382b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru struct p2p_device *dev; 383b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru dl_list_for_each(dev, &p2p->devices, struct p2p_device, list) { 384b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (os_memcmp(dev->interface_addr, addr, ETH_ALEN) == 0) 385b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return dev; 386b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 387b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return NULL; 388b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru} 389b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 390b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 391b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru/** 392b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * p2p_create_device - Create a peer entry 393b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * @p2p: P2P module context from p2p_init() 394b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * @addr: P2P Device Address of the peer 395b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * Returns: Pointer to the device entry or %NULL on failure 396b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * 397b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * If there is already an entry for the peer, it will be returned instead of 398b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * creating a new one. 399b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru */ 400b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Querustatic struct p2p_device * p2p_create_device(struct p2p_data *p2p, 401b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru const u8 *addr) 402b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru{ 403b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru struct p2p_device *dev, *oldest = NULL; 404b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru size_t count = 0; 405b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 406b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru dev = p2p_get_device(p2p, addr); 407b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (dev) 408b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return dev; 409b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 410b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru dl_list_for_each(dev, &p2p->devices, struct p2p_device, list) { 411b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru count++; 412b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (oldest == NULL || 413b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru os_reltime_before(&dev->last_seen, &oldest->last_seen)) 414b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru oldest = dev; 415b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 416b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (count + 1 > p2p->cfg->max_peers && oldest) { 417b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru p2p_dbg(p2p, "Remove oldest peer entry to make room for a new peer"); 418b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru dl_list_del(&oldest->list); 419b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru p2p_device_free(p2p, oldest); 420b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 421b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 422b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru dev = os_zalloc(sizeof(*dev)); 423b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (dev == NULL) 424b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return NULL; 425b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru dl_list_add(&p2p->devices, &dev->list); 426b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru os_memcpy(dev->info.p2p_device_addr, addr, ETH_ALEN); 427b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 428b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return dev; 429b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru} 430b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 431b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 432b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Querustatic void p2p_copy_client_info(struct p2p_device *dev, 433b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru struct p2p_client_info *cli) 434b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru{ 435b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru os_memcpy(dev->info.device_name, cli->dev_name, cli->dev_name_len); 436b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru dev->info.device_name[cli->dev_name_len] = '\0'; 437b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru dev->info.dev_capab = cli->dev_capab; 438b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru dev->info.config_methods = cli->config_methods; 439b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru os_memcpy(dev->info.pri_dev_type, cli->pri_dev_type, 8); 440b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru dev->info.wps_sec_dev_type_list_len = 8 * cli->num_sec_dev_types; 441b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru os_memcpy(dev->info.wps_sec_dev_type_list, cli->sec_dev_types, 442b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru dev->info.wps_sec_dev_type_list_len); 443b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru} 444b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 445b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 446b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Querustatic int p2p_add_group_clients(struct p2p_data *p2p, const u8 *go_dev_addr, 447b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru const u8 *go_interface_addr, int freq, 448b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru const u8 *gi, size_t gi_len) 449b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru{ 450b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru struct p2p_group_info info; 451b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru size_t c; 452b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru struct p2p_device *dev; 453b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 454b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (gi == NULL) 455b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return 0; 456b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 457b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (p2p_group_info_parse(gi, gi_len, &info) < 0) 458b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return -1; 459b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 460b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru /* 461b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * Clear old data for this group; if the devices are still in the 462b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * group, the information will be restored in the loop following this. 463b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru */ 464b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru dl_list_for_each(dev, &p2p->devices, struct p2p_device, list) { 465b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (os_memcmp(dev->member_in_go_iface, go_interface_addr, 466b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru ETH_ALEN) == 0) { 467b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru os_memset(dev->member_in_go_iface, 0, ETH_ALEN); 468b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru os_memset(dev->member_in_go_dev, 0, ETH_ALEN); 469b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 470b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 471b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 472b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru for (c = 0; c < info.num_clients; c++) { 473b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru struct p2p_client_info *cli = &info.client[c]; 474b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (os_memcmp(cli->p2p_device_addr, p2p->cfg->dev_addr, 475b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru ETH_ALEN) == 0) 476b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru continue; /* ignore our own entry */ 477b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru dev = p2p_get_device(p2p, cli->p2p_device_addr); 478b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (dev) { 479b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (dev->flags & (P2P_DEV_GROUP_CLIENT_ONLY | 480b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru P2P_DEV_PROBE_REQ_ONLY)) { 481b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru /* 482b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * Update information since we have not 483b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * received this directly from the client. 484b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru */ 485b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru p2p_copy_client_info(dev, cli); 486b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } else { 487b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru /* 488b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * Need to update P2P Client Discoverability 489b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * flag since it is valid only in P2P Group 490b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * Info attribute. 491b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru */ 492b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru dev->info.dev_capab &= 493b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru ~P2P_DEV_CAPAB_CLIENT_DISCOVERABILITY; 494b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru dev->info.dev_capab |= 495b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru cli->dev_capab & 496b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru P2P_DEV_CAPAB_CLIENT_DISCOVERABILITY; 497b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 498b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (dev->flags & P2P_DEV_PROBE_REQ_ONLY) { 499b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru dev->flags &= ~P2P_DEV_PROBE_REQ_ONLY; 500b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 501b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru } else { 502b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru dev = p2p_create_device(p2p, cli->p2p_device_addr); 503b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru if (dev == NULL) 504b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru continue; 505b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru dev->flags |= P2P_DEV_GROUP_CLIENT_ONLY; 506b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru p2p_copy_client_info(dev, cli); 507b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru dev->oper_freq = freq; 508b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru p2p->cfg->dev_found(p2p->cfg->cb_ctx, 509b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru dev->info.p2p_device_addr, 510b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru &dev->info, 1); 511b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru dev->flags |= P2P_DEV_REPORTED | P2P_DEV_REPORTED_ONCE; 512b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru } 513b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru 514b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru os_memcpy(dev->interface_addr, cli->p2p_interface_addr, 515b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru ETH_ALEN); 516b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru os_get_reltime(&dev->last_seen); 517b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru os_memcpy(dev->member_in_go_dev, go_dev_addr, ETH_ALEN); 518b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru os_memcpy(dev->member_in_go_iface, go_interface_addr, 519b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru ETH_ALEN); 520b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru } 521b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru 522b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru return 0; 523b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru} 524b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru 525b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 526b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Querustatic void p2p_copy_wps_info(struct p2p_data *p2p, struct p2p_device *dev, 527b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru int probe_req, const struct p2p_message *msg) 528b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru{ 529b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru os_memcpy(dev->info.device_name, msg->device_name, 530b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru sizeof(dev->info.device_name)); 531b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 532b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (msg->manufacturer && 533b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru msg->manufacturer_len < sizeof(dev->info.manufacturer)) { 534b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru os_memset(dev->info.manufacturer, 0, 535b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru sizeof(dev->info.manufacturer)); 536b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru os_memcpy(dev->info.manufacturer, msg->manufacturer, 537b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru msg->manufacturer_len); 538b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru } 539b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru 540b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru if (msg->model_name && 541b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru msg->model_name_len < sizeof(dev->info.model_name)) { 542b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru os_memset(dev->info.model_name, 0, 543b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru sizeof(dev->info.model_name)); 544b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru os_memcpy(dev->info.model_name, msg->model_name, 545b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru msg->model_name_len); 546b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru } 547b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru 548b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru if (msg->model_number && 549b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru msg->model_number_len < sizeof(dev->info.model_number)) { 550b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru os_memset(dev->info.model_number, 0, 551b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru sizeof(dev->info.model_number)); 552b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru os_memcpy(dev->info.model_number, msg->model_number, 553b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru msg->model_number_len); 554b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru } 555b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru 556b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru if (msg->serial_number && 557b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru msg->serial_number_len < sizeof(dev->info.serial_number)) { 558b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru os_memset(dev->info.serial_number, 0, 559b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru sizeof(dev->info.serial_number)); 560b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru os_memcpy(dev->info.serial_number, msg->serial_number, 561b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru msg->serial_number_len); 562b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru } 563b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru 564b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (msg->pri_dev_type) 565b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru os_memcpy(dev->info.pri_dev_type, msg->pri_dev_type, 566b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru sizeof(dev->info.pri_dev_type)); 567b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru else if (msg->wps_pri_dev_type) 568b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru os_memcpy(dev->info.pri_dev_type, msg->wps_pri_dev_type, 569b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru sizeof(dev->info.pri_dev_type)); 570b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru 571b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru if (msg->wps_sec_dev_type_list) { 572b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru os_memcpy(dev->info.wps_sec_dev_type_list, 573b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru msg->wps_sec_dev_type_list, 574b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru msg->wps_sec_dev_type_list_len); 575b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru dev->info.wps_sec_dev_type_list_len = 576b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru msg->wps_sec_dev_type_list_len; 577b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru } 578b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru 579b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru if (msg->capability) { 580b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru /* 581b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * P2P Client Discoverability bit is reserved in all frames 582b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * that use this function, so do not change its value here. 583b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru */ 584b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru dev->info.dev_capab &= P2P_DEV_CAPAB_CLIENT_DISCOVERABILITY; 585b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru dev->info.dev_capab |= msg->capability[0] & 586b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru ~P2P_DEV_CAPAB_CLIENT_DISCOVERABILITY; 587b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru dev->info.group_capab = msg->capability[1]; 588b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 589b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 590b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (msg->ext_listen_timing) { 591b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru dev->ext_listen_period = WPA_GET_LE16(msg->ext_listen_timing); 592b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru dev->ext_listen_interval = 593b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru WPA_GET_LE16(msg->ext_listen_timing + 2); 594b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 595b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 596b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (!probe_req) { 597b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru u16 new_config_methods; 598b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru new_config_methods = msg->config_methods ? 599b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru msg->config_methods : msg->wps_config_methods; 600b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (new_config_methods && 601b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru dev->info.config_methods != new_config_methods) { 602b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru p2p_dbg(p2p, "Update peer " MACSTR 603b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru " config_methods 0x%x -> 0x%x", 604b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru MAC2STR(dev->info.p2p_device_addr), 605b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru dev->info.config_methods, 606b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru new_config_methods); 607b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru dev->info.config_methods = new_config_methods; 608b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 609b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 610b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru} 611b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 612b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 613b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru/** 614b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * p2p_add_device - Add peer entries based on scan results or P2P frames 615b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * @p2p: P2P module context from p2p_init() 616b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * @addr: Source address of Beacon or Probe Response frame (may be either 617b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru * P2P Device Address or P2P Interface Address) 618b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru * @level: Signal level (signal strength of the received frame from the peer) 619b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * @freq: Frequency on which the Beacon or Probe Response frame was received 620b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * @rx_time: Time when the result was received 621b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * @ies: IEs from the Beacon or Probe Response frame 622b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * @ies_len: Length of ies buffer in octets 623b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru * @scan_res: Whether this was based on scan results 624b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * Returns: 0 on success, -1 on failure 625b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * 626b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * If the scan result is for a GO, the clients in the group will also be added 627b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * to the peer table. This function can also be used with some other frames 628b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * like Provision Discovery Request that contains P2P Capability and P2P Device 629b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * Info attributes. 630b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru */ 631b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queruint p2p_add_device(struct p2p_data *p2p, const u8 *addr, int freq, 632b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru struct os_reltime *rx_time, int level, const u8 *ies, 633b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru size_t ies_len, int scan_res) 634b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru{ 635b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru struct p2p_device *dev; 636b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru struct p2p_message msg; 637b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru const u8 *p2p_dev_addr; 638b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru int i; 639b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru struct os_reltime time_now; 640b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 641b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru os_memset(&msg, 0, sizeof(msg)); 642b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (p2p_parse_ies(ies, ies_len, &msg)) { 643b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru p2p_dbg(p2p, "Failed to parse P2P IE for a device entry"); 644b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru p2p_parse_free(&msg); 645b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return -1; 646b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 647b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 648b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (msg.p2p_device_addr) 649b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru p2p_dev_addr = msg.p2p_device_addr; 650b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru else if (msg.device_id) 651b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru p2p_dev_addr = msg.device_id; 652b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru else { 653b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru p2p_dbg(p2p, "Ignore scan data without P2P Device Info or P2P Device Id"); 654b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru p2p_parse_free(&msg); 655b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return -1; 656b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 657b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 658b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (!is_zero_ether_addr(p2p->peer_filter) && 659b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru os_memcmp(p2p_dev_addr, p2p->peer_filter, ETH_ALEN) != 0) { 660b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru p2p_dbg(p2p, "Do not add peer filter for " MACSTR 661b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru " due to peer filter", MAC2STR(p2p_dev_addr)); 662b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru p2p_parse_free(&msg); 663b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return 0; 664b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 665b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 666b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru dev = p2p_create_device(p2p, p2p_dev_addr); 667b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (dev == NULL) { 668b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru p2p_parse_free(&msg); 669b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return -1; 670b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 671b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 672b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (rx_time == NULL) { 673b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru os_get_reltime(&time_now); 674b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru rx_time = &time_now; 675b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 676b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 677b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru /* 678b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * Update the device entry only if the new peer 679b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * entry is newer than the one previously stored. 680b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru */ 681b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (dev->last_seen.sec > 0 && 682b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru os_reltime_before(rx_time, &dev->last_seen)) { 683b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru p2p_dbg(p2p, "Do not update peer entry based on old frame (rx_time=%u.%06u last_seen=%u.%06u)", 684b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru (unsigned int) rx_time->sec, 685b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru (unsigned int) rx_time->usec, 686b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru (unsigned int) dev->last_seen.sec, 687b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru (unsigned int) dev->last_seen.usec); 688b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru p2p_parse_free(&msg); 689b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return -1; 690b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 691b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 692b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru os_memcpy(&dev->last_seen, rx_time, sizeof(struct os_reltime)); 693b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 694b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru dev->flags &= ~(P2P_DEV_PROBE_REQ_ONLY | P2P_DEV_GROUP_CLIENT_ONLY); 695b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 696b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (os_memcmp(addr, p2p_dev_addr, ETH_ALEN) != 0) 697b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru os_memcpy(dev->interface_addr, addr, ETH_ALEN); 698b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru if (msg.ssid && 699b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru (msg.ssid[1] != P2P_WILDCARD_SSID_LEN || 700b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru os_memcmp(msg.ssid + 2, P2P_WILDCARD_SSID, P2P_WILDCARD_SSID_LEN) 701b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru != 0)) { 702b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru os_memcpy(dev->oper_ssid, msg.ssid + 2, msg.ssid[1]); 703b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru dev->oper_ssid_len = msg.ssid[1]; 704b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 705b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 706b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (freq >= 2412 && freq <= 2484 && msg.ds_params && 707b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru *msg.ds_params >= 1 && *msg.ds_params <= 14) { 708b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru int ds_freq; 709b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (*msg.ds_params == 14) 710b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru ds_freq = 2484; 711b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru else 712b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru ds_freq = 2407 + *msg.ds_params * 5; 713b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (freq != ds_freq) { 714b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru p2p_dbg(p2p, "Update Listen frequency based on DS Parameter Set IE: %d -> %d MHz", 715b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru freq, ds_freq); 716b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru freq = ds_freq; 717b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 718b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 719b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 720b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (dev->listen_freq && dev->listen_freq != freq && scan_res) { 721b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru p2p_dbg(p2p, "Update Listen frequency based on scan results (" 722b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru MACSTR " %d -> %d MHz (DS param %d)", 723b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru MAC2STR(dev->info.p2p_device_addr), dev->listen_freq, 724b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru freq, msg.ds_params ? *msg.ds_params : -1); 725b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 726b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (scan_res) { 727b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru dev->listen_freq = freq; 728b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (msg.group_info) 729b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru dev->oper_freq = freq; 730b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 731b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru dev->info.level = level; 732b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 733b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru p2p_copy_wps_info(p2p, dev, 0, &msg); 734b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 735b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru for (i = 0; i < P2P_MAX_WPS_VENDOR_EXT; i++) { 736b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru wpabuf_free(dev->info.wps_vendor_ext[i]); 737b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru dev->info.wps_vendor_ext[i] = NULL; 738b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 739b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 740b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru for (i = 0; i < P2P_MAX_WPS_VENDOR_EXT; i++) { 741b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru if (msg.wps_vendor_ext[i] == NULL) 742b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru break; 743b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru dev->info.wps_vendor_ext[i] = wpabuf_alloc_copy( 744b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru msg.wps_vendor_ext[i], msg.wps_vendor_ext_len[i]); 745b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (dev->info.wps_vendor_ext[i] == NULL) 746b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru break; 747b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 748b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru 749b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru if (msg.wfd_subelems) { 750b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru wpabuf_free(dev->info.wfd_subelems); 751b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru dev->info.wfd_subelems = wpabuf_dup(msg.wfd_subelems); 752b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 753b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 754b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (scan_res) { 755b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru p2p_add_group_clients(p2p, p2p_dev_addr, addr, freq, 756b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru msg.group_info, msg.group_info_len); 757b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 758b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 759b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru p2p_parse_free(&msg); 760b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru 761b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (p2p_pending_sd_req(p2p, dev)) 762b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru dev->flags |= P2P_DEV_SD_SCHEDULE; 763b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru 764b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (dev->flags & P2P_DEV_REPORTED) 765b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return 0; 766b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 767b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru p2p_dbg(p2p, "Peer found with Listen frequency %d MHz (rx_time=%u.%06u)", 768b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru freq, (unsigned int) rx_time->sec, 769b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru (unsigned int) rx_time->usec); 770b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (dev->flags & P2P_DEV_USER_REJECTED) { 771b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru p2p_dbg(p2p, "Do not report rejected device"); 772b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return 0; 773b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 774b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 775b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (dev->info.config_methods == 0 && 776b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru (freq == 2412 || freq == 2437 || freq == 2462)) { 777b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru /* 778b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * If we have only seen a Beacon frame from a GO, we do not yet 779b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * know what WPS config methods it supports. Since some 780b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * applications use config_methods value from P2P-DEVICE-FOUND 781b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * events, postpone reporting this peer until we've fully 782b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * discovered its capabilities. 783b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * 784b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * At least for now, do this only if the peer was detected on 785b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * one of the social channels since that peer can be easily be 786b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru * found again and there are no limitations of having to use 787b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * passive scan on this channels, so this can be done through 788b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * Probe Response frame that includes the config_methods 789b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * information. 790b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru */ 791b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru p2p_dbg(p2p, "Do not report peer " MACSTR 792b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru " with unknown config methods", MAC2STR(addr)); 793b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return 0; 794b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 795b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru 796b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru p2p->cfg->dev_found(p2p->cfg->cb_ctx, addr, &dev->info, 797b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru !(dev->flags & P2P_DEV_REPORTED_ONCE)); 798b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru dev->flags |= P2P_DEV_REPORTED | P2P_DEV_REPORTED_ONCE; 799b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 800b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return 0; 801b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru} 802b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 803b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 804b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Querustatic void p2p_device_free(struct p2p_data *p2p, struct p2p_device *dev) 805b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru{ 806b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru int i; 807b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 808b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (p2p->go_neg_peer == dev) { 809b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru /* 810b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * If GO Negotiation is in progress, report that it has failed. 811b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru */ 812b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru p2p_go_neg_failed(p2p, dev, -1); 813b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru p2p->go_neg_peer = NULL; 814b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 815b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (p2p->invite_peer == dev) 816b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru p2p->invite_peer = NULL; 817b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (p2p->sd_peer == dev) 818b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru p2p->sd_peer = NULL; 819b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (p2p->pending_client_disc_go == dev) 820b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru p2p->pending_client_disc_go = NULL; 821b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru 822b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru /* dev_lost() device, but only if it was previously dev_found() */ 823b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (dev->flags & P2P_DEV_REPORTED_ONCE) 824b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru p2p->cfg->dev_lost(p2p->cfg->cb_ctx, 825b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru dev->info.p2p_device_addr); 826b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 827b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru for (i = 0; i < P2P_MAX_WPS_VENDOR_EXT; i++) { 828b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru wpabuf_free(dev->info.wps_vendor_ext[i]); 829b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru dev->info.wps_vendor_ext[i] = NULL; 830b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 831b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 832b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru wpabuf_free(dev->info.wfd_subelems); 833b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 834b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru os_free(dev); 835b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru} 836b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 837b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 838b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Querustatic int p2p_get_next_prog_freq(struct p2p_data *p2p) 839b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru{ 840b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru struct p2p_channels *c; 841b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru struct p2p_reg_class *cla; 842b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru size_t cl, ch; 843b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru int found = 0; 844b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru u8 reg_class; 845b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru u8 channel; 846b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru int freq; 847b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 848b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru c = &p2p->cfg->channels; 849b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru for (cl = 0; cl < c->reg_classes; cl++) { 850b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru cla = &c->reg_class[cl]; 851b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (cla->reg_class != p2p->last_prog_scan_class) 852b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru continue; 853b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru for (ch = 0; ch < cla->channels; ch++) { 854b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (cla->channel[ch] == p2p->last_prog_scan_chan) { 855b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru found = 1; 856b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru break; 857b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 858b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 859b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (found) 860b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru break; 861b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 862b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 863b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru if (!found) { 864b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru /* Start from beginning */ 865b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru reg_class = c->reg_class[0].reg_class; 866b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru channel = c->reg_class[0].channel[0]; 867b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } else { 868b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru /* Pick the next channel */ 869b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru ch++; 870b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (ch == cla->channels) { 871b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru cl++; 872b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (cl == c->reg_classes) 873b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru cl = 0; 874b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru ch = 0; 875b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 876b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru reg_class = c->reg_class[cl].reg_class; 877b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru channel = c->reg_class[cl].channel[ch]; 878b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 879b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 880b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru freq = p2p_channel_to_freq(reg_class, channel); 881b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru p2p_dbg(p2p, "Next progressive search channel: reg_class %u channel %u -> %d MHz", 882b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru reg_class, channel, freq); 883b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru p2p->last_prog_scan_class = reg_class; 884b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru p2p->last_prog_scan_chan = channel; 885b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 886b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (freq == 2412 || freq == 2437 || freq == 2462) 887b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return 0; /* No need to add social channels */ 888b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return freq; 889b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru} 890b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 891b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 892b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Querustatic void p2p_search(struct p2p_data *p2p) 893b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru{ 894b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru int freq = 0; 895b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru enum p2p_scan_type type; 896b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru u16 pw_id = DEV_PW_DEFAULT; 897b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru int res; 898b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 899b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (p2p->drv_in_listen) { 900b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru p2p_dbg(p2p, "Driver is still in Listen state - wait for it to end before continuing"); 901b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return; 902b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 903b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru p2p->cfg->stop_listen(p2p->cfg->cb_ctx); 904b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 905b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (p2p->find_type == P2P_FIND_PROGRESSIVE && 906b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru (freq = p2p_get_next_prog_freq(p2p)) > 0) { 907b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru type = P2P_SCAN_SOCIAL_PLUS_ONE; 908b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru p2p_dbg(p2p, "Starting search (+ freq %u)", freq); 909b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } else { 910b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru type = P2P_SCAN_SOCIAL; 911b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru p2p_dbg(p2p, "Starting search"); 912b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 913b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 914b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru res = p2p->cfg->p2p_scan(p2p->cfg->cb_ctx, type, freq, 915b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru p2p->num_req_dev_types, p2p->req_dev_types, 916b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru p2p->find_dev_id, pw_id); 917b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (res < 0) { 918b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru p2p_dbg(p2p, "Scan request failed"); 919b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru p2p_continue_find(p2p); 920b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } else { 921b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru p2p_dbg(p2p, "Running p2p_scan"); 922b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru p2p->p2p_scan_running = 1; 923b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru eloop_cancel_timeout(p2p_scan_timeout, p2p, NULL); 924b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru eloop_register_timeout(P2P_SCAN_TIMEOUT, 0, p2p_scan_timeout, 925b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru p2p, NULL); 926b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 927b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru} 928b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 929b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 930b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Querustatic void p2p_find_timeout(void *eloop_ctx, void *timeout_ctx) 931b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru{ 932b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru struct p2p_data *p2p = eloop_ctx; 933b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru p2p_dbg(p2p, "Find timeout -> stop"); 934b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru p2p_stop_find(p2p); 935b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru} 936b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 937b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 938b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Querustatic int p2p_run_after_scan(struct p2p_data *p2p) 939b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru{ 940b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru struct p2p_device *dev; 941b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru enum p2p_after_scan op; 942b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 943b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (p2p->after_scan_tx) { 944b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru p2p->after_scan_tx_in_progress = 1; 945b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru p2p_dbg(p2p, "Send pending Action frame at p2p_scan completion"); 946b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru p2p->cfg->send_action(p2p->cfg->cb_ctx, 947b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru p2p->after_scan_tx->freq, 948b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru p2p->after_scan_tx->dst, 949b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru p2p->after_scan_tx->src, 950b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru p2p->after_scan_tx->bssid, 951b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru (u8 *) (p2p->after_scan_tx + 1), 952b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru p2p->after_scan_tx->len, 953b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru p2p->after_scan_tx->wait_time); 954b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru os_free(p2p->after_scan_tx); 955b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru p2p->after_scan_tx = NULL; 956b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return 1; 957b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 958b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 959b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru op = p2p->start_after_scan; 960b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru p2p->start_after_scan = P2P_AFTER_SCAN_NOTHING; 961b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru switch (op) { 962b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru case P2P_AFTER_SCAN_NOTHING: 963b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru break; 964b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru case P2P_AFTER_SCAN_LISTEN: 965b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru p2p_dbg(p2p, "Start previously requested Listen state"); 966b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru p2p_listen(p2p, p2p->pending_listen_sec * 1000 + 967b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru p2p->pending_listen_usec / 1000); 968b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return 1; 969b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru case P2P_AFTER_SCAN_CONNECT: 970b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru p2p_dbg(p2p, "Start previously requested connect with " MACSTR, 971b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru MAC2STR(p2p->after_scan_peer)); 972b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru dev = p2p_get_device(p2p, p2p->after_scan_peer); 973b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (dev == NULL) { 974b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru p2p_dbg(p2p, "Peer not known anymore"); 975b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru break; 976b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 977b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru p2p_connect_send(p2p, dev); 978b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return 1; 979b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 980b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 981b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return 0; 982b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru} 983b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 984b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 985b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Querustatic void p2p_scan_timeout(void *eloop_ctx, void *timeout_ctx) 986b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru{ 987b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru struct p2p_data *p2p = eloop_ctx; 988b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru int running; 989b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru p2p_dbg(p2p, "p2p_scan timeout (running=%d)", p2p->p2p_scan_running); 990b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru running = p2p->p2p_scan_running; 991b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru /* Make sure we recover from missed scan results callback */ 992b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru p2p->p2p_scan_running = 0; 993b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 994b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (running) 995b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru p2p_run_after_scan(p2p); 996b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru} 997b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 998b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 999b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Querustatic void p2p_free_req_dev_types(struct p2p_data *p2p) 1000b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru{ 1001b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru p2p->num_req_dev_types = 0; 1002b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru os_free(p2p->req_dev_types); 1003b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru p2p->req_dev_types = NULL; 1004b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru} 1005b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1006b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1007b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queruint p2p_find(struct p2p_data *p2p, unsigned int timeout, 1008b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru enum p2p_discovery_type type, 1009b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru unsigned int num_req_dev_types, const u8 *req_dev_types, 1010b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru const u8 *dev_id, unsigned int search_delay) 1011b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru{ 1012b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru int res; 1013b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1014b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru p2p_dbg(p2p, "Starting find (type=%d)", type); 1015b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru os_get_reltime(&p2p->find_start); 1016b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (p2p->p2p_scan_running) { 1017b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru p2p_dbg(p2p, "p2p_scan is already running"); 1018b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1019b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1020b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru p2p_free_req_dev_types(p2p); 1021b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (req_dev_types && num_req_dev_types) { 1022b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru p2p->req_dev_types = os_malloc(num_req_dev_types * 1023b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru WPS_DEV_TYPE_LEN); 1024b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (p2p->req_dev_types == NULL) 1025b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return -1; 1026b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru os_memcpy(p2p->req_dev_types, req_dev_types, 1027b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru num_req_dev_types * WPS_DEV_TYPE_LEN); 1028b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru p2p->num_req_dev_types = num_req_dev_types; 1029b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1030b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1031b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (dev_id) { 1032b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru os_memcpy(p2p->find_dev_id_buf, dev_id, ETH_ALEN); 1033b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru p2p->find_dev_id = p2p->find_dev_id_buf; 1034b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } else 1035b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru p2p->find_dev_id = NULL; 1036b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1037b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru p2p->start_after_scan = P2P_AFTER_SCAN_NOTHING; 1038b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru p2p_clear_timeout(p2p); 1039b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru p2p->cfg->stop_listen(p2p->cfg->cb_ctx); 1040b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru p2p->find_type = type; 1041b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru p2p_device_clear_reported(p2p); 1042b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru p2p_set_state(p2p, P2P_SEARCH); 1043b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru p2p->search_delay = search_delay; 1044b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru p2p->in_search_delay = 0; 1045b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru eloop_cancel_timeout(p2p_find_timeout, p2p, NULL); 1046b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru p2p->last_p2p_find_timeout = timeout; 1047b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (timeout) 1048b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru eloop_register_timeout(timeout, 0, p2p_find_timeout, 1049b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru p2p, NULL); 1050b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru switch (type) { 1051b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru case P2P_FIND_START_WITH_FULL: 1052b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru case P2P_FIND_PROGRESSIVE: 1053b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru res = p2p->cfg->p2p_scan(p2p->cfg->cb_ctx, P2P_SCAN_FULL, 0, 1054b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru p2p->num_req_dev_types, 1055b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru p2p->req_dev_types, dev_id, 1056b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru DEV_PW_DEFAULT); 1057b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru break; 1058b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru case P2P_FIND_ONLY_SOCIAL: 1059b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru res = p2p->cfg->p2p_scan(p2p->cfg->cb_ctx, P2P_SCAN_SOCIAL, 0, 1060b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru p2p->num_req_dev_types, 1061b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru p2p->req_dev_types, dev_id, 1062b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru DEV_PW_DEFAULT); 1063b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru break; 1064b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru default: 1065b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return -1; 1066b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1067b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1068b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru if (res == 0) { 1069b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru p2p_dbg(p2p, "Running p2p_scan"); 1070b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru p2p->p2p_scan_running = 1; 1071b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru eloop_cancel_timeout(p2p_scan_timeout, p2p, NULL); 1072b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru eloop_register_timeout(P2P_SCAN_TIMEOUT, 0, p2p_scan_timeout, 1073b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru p2p, NULL); 1074b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru } else if (p2p->p2p_scan_running) { 1075b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru p2p_dbg(p2p, "Failed to start p2p_scan - another p2p_scan was already running"); 1076b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru /* wait for the previous p2p_scan to complete */ 1077b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru } else { 1078b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru p2p_dbg(p2p, "Failed to start p2p_scan"); 1079b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru p2p_set_state(p2p, P2P_IDLE); 1080b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru eloop_cancel_timeout(p2p_find_timeout, p2p, NULL); 1081b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru } 1082b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru 1083b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru return res; 1084b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru} 1085b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1086b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1087b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queruvoid p2p_stop_find_for_freq(struct p2p_data *p2p, int freq) 1088b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru{ 1089b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru p2p_dbg(p2p, "Stopping find"); 1090b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru eloop_cancel_timeout(p2p_find_timeout, p2p, NULL); 1091b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru p2p_clear_timeout(p2p); 1092b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (p2p->state == P2P_SEARCH) 1093b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru p2p->cfg->find_stopped(p2p->cfg->cb_ctx); 1094b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru p2p_set_state(p2p, P2P_IDLE); 1095b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru p2p_free_req_dev_types(p2p); 1096b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru p2p->start_after_scan = P2P_AFTER_SCAN_NOTHING; 1097b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (p2p->go_neg_peer) 1098b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru p2p->go_neg_peer->flags &= ~P2P_DEV_PEER_WAITING_RESPONSE; 1099b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru p2p->go_neg_peer = NULL; 1100b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru p2p->sd_peer = NULL; 1101b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru p2p->invite_peer = NULL; 1102b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru p2p_stop_listen_for_freq(p2p, freq); 1103b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru} 1104b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1105b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1106b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queruvoid p2p_stop_listen_for_freq(struct p2p_data *p2p, int freq) 1107b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru{ 1108b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (freq > 0 && p2p->drv_in_listen == freq && p2p->in_listen) { 1109b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru p2p_dbg(p2p, "Skip stop_listen since we are on correct channel for response"); 1110b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return; 1111b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1112b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (p2p->in_listen) { 1113b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru p2p->in_listen = 0; 1114b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru p2p_clear_timeout(p2p); 1115b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1116b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (p2p->drv_in_listen) { 1117b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru /* 1118b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * The driver may not deliver callback to p2p_listen_end() 1119b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * when the operation gets canceled, so clear the internal 1120b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * variable that is tracking driver state. 1121b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru */ 1122b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru p2p_dbg(p2p, "Clear drv_in_listen (%d)", p2p->drv_in_listen); 1123b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru p2p->drv_in_listen = 0; 1124b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1125b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru p2p->cfg->stop_listen(p2p->cfg->cb_ctx); 1126b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru} 1127b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1128b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1129b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queruvoid p2p_stop_listen(struct p2p_data *p2p) 1130b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru{ 1131b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (p2p->state != P2P_LISTEN_ONLY) { 1132b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru p2p_dbg(p2p, "Skip stop_listen since not in listen_only state."); 1133b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return; 1134b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1135b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1136b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru p2p_stop_listen_for_freq(p2p, 0); 1137b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru p2p_set_state(p2p, P2P_IDLE); 1138b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru} 1139b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1140b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1141b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queruvoid p2p_stop_find(struct p2p_data *p2p) 1142b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru{ 1143b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru p2p_stop_find_for_freq(p2p, 0); 1144b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru} 1145b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1146b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1147b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Querustatic int p2p_prepare_channel_pref(struct p2p_data *p2p, 1148b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru unsigned int force_freq, 1149b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru unsigned int pref_freq, int go) 1150b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru{ 1151b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru u8 op_class, op_channel; 1152b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru unsigned int freq = force_freq ? force_freq : pref_freq; 1153b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1154b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru p2p_dbg(p2p, "Prepare channel pref - force_freq=%u pref_freq=%u go=%d", 1155b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru force_freq, pref_freq, go); 1156b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (p2p_freq_to_channel(freq, &op_class, &op_channel) < 0) { 1157b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru p2p_dbg(p2p, "Unsupported frequency %u MHz", freq); 1158b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return -1; 1159b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1160b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1161b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (!p2p_channels_includes(&p2p->cfg->channels, op_class, op_channel) && 1162b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru (go || !p2p_channels_includes(&p2p->cfg->cli_channels, op_class, 1163b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru op_channel))) { 1164b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru p2p_dbg(p2p, "Frequency %u MHz (oper_class %u channel %u) not allowed for P2P", 1165b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru freq, op_class, op_channel); 1166b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return -1; 1167b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1168b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1169b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru p2p->op_reg_class = op_class; 1170b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru p2p->op_channel = op_channel; 1171b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1172b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (force_freq) { 1173b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru p2p->channels.reg_classes = 1; 1174b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru p2p->channels.reg_class[0].channels = 1; 1175b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru p2p->channels.reg_class[0].reg_class = p2p->op_reg_class; 1176b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru p2p->channels.reg_class[0].channel[0] = p2p->op_channel; 1177b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } else { 1178b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru os_memcpy(&p2p->channels, &p2p->cfg->channels, 1179b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru sizeof(struct p2p_channels)); 1180b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1181b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1182b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return 0; 1183b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru} 1184b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1185b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1186b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Querustatic void p2p_prepare_channel_best(struct p2p_data *p2p) 1187b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru{ 1188b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru u8 op_class, op_channel; 1189b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru const int op_classes_5ghz[] = { 124, 115, 0 }; 1190b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru const int op_classes_ht40[] = { 126, 127, 116, 117, 0 }; 1191b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru const int op_classes_vht[] = { 128, 0 }; 1192b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1193b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru p2p_dbg(p2p, "Prepare channel best"); 1194b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1195b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (!p2p->cfg->cfg_op_channel && p2p->best_freq_overall > 0 && 1196b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru p2p_supported_freq(p2p, p2p->best_freq_overall) && 1197b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru p2p_freq_to_channel(p2p->best_freq_overall, &op_class, &op_channel) 1198b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru == 0) { 1199b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru p2p_dbg(p2p, "Select best overall channel as operating channel preference"); 1200b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru p2p->op_reg_class = op_class; 1201b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru p2p->op_channel = op_channel; 1202b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } else if (!p2p->cfg->cfg_op_channel && p2p->best_freq_5 > 0 && 1203b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru p2p_supported_freq(p2p, p2p->best_freq_5) && 1204b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru p2p_freq_to_channel(p2p->best_freq_5, &op_class, &op_channel) 1205b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru == 0) { 1206b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru p2p_dbg(p2p, "Select best 5 GHz channel as operating channel preference"); 1207b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru p2p->op_reg_class = op_class; 1208b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru p2p->op_channel = op_channel; 1209b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } else if (!p2p->cfg->cfg_op_channel && p2p->best_freq_24 > 0 && 1210b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru p2p_supported_freq(p2p, p2p->best_freq_24) && 1211b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru p2p_freq_to_channel(p2p->best_freq_24, &op_class, 1212b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru &op_channel) == 0) { 1213b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru p2p_dbg(p2p, "Select best 2.4 GHz channel as operating channel preference"); 1214b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru p2p->op_reg_class = op_class; 1215b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru p2p->op_channel = op_channel; 1216b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } else if (p2p->cfg->num_pref_chan > 0 && 1217b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru p2p_channels_includes(&p2p->cfg->channels, 1218b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru p2p->cfg->pref_chan[0].op_class, 1219b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru p2p->cfg->pref_chan[0].chan)) { 1220b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru p2p_dbg(p2p, "Select first pref_chan entry as operating channel preference"); 1221b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru p2p->op_reg_class = p2p->cfg->pref_chan[0].op_class; 1222b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru p2p->op_channel = p2p->cfg->pref_chan[0].chan; 1223b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } else if (p2p_channel_select(&p2p->cfg->channels, op_classes_vht, 1224b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru &p2p->op_reg_class, &p2p->op_channel) == 1225b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 0) { 1226b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru p2p_dbg(p2p, "Select possible VHT channel (op_class %u channel %u) as operating channel preference", 1227b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru p2p->op_reg_class, p2p->op_channel); 1228b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } else if (p2p_channel_select(&p2p->cfg->channels, op_classes_ht40, 1229b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru &p2p->op_reg_class, &p2p->op_channel) == 1230b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 0) { 1231b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru p2p_dbg(p2p, "Select possible HT40 channel (op_class %u channel %u) as operating channel preference", 1232b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru p2p->op_reg_class, p2p->op_channel); 1233b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } else if (p2p_channel_select(&p2p->cfg->channels, op_classes_5ghz, 1234b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru &p2p->op_reg_class, &p2p->op_channel) == 1235b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 0) { 1236b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru p2p_dbg(p2p, "Select possible 5 GHz channel (op_class %u channel %u) as operating channel preference", 1237b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru p2p->op_reg_class, p2p->op_channel); 1238b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } else { 1239b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru p2p_dbg(p2p, "Select pre-configured channel as operating channel preference"); 1240b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru p2p->op_reg_class = p2p->cfg->op_reg_class; 1241b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru p2p->op_channel = p2p->cfg->op_channel; 1242b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1243b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1244b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru os_memcpy(&p2p->channels, &p2p->cfg->channels, 1245b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru sizeof(struct p2p_channels)); 1246b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru} 1247b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1248b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1249b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru/** 1250b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * p2p_prepare_channel - Select operating channel for GO Negotiation 1251b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * @p2p: P2P module context from p2p_init() 1252b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * @dev: Selected peer device 1253b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * @force_freq: Forced frequency in MHz or 0 if not forced 1254b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * @pref_freq: Preferred frequency in MHz or 0 if no preference 1255b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * @go: Whether the local end will be forced to be GO 1256b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * Returns: 0 on success, -1 on failure (channel not supported for P2P) 1257b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * 1258b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * This function is used to do initial operating channel selection for GO 1259b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * Negotiation prior to having received peer information. The selected channel 1260b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * may be further optimized in p2p_reselect_channel() once the peer information 1261b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * is available. 1262b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru */ 1263b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queruint p2p_prepare_channel(struct p2p_data *p2p, struct p2p_device *dev, 1264b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru unsigned int force_freq, unsigned int pref_freq, int go) 1265b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru{ 1266b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru p2p_dbg(p2p, "Prepare channel - force_freq=%u pref_freq=%u go=%d", 1267b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru force_freq, pref_freq, go); 1268b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (force_freq || pref_freq) { 1269b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (p2p_prepare_channel_pref(p2p, force_freq, pref_freq, go) < 1270b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 0) 1271b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return -1; 1272b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } else { 1273b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru p2p_prepare_channel_best(p2p); 1274b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1275b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru p2p_channels_dump(p2p, "prepared channels", &p2p->channels); 1276b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (go) 1277b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru p2p_channels_remove_freqs(&p2p->channels, &p2p->no_go_freq); 1278b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru else if (!force_freq) 1279b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru p2p_channels_union(&p2p->channels, &p2p->cfg->cli_channels, 1280b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru &p2p->channels); 1281b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru p2p_channels_dump(p2p, "after go/cli filter/add", &p2p->channels); 1282b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1283b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru p2p_dbg(p2p, "Own preference for operation channel: Operating Class %u Channel %u%s", 1284b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru p2p->op_reg_class, p2p->op_channel, 1285b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru force_freq ? " (forced)" : ""); 1286b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1287b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (force_freq) 1288b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru dev->flags |= P2P_DEV_FORCE_FREQ; 1289b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru else 1290b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru dev->flags &= ~P2P_DEV_FORCE_FREQ; 1291b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1292b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return 0; 1293b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru} 1294b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1295b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1296b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Querustatic void p2p_set_dev_persistent(struct p2p_device *dev, 1297b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru int persistent_group) 1298b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru{ 1299b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru switch (persistent_group) { 1300b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru case 0: 1301b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru dev->flags &= ~(P2P_DEV_PREFER_PERSISTENT_GROUP | 1302b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru P2P_DEV_PREFER_PERSISTENT_RECONN); 1303b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru break; 1304b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru case 1: 1305b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru dev->flags |= P2P_DEV_PREFER_PERSISTENT_GROUP; 1306b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru dev->flags &= ~P2P_DEV_PREFER_PERSISTENT_RECONN; 1307b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru break; 1308b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru case 2: 1309b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru dev->flags |= P2P_DEV_PREFER_PERSISTENT_GROUP | 1310b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru P2P_DEV_PREFER_PERSISTENT_RECONN; 1311b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru break; 1312b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1313b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru} 1314b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1315b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1316b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queruint p2p_connect(struct p2p_data *p2p, const u8 *peer_addr, 1317b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru enum p2p_wps_method wps_method, 1318b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru int go_intent, const u8 *own_interface_addr, 1319b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru unsigned int force_freq, int persistent_group, 1320b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru const u8 *force_ssid, size_t force_ssid_len, 1321b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru int pd_before_go_neg, unsigned int pref_freq) 1322b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru{ 1323b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru struct p2p_device *dev; 1324b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1325b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru p2p_dbg(p2p, "Request to start group negotiation - peer=" MACSTR 1326b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru " GO Intent=%d Intended Interface Address=" MACSTR 1327b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru " wps_method=%d persistent_group=%d pd_before_go_neg=%d", 1328b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru MAC2STR(peer_addr), go_intent, MAC2STR(own_interface_addr), 1329b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru wps_method, persistent_group, pd_before_go_neg); 1330b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1331b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru dev = p2p_get_device(p2p, peer_addr); 1332b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (dev == NULL || (dev->flags & P2P_DEV_PROBE_REQ_ONLY)) { 1333b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru p2p_dbg(p2p, "Cannot connect to unknown P2P Device " MACSTR, 1334b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru MAC2STR(peer_addr)); 1335b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return -1; 1336b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1337b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1338b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (p2p_prepare_channel(p2p, dev, force_freq, pref_freq, 1339b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru go_intent == 15) < 0) 1340b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return -1; 1341b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1342b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (dev->flags & P2P_DEV_GROUP_CLIENT_ONLY) { 1343b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (!(dev->info.dev_capab & 1344b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru P2P_DEV_CAPAB_CLIENT_DISCOVERABILITY)) { 1345b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru p2p_dbg(p2p, "Cannot connect to P2P Device " MACSTR 1346b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru " that is in a group and is not discoverable", 1347b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru MAC2STR(peer_addr)); 1348b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return -1; 1349b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1350b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (dev->oper_freq <= 0) { 1351b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru p2p_dbg(p2p, "Cannot connect to P2P Device " MACSTR 1352b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru " with incomplete information", 1353b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru MAC2STR(peer_addr)); 1354b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return -1; 1355b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1356b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1357b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru /* 1358b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * First, try to connect directly. If the peer does not 1359b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * acknowledge frames, assume it is sleeping and use device 1360b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * discoverability via the GO at that point. 1361b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru */ 1362b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1363b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1364b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru p2p->ssid_set = 0; 1365b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (force_ssid) { 1366b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru wpa_hexdump_ascii(MSG_DEBUG, "P2P: Forced SSID", 1367b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru force_ssid, force_ssid_len); 1368b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru os_memcpy(p2p->ssid, force_ssid, force_ssid_len); 1369b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru p2p->ssid_len = force_ssid_len; 1370b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru p2p->ssid_set = 1; 1371b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1372b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1373b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru dev->flags &= ~P2P_DEV_NOT_YET_READY; 1374b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru dev->flags &= ~P2P_DEV_USER_REJECTED; 1375b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru dev->flags &= ~P2P_DEV_WAIT_GO_NEG_RESPONSE; 1376b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru dev->flags &= ~P2P_DEV_WAIT_GO_NEG_CONFIRM; 1377b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (pd_before_go_neg) 1378b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru dev->flags |= P2P_DEV_PD_BEFORE_GO_NEG; 1379b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru else { 1380b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru dev->flags &= ~P2P_DEV_PD_BEFORE_GO_NEG; 1381b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru /* 1382b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * Assign dialog token and tie breaker here to use the same 1383b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * values in each retry within the same GO Negotiation exchange. 1384b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru */ 1385b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru dev->dialog_token++; 1386b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (dev->dialog_token == 0) 1387b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru dev->dialog_token = 1; 1388b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru dev->tie_breaker = p2p->next_tie_breaker; 1389b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru p2p->next_tie_breaker = !p2p->next_tie_breaker; 1390b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1391b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru dev->connect_reqs = 0; 1392b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru dev->go_neg_req_sent = 0; 1393b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru dev->go_state = UNKNOWN_GO; 1394b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru p2p_set_dev_persistent(dev, persistent_group); 1395b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru p2p->go_intent = go_intent; 1396b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru os_memcpy(p2p->intended_addr, own_interface_addr, ETH_ALEN); 1397b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1398b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (p2p->state != P2P_IDLE) 1399b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru p2p_stop_find(p2p); 1400b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1401b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (p2p->after_scan_tx) { 1402b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru /* 1403b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * We need to drop the pending frame to avoid issues with the 1404b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * new GO Negotiation, e.g., when the pending frame was from a 1405b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * previous attempt at starting a GO Negotiation. 1406b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru */ 1407b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru p2p_dbg(p2p, "Dropped previous pending Action frame TX that was waiting for p2p_scan completion"); 1408b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru os_free(p2p->after_scan_tx); 1409b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru p2p->after_scan_tx = NULL; 1410b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1411b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1412b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru dev->wps_method = wps_method; 1413b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru dev->status = P2P_SC_SUCCESS; 1414b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1415b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (p2p->p2p_scan_running) { 1416b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru p2p_dbg(p2p, "p2p_scan running - delay connect send"); 1417b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru p2p->start_after_scan = P2P_AFTER_SCAN_CONNECT; 1418b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru os_memcpy(p2p->after_scan_peer, peer_addr, ETH_ALEN); 1419b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return 0; 1420b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1421b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru p2p->start_after_scan = P2P_AFTER_SCAN_NOTHING; 1422b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1423b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return p2p_connect_send(p2p, dev); 1424b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru} 1425b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1426b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1427b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queruint p2p_authorize(struct p2p_data *p2p, const u8 *peer_addr, 1428b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru enum p2p_wps_method wps_method, 1429b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru int go_intent, const u8 *own_interface_addr, 1430b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru unsigned int force_freq, int persistent_group, 1431b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru const u8 *force_ssid, size_t force_ssid_len, 1432b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru unsigned int pref_freq) 1433b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru{ 1434b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru struct p2p_device *dev; 1435b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1436b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru p2p_dbg(p2p, "Request to authorize group negotiation - peer=" MACSTR 1437b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru " GO Intent=%d Intended Interface Address=" MACSTR 1438b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru " wps_method=%d persistent_group=%d", 1439b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru MAC2STR(peer_addr), go_intent, MAC2STR(own_interface_addr), 1440b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru wps_method, persistent_group); 1441b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1442b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru dev = p2p_get_device(p2p, peer_addr); 1443b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (dev == NULL) { 1444b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru p2p_dbg(p2p, "Cannot authorize unknown P2P Device " MACSTR, 1445b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru MAC2STR(peer_addr)); 1446b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return -1; 1447b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1448b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1449b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (p2p_prepare_channel(p2p, dev, force_freq, pref_freq, go_intent == 1450b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 15) < 0) 1451b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return -1; 1452b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1453b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru p2p->ssid_set = 0; 1454b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (force_ssid) { 1455b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru wpa_hexdump_ascii(MSG_DEBUG, "P2P: Forced SSID", 1456b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru force_ssid, force_ssid_len); 1457b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru os_memcpy(p2p->ssid, force_ssid, force_ssid_len); 1458b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru p2p->ssid_len = force_ssid_len; 1459b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru p2p->ssid_set = 1; 1460b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1461b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1462b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru dev->flags &= ~P2P_DEV_NOT_YET_READY; 1463b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru dev->flags &= ~P2P_DEV_USER_REJECTED; 1464b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru dev->go_neg_req_sent = 0; 1465b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru dev->go_state = UNKNOWN_GO; 1466b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru p2p_set_dev_persistent(dev, persistent_group); 1467b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru p2p->go_intent = go_intent; 1468b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru os_memcpy(p2p->intended_addr, own_interface_addr, ETH_ALEN); 1469b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1470b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru dev->wps_method = wps_method; 1471b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru dev->status = P2P_SC_SUCCESS; 1472b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1473b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return 0; 1474b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru} 1475b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1476b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1477b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queruvoid p2p_add_dev_info(struct p2p_data *p2p, const u8 *addr, 1478b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru struct p2p_device *dev, struct p2p_message *msg) 1479b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru{ 1480b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru os_get_reltime(&dev->last_seen); 1481b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1482b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru p2p_copy_wps_info(p2p, dev, 0, msg); 1483b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1484b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (msg->listen_channel) { 1485b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru int freq; 1486b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru freq = p2p_channel_to_freq(msg->listen_channel[3], 1487b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru msg->listen_channel[4]); 1488b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (freq < 0) { 1489b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru p2p_dbg(p2p, "Unknown peer Listen channel: " 1490b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru "country=%c%c(0x%02x) reg_class=%u channel=%u", 1491b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru msg->listen_channel[0], 1492b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru msg->listen_channel[1], 1493b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru msg->listen_channel[2], 1494b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru msg->listen_channel[3], 1495b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru msg->listen_channel[4]); 1496b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } else { 1497b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru p2p_dbg(p2p, "Update peer " MACSTR 1498b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru " Listen channel: %u -> %u MHz", 1499b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru MAC2STR(dev->info.p2p_device_addr), 1500b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru dev->listen_freq, freq); 1501b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru dev->listen_freq = freq; 1502b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1503b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1504b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1505b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (msg->wfd_subelems) { 1506b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru wpabuf_free(dev->info.wfd_subelems); 1507b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru dev->info.wfd_subelems = wpabuf_dup(msg->wfd_subelems); 1508b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1509b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1510b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (dev->flags & P2P_DEV_PROBE_REQ_ONLY) { 1511b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru dev->flags &= ~P2P_DEV_PROBE_REQ_ONLY; 1512b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru p2p_dbg(p2p, "Completed device entry based on data from GO Negotiation Request"); 1513b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } else { 1514b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru p2p_dbg(p2p, "Created device entry based on GO Neg Req: " 1515b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru MACSTR " dev_capab=0x%x group_capab=0x%x name='%s' " 1516b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru "listen_freq=%d", 1517b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru MAC2STR(dev->info.p2p_device_addr), 1518b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru dev->info.dev_capab, dev->info.group_capab, 1519b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru dev->info.device_name, dev->listen_freq); 1520b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1521b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1522b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru dev->flags &= ~P2P_DEV_GROUP_CLIENT_ONLY; 1523b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1524b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (dev->flags & P2P_DEV_USER_REJECTED) { 1525b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru p2p_dbg(p2p, "Do not report rejected device"); 1526b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return; 1527b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1528b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1529b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru p2p->cfg->dev_found(p2p->cfg->cb_ctx, addr, &dev->info, 1530b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru !(dev->flags & P2P_DEV_REPORTED_ONCE)); 1531b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru dev->flags |= P2P_DEV_REPORTED | P2P_DEV_REPORTED_ONCE; 1532b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru} 1533b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1534b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1535b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queruvoid p2p_build_ssid(struct p2p_data *p2p, u8 *ssid, size_t *ssid_len) 1536b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru{ 1537b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru os_memcpy(ssid, P2P_WILDCARD_SSID, P2P_WILDCARD_SSID_LEN); 1538b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru p2p_random((char *) &ssid[P2P_WILDCARD_SSID_LEN], 2); 1539b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru os_memcpy(&ssid[P2P_WILDCARD_SSID_LEN + 2], 1540b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru p2p->cfg->ssid_postfix, p2p->cfg->ssid_postfix_len); 1541b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru *ssid_len = P2P_WILDCARD_SSID_LEN + 2 + p2p->cfg->ssid_postfix_len; 1542b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru} 1543b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1544b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1545b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queruint p2p_go_params(struct p2p_data *p2p, struct p2p_go_neg_results *params) 1546b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru{ 1547b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru p2p_build_ssid(p2p, params->ssid, ¶ms->ssid_len); 1548b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru p2p_random(params->passphrase, 8); 1549b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return 0; 1550b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru} 1551b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1552b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1553b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queruvoid p2p_go_complete(struct p2p_data *p2p, struct p2p_device *peer) 1554b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru{ 1555b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru struct p2p_go_neg_results res; 1556b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru int go = peer->go_state == LOCAL_GO; 1557b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru struct p2p_channels intersection; 1558b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru int freqs; 1559b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru size_t i, j; 1560b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1561b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru p2p_dbg(p2p, "GO Negotiation with " MACSTR " completed (%s will be GO)", 1562b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru MAC2STR(peer->info.p2p_device_addr), go ? "local end" : "peer"); 1563b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1564b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru os_memset(&res, 0, sizeof(res)); 1565b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru res.role_go = go; 1566b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru os_memcpy(res.peer_device_addr, peer->info.p2p_device_addr, ETH_ALEN); 1567b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru os_memcpy(res.peer_interface_addr, peer->intended_addr, ETH_ALEN); 1568b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru res.wps_method = peer->wps_method; 1569b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (peer->flags & P2P_DEV_PREFER_PERSISTENT_GROUP) { 1570b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (peer->flags & P2P_DEV_PREFER_PERSISTENT_RECONN) 1571b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru res.persistent_group = 2; 1572b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru else 1573b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru res.persistent_group = 1; 1574b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1575b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1576b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (go) { 1577b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru /* Setup AP mode for WPS provisioning */ 1578b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru res.freq = p2p_channel_to_freq(p2p->op_reg_class, 1579b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru p2p->op_channel); 1580b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru os_memcpy(res.ssid, p2p->ssid, p2p->ssid_len); 1581b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru res.ssid_len = p2p->ssid_len; 1582b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru p2p_random(res.passphrase, 8); 1583b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } else { 1584b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru res.freq = peer->oper_freq; 1585b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (p2p->ssid_len) { 1586b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru os_memcpy(res.ssid, p2p->ssid, p2p->ssid_len); 1587b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru res.ssid_len = p2p->ssid_len; 1588b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1589b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1590b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1591b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru p2p_channels_dump(p2p, "own channels", &p2p->channels); 1592b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru p2p_channels_dump(p2p, "peer channels", &peer->channels); 1593b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru p2p_channels_intersect(&p2p->channels, &peer->channels, 1594b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru &intersection); 1595b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (go) { 1596b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru p2p_channels_remove_freqs(&intersection, &p2p->no_go_freq); 1597b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru p2p_channels_dump(p2p, "intersection after no-GO removal", 1598b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru &intersection); 1599b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1600b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru freqs = 0; 1601b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru for (i = 0; i < intersection.reg_classes; i++) { 1602b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru struct p2p_reg_class *c = &intersection.reg_class[i]; 1603b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (freqs + 1 == P2P_MAX_CHANNELS) 1604b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru break; 1605b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru for (j = 0; j < c->channels; j++) { 1606b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru int freq; 1607b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (freqs + 1 == P2P_MAX_CHANNELS) 1608b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru break; 1609b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru freq = p2p_channel_to_freq(c->reg_class, c->channel[j]); 1610b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (freq < 0) 1611b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru continue; 1612b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru res.freq_list[freqs++] = freq; 1613b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1614b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1615b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1616b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru res.peer_config_timeout = go ? peer->client_timeout : peer->go_timeout; 1617b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1618b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru p2p_clear_timeout(p2p); 1619b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru p2p->ssid_set = 0; 1620b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru peer->go_neg_req_sent = 0; 1621b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru peer->wps_method = WPS_NOT_READY; 1622b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1623b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru p2p_set_state(p2p, P2P_PROVISIONING); 1624b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru p2p->cfg->go_neg_completed(p2p->cfg->cb_ctx, &res); 1625b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru} 1626b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1627b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1628b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Querustatic void p2p_rx_p2p_action(struct p2p_data *p2p, const u8 *sa, 1629b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru const u8 *data, size_t len, int rx_freq) 1630b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru{ 1631b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru p2p_dbg(p2p, "RX P2P Public Action from " MACSTR, MAC2STR(sa)); 1632b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru wpa_hexdump(MSG_MSGDUMP, "P2P: P2P Public Action contents", data, len); 1633b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1634b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (len < 1) 1635b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return; 1636b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1637b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru switch (data[0]) { 1638b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru case P2P_GO_NEG_REQ: 1639b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru p2p_process_go_neg_req(p2p, sa, data + 1, len - 1, rx_freq); 1640b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru break; 1641b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru case P2P_GO_NEG_RESP: 1642b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru p2p_process_go_neg_resp(p2p, sa, data + 1, len - 1, rx_freq); 1643b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru break; 1644b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru case P2P_GO_NEG_CONF: 1645b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru p2p_process_go_neg_conf(p2p, sa, data + 1, len - 1); 1646b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru break; 1647b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru case P2P_INVITATION_REQ: 1648b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru p2p_process_invitation_req(p2p, sa, data + 1, len - 1, 1649b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru rx_freq); 1650b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru break; 1651b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru case P2P_INVITATION_RESP: 1652b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru p2p->cfg->send_action_done(p2p->cfg->cb_ctx); 1653b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru p2p_process_invitation_resp(p2p, sa, data + 1, len - 1); 1654b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru break; 1655b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru case P2P_PROV_DISC_REQ: 1656b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru p2p_process_prov_disc_req(p2p, sa, data + 1, len - 1, rx_freq); 1657b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru break; 1658b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru case P2P_PROV_DISC_RESP: 1659b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru p2p_process_prov_disc_resp(p2p, sa, data + 1, len - 1); 1660b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru break; 1661b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru case P2P_DEV_DISC_REQ: 1662b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru p2p_process_dev_disc_req(p2p, sa, data + 1, len - 1, rx_freq); 1663b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru break; 1664b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru case P2P_DEV_DISC_RESP: 1665b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru p2p_process_dev_disc_resp(p2p, sa, data + 1, len - 1); 1666b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru break; 1667b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru default: 1668b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru p2p_dbg(p2p, "Unsupported P2P Public Action frame type %d", 1669b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru data[0]); 1670b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru break; 1671b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1672b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru} 1673b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1674b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1675b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Querustatic void p2p_rx_action_public(struct p2p_data *p2p, const u8 *da, 1676b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru const u8 *sa, const u8 *bssid, const u8 *data, 1677b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru size_t len, int freq) 1678b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru{ 1679b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (len < 1) 1680b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return; 1681b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1682b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru switch (data[0]) { 1683b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru case WLAN_PA_VENDOR_SPECIFIC: 1684b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru data++; 1685b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru len--; 1686b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (len < 3) 1687b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return; 1688b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (WPA_GET_BE24(data) != OUI_WFA) 1689b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return; 1690b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1691b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru data += 3; 1692b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru len -= 3; 1693b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (len < 1) 1694b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return; 1695b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1696b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (*data != P2P_OUI_TYPE) 1697b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return; 1698b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1699b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru p2p_rx_p2p_action(p2p, sa, data + 1, len - 1, freq); 1700b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru break; 1701b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru case WLAN_PA_GAS_INITIAL_REQ: 1702b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru p2p_rx_gas_initial_req(p2p, sa, data + 1, len - 1, freq); 1703b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru break; 1704b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru case WLAN_PA_GAS_INITIAL_RESP: 1705b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru p2p_rx_gas_initial_resp(p2p, sa, data + 1, len - 1, freq); 1706b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru break; 1707b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru case WLAN_PA_GAS_COMEBACK_REQ: 1708b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru p2p_rx_gas_comeback_req(p2p, sa, data + 1, len - 1, freq); 1709b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru break; 1710b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru case WLAN_PA_GAS_COMEBACK_RESP: 1711b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru p2p_rx_gas_comeback_resp(p2p, sa, data + 1, len - 1, freq); 1712b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru break; 1713b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1714b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru} 1715b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1716b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1717b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queruvoid p2p_rx_action(struct p2p_data *p2p, const u8 *da, const u8 *sa, 1718b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru const u8 *bssid, u8 category, 1719b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru const u8 *data, size_t len, int freq) 1720b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru{ 1721b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (category == WLAN_ACTION_PUBLIC) { 1722b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru p2p_rx_action_public(p2p, da, sa, bssid, data, len, freq); 1723b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return; 1724b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1725b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1726b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (category != WLAN_ACTION_VENDOR_SPECIFIC) 1727b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return; 1728b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1729b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (len < 4) 1730b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return; 1731b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1732b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (WPA_GET_BE24(data) != OUI_WFA) 1733b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return; 1734b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru data += 3; 1735b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru len -= 3; 1736b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1737b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (*data != P2P_OUI_TYPE) 1738b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return; 1739b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru data++; 1740b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru len--; 1741b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1742b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru /* P2P action frame */ 1743b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru p2p_dbg(p2p, "RX P2P Action from " MACSTR, MAC2STR(sa)); 1744b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru wpa_hexdump(MSG_MSGDUMP, "P2P: P2P Action contents", data, len); 1745b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1746b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (len < 1) 1747b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return; 1748b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru switch (data[0]) { 1749b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru case P2P_NOA: 1750b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru p2p_dbg(p2p, "Received P2P Action - Notice of Absence"); 1751b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru /* TODO */ 1752b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru break; 1753b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru case P2P_PRESENCE_REQ: 1754b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru p2p_process_presence_req(p2p, da, sa, data + 1, len - 1, freq); 1755b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru break; 1756b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru case P2P_PRESENCE_RESP: 1757b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru p2p_process_presence_resp(p2p, da, sa, data + 1, len - 1); 1758b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru break; 1759b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru case P2P_GO_DISC_REQ: 1760b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru p2p_process_go_disc_req(p2p, da, sa, data + 1, len - 1, freq); 1761b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru break; 1762b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru default: 1763b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru p2p_dbg(p2p, "Received P2P Action - unknown type %u", data[0]); 1764b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru break; 1765b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1766b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru} 1767b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1768b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1769b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Querustatic void p2p_go_neg_start(void *eloop_ctx, void *timeout_ctx) 1770b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru{ 1771b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru struct p2p_data *p2p = eloop_ctx; 1772b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (p2p->go_neg_peer == NULL) 1773b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return; 1774b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru p2p->cfg->stop_listen(p2p->cfg->cb_ctx); 1775b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru p2p->go_neg_peer->status = P2P_SC_SUCCESS; 1776b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru p2p_connect_send(p2p, p2p->go_neg_peer); 1777b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru} 1778b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1779b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1780b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Querustatic void p2p_invite_start(void *eloop_ctx, void *timeout_ctx) 1781b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru{ 1782b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru struct p2p_data *p2p = eloop_ctx; 1783b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (p2p->invite_peer == NULL) 1784b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru return; 1785b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru p2p->cfg->stop_listen(p2p->cfg->cb_ctx); 1786b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru p2p_invite_send(p2p, p2p->invite_peer, p2p->invite_go_dev_addr); 1787b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru} 1788b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1789b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1790b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Querustatic void p2p_add_dev_from_probe_req(struct p2p_data *p2p, const u8 *addr, 1791b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru const u8 *ie, size_t ie_len) 1792b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru{ 1793b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru struct p2p_message msg; 1794b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru struct p2p_device *dev; 1795b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1796b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru os_memset(&msg, 0, sizeof(msg)); 1797b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (p2p_parse_ies(ie, ie_len, &msg) < 0 || msg.p2p_attributes == NULL) 1798b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru { 1799b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru p2p_parse_free(&msg); 1800b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return; /* not a P2P probe */ 1801b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1802b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1803b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (msg.ssid == NULL || msg.ssid[1] != P2P_WILDCARD_SSID_LEN || 1804b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru os_memcmp(msg.ssid + 2, P2P_WILDCARD_SSID, P2P_WILDCARD_SSID_LEN) 1805b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru != 0) { 1806b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru /* The Probe Request is not part of P2P Device Discovery. It is 1807b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * not known whether the source address of the frame is the P2P 1808b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * Device Address or P2P Interface Address. Do not add a new 1809b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * peer entry based on this frames. 1810b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru */ 1811b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru p2p_parse_free(&msg); 1812b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return; 1813b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1814b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1815b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru dev = p2p_get_device(p2p, addr); 1816b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (dev) { 1817b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (dev->country[0] == 0 && msg.listen_channel) 1818b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru os_memcpy(dev->country, msg.listen_channel, 3); 1819b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru os_get_reltime(&dev->last_seen); 1820b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru p2p_parse_free(&msg); 1821b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return; /* already known */ 1822b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru } 1823b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru 1824b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru dev = p2p_create_device(p2p, addr); 1825b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru if (dev == NULL) { 1826b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru p2p_parse_free(&msg); 1827b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return; 1828b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1829b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1830b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru os_get_reltime(&dev->last_seen); 1831b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru dev->flags |= P2P_DEV_PROBE_REQ_ONLY; 1832b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1833b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (msg.listen_channel) { 1834b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru os_memcpy(dev->country, msg.listen_channel, 3); 1835b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru dev->listen_freq = p2p_channel_to_freq(msg.listen_channel[3], 1836b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru msg.listen_channel[4]); 1837b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1838b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1839b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru p2p_copy_wps_info(p2p, dev, 1, &msg); 1840b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1841b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (msg.wfd_subelems) { 1842b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru wpabuf_free(dev->info.wfd_subelems); 1843b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru dev->info.wfd_subelems = wpabuf_dup(msg.wfd_subelems); 1844b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1845b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1846b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru p2p_parse_free(&msg); 1847b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1848b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru p2p_dbg(p2p, "Created device entry based on Probe Req: " MACSTR 1849b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru " dev_capab=0x%x group_capab=0x%x name='%s' listen_freq=%d", 1850b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru MAC2STR(dev->info.p2p_device_addr), dev->info.dev_capab, 1851b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru dev->info.group_capab, dev->info.device_name, 1852b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru dev->listen_freq); 1853b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru} 1854b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1855b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1856b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Querustruct p2p_device * p2p_add_dev_from_go_neg_req(struct p2p_data *p2p, 1857b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru const u8 *addr, 1858b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru struct p2p_message *msg) 1859b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru{ 1860b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru struct p2p_device *dev; 1861b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1862b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru dev = p2p_get_device(p2p, addr); 1863b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (dev) { 1864b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru os_get_reltime(&dev->last_seen); 1865b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return dev; /* already known */ 1866b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1867b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1868b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru dev = p2p_create_device(p2p, addr); 1869b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (dev == NULL) 1870b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return NULL; 1871b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1872b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru p2p_add_dev_info(p2p, addr, dev, msg); 1873b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1874b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return dev; 1875b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru} 1876b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1877b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1878b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Querustatic int dev_type_match(const u8 *dev_type, const u8 *req_dev_type) 1879b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru{ 1880b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (os_memcmp(dev_type, req_dev_type, WPS_DEV_TYPE_LEN) == 0) 1881b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return 1; 1882b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (os_memcmp(dev_type, req_dev_type, 2) == 0 && 1883b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru WPA_GET_BE32(&req_dev_type[2]) == 0 && 1884b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru WPA_GET_BE16(&req_dev_type[6]) == 0) 1885b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return 1; /* Category match with wildcard OUI/sub-category */ 1886b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return 0; 1887b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru} 1888b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1889b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1890b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queruint dev_type_list_match(const u8 *dev_type, const u8 *req_dev_type[], 1891b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru size_t num_req_dev_type) 1892b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru{ 1893b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru size_t i; 1894b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru for (i = 0; i < num_req_dev_type; i++) { 1895b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (dev_type_match(dev_type, req_dev_type[i])) 1896b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return 1; 1897b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1898b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return 0; 1899b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru} 1900b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1901b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1902b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru/** 1903b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * p2p_match_dev_type - Match local device type with requested type 1904b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * @p2p: P2P module context from p2p_init() 1905b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * @wps: WPS TLVs from Probe Request frame (concatenated WPS IEs) 1906b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * Returns: 1 on match, 0 on mismatch 1907b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * 1908b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * This function can be used to match the Requested Device Type attribute in 1909b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * WPS IE with the local device types for deciding whether to reply to a Probe 1910b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * Request frame. 1911b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru */ 1912b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queruint p2p_match_dev_type(struct p2p_data *p2p, struct wpabuf *wps) 1913b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru{ 1914b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru struct wps_parse_attr attr; 1915b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru size_t i; 1916b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1917b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (wps_parse_msg(wps, &attr)) 1918b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return 1; /* assume no Requested Device Type attributes */ 1919b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1920b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (attr.num_req_dev_type == 0) 1921b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return 1; /* no Requested Device Type attributes -> match */ 1922b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1923b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (dev_type_list_match(p2p->cfg->pri_dev_type, attr.req_dev_type, 1924b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru attr.num_req_dev_type)) 1925b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return 1; /* Own Primary Device Type matches */ 1926b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1927b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru for (i = 0; i < p2p->cfg->num_sec_dev_types; i++) 1928b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (dev_type_list_match(p2p->cfg->sec_dev_type[i], 1929b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru attr.req_dev_type, 1930b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru attr.num_req_dev_type)) 1931b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return 1; /* Own Secondary Device Type matches */ 1932b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1933b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru /* No matching device type found */ 1934b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return 0; 1935b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru} 1936b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1937b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1938b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Querustruct wpabuf * p2p_build_probe_resp_ies(struct p2p_data *p2p) 1939b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru{ 1940b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru struct wpabuf *buf; 1941b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru u8 *len; 1942b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru int pw_id = -1; 1943b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru size_t extra = 0; 1944b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1945b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#ifdef CONFIG_WIFI_DISPLAY 1946b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (p2p->wfd_ie_probe_resp) 1947b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru extra = wpabuf_len(p2p->wfd_ie_probe_resp); 1948b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#endif /* CONFIG_WIFI_DISPLAY */ 1949b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1950b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru buf = wpabuf_alloc(1000 + extra); 1951b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (buf == NULL) 1952b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return NULL; 1953b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1954b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (p2p->go_neg_peer) { 1955b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru /* Advertise immediate availability of WPS credential */ 1956b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru pw_id = p2p_wps_method_pw_id(p2p->go_neg_peer->wps_method); 1957b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1958b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1959b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (p2p_build_wps_ie(p2p, buf, pw_id, 1) < 0) { 1960b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru p2p_dbg(p2p, "Failed to build WPS IE for Probe Response"); 1961b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru wpabuf_free(buf); 1962b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return NULL; 1963b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1964b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1965b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#ifdef CONFIG_WIFI_DISPLAY 1966b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (p2p->wfd_ie_probe_resp) 1967b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru wpabuf_put_buf(buf, p2p->wfd_ie_probe_resp); 1968b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#endif /* CONFIG_WIFI_DISPLAY */ 1969b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1970b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru /* P2P IE */ 1971b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru len = p2p_buf_add_ie_hdr(buf); 1972b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru p2p_buf_add_capability(buf, p2p->dev_capab & 1973b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru ~P2P_DEV_CAPAB_CLIENT_DISCOVERABILITY, 0); 1974b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (p2p->ext_listen_interval) 1975b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru p2p_buf_add_ext_listen_timing(buf, p2p->ext_listen_period, 1976b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru p2p->ext_listen_interval); 1977b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru p2p_buf_add_device_info(buf, p2p, NULL); 1978b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru p2p_buf_update_ie_hdr(buf, len); 1979b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1980b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return buf; 1981b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru} 1982b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1983b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1984b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Querustatic enum p2p_probe_req_status 1985b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Querup2p_reply_probe(struct p2p_data *p2p, const u8 *addr, const u8 *dst, 1986b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru const u8 *bssid, const u8 *ie, size_t ie_len) 1987b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru{ 1988b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru struct ieee802_11_elems elems; 1989b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru struct wpabuf *buf; 1990b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru struct ieee80211_mgmt *resp; 1991b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru struct p2p_message msg; 1992b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru struct wpabuf *ies; 1993b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1994b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (!p2p->in_listen || !p2p->drv_in_listen) { 1995b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru /* not in Listen state - ignore Probe Request */ 1996b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return P2P_PREQ_NOT_LISTEN; 1997b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1998b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1999b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (ieee802_11_parse_elems((u8 *) ie, ie_len, &elems, 0) == 2000b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru ParseFailed) { 2001b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru /* Ignore invalid Probe Request frames */ 2002b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return P2P_PREQ_MALFORMED; 2003b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 2004b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 2005b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (elems.p2p == NULL) { 2006b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru /* not a P2P probe - ignore it */ 2007b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return P2P_PREQ_NOT_P2P; 2008b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 2009b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 2010b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (dst && !is_broadcast_ether_addr(dst) && 2011b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru os_memcmp(dst, p2p->cfg->dev_addr, ETH_ALEN) != 0) { 2012b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru /* Not sent to the broadcast address or our P2P Device Address 2013b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru */ 2014b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return P2P_PREQ_NOT_PROCESSED; 2015b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 2016b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 2017b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (bssid && !is_broadcast_ether_addr(bssid)) { 2018b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru /* Not sent to the Wildcard BSSID */ 2019b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return P2P_PREQ_NOT_PROCESSED; 2020b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 2021b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 2022b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (elems.ssid == NULL || elems.ssid_len != P2P_WILDCARD_SSID_LEN || 2023b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru os_memcmp(elems.ssid, P2P_WILDCARD_SSID, P2P_WILDCARD_SSID_LEN) != 2024b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 0) { 2025b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru /* not using P2P Wildcard SSID - ignore */ 2026b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return P2P_PREQ_NOT_PROCESSED; 2027b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 2028b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 2029b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (supp_rates_11b_only(&elems)) { 2030b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru /* Indicates support for 11b rates only */ 2031b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return P2P_PREQ_NOT_P2P; 2032b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 2033b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 2034b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru os_memset(&msg, 0, sizeof(msg)); 2035b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (p2p_parse_ies(ie, ie_len, &msg) < 0) { 2036b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru /* Could not parse P2P attributes */ 2037b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return P2P_PREQ_NOT_P2P; 2038b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 2039b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 2040b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (msg.device_id && 2041b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru os_memcmp(msg.device_id, p2p->cfg->dev_addr, ETH_ALEN) != 0) { 2042b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru /* Device ID did not match */ 2043b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru p2p_parse_free(&msg); 2044b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return P2P_PREQ_NOT_PROCESSED; 2045b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 2046b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 2047b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru /* Check Requested Device Type match */ 2048b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (msg.wps_attributes && 2049b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru !p2p_match_dev_type(p2p, msg.wps_attributes)) { 2050b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru /* No match with Requested Device Type */ 2051b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru p2p_parse_free(&msg); 2052b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return P2P_PREQ_NOT_PROCESSED; 2053b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 2054b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru p2p_parse_free(&msg); 2055b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 2056b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (!p2p->cfg->send_probe_resp) { 2057b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru /* Response generated elsewhere */ 2058b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return P2P_PREQ_NOT_PROCESSED; 2059b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 2060b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 2061b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru p2p_dbg(p2p, "Reply to P2P Probe Request in Listen state"); 2062b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 2063b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru /* 2064b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * We do not really have a specific BSS that this frame is advertising, 2065b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * so build a frame that has some information in valid format. This is 2066b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * really only used for discovery purposes, not to learn exact BSS 2067b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * parameters. 2068b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru */ 2069b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru ies = p2p_build_probe_resp_ies(p2p); 2070b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (ies == NULL) 2071b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return P2P_PREQ_NOT_PROCESSED; 2072b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 2073b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru buf = wpabuf_alloc(200 + wpabuf_len(ies)); 2074b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (buf == NULL) { 2075b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru wpabuf_free(ies); 2076b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return P2P_PREQ_NOT_PROCESSED; 2077b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 2078b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 2079b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru resp = NULL; 2080b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru resp = wpabuf_put(buf, resp->u.probe_resp.variable - (u8 *) resp); 2081b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 2082b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru resp->frame_control = host_to_le16((WLAN_FC_TYPE_MGMT << 2) | 2083b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru (WLAN_FC_STYPE_PROBE_RESP << 4)); 2084b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru os_memcpy(resp->da, addr, ETH_ALEN); 2085b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru os_memcpy(resp->sa, p2p->cfg->dev_addr, ETH_ALEN); 2086b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru os_memcpy(resp->bssid, p2p->cfg->dev_addr, ETH_ALEN); 2087b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru resp->u.probe_resp.beacon_int = host_to_le16(100); 2088b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru /* hardware or low-level driver will setup seq_ctrl and timestamp */ 2089b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru resp->u.probe_resp.capab_info = 2090b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru host_to_le16(WLAN_CAPABILITY_SHORT_PREAMBLE | 2091b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru WLAN_CAPABILITY_PRIVACY | 2092b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru WLAN_CAPABILITY_SHORT_SLOT_TIME); 2093b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 2094b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru wpabuf_put_u8(buf, WLAN_EID_SSID); 2095b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru wpabuf_put_u8(buf, P2P_WILDCARD_SSID_LEN); 2096b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru wpabuf_put_data(buf, P2P_WILDCARD_SSID, P2P_WILDCARD_SSID_LEN); 2097b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 2098b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru wpabuf_put_u8(buf, WLAN_EID_SUPP_RATES); 2099b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru wpabuf_put_u8(buf, 8); 2100b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru wpabuf_put_u8(buf, (60 / 5) | 0x80); 2101b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru wpabuf_put_u8(buf, 90 / 5); 2102b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru wpabuf_put_u8(buf, (120 / 5) | 0x80); 2103b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru wpabuf_put_u8(buf, 180 / 5); 2104b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru wpabuf_put_u8(buf, (240 / 5) | 0x80); 2105b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru wpabuf_put_u8(buf, 360 / 5); 2106b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru wpabuf_put_u8(buf, 480 / 5); 2107b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru wpabuf_put_u8(buf, 540 / 5); 2108b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 2109b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru wpabuf_put_u8(buf, WLAN_EID_DS_PARAMS); 2110b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru wpabuf_put_u8(buf, 1); 2111b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru wpabuf_put_u8(buf, p2p->cfg->channel); 2112b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 2113b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru wpabuf_put_buf(buf, ies); 2114b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru wpabuf_free(ies); 2115b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 2116b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru p2p->cfg->send_probe_resp(p2p->cfg->cb_ctx, buf); 2117b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 2118b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru wpabuf_free(buf); 2119b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru 2120b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru return P2P_PREQ_NOT_PROCESSED; 2121b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru} 2122b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 2123b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 2124b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queruenum p2p_probe_req_status 2125b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Querup2p_probe_req_rx(struct p2p_data *p2p, const u8 *addr, const u8 *dst, 2126b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru const u8 *bssid, const u8 *ie, size_t ie_len) 2127b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru{ 2128b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru enum p2p_probe_req_status res; 2129b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 2130b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru p2p_add_dev_from_probe_req(p2p, addr, ie, ie_len); 2131b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 2132b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru res = p2p_reply_probe(p2p, addr, dst, bssid, ie, ie_len); 2133b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 2134b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if ((p2p->state == P2P_CONNECT || p2p->state == P2P_CONNECT_LISTEN) && 2135b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru p2p->go_neg_peer && 2136b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru os_memcmp(addr, p2p->go_neg_peer->info.p2p_device_addr, ETH_ALEN) 2137b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru == 0 && 2138b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru !(p2p->go_neg_peer->flags & P2P_DEV_WAIT_GO_NEG_CONFIRM)) { 2139b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru /* Received a Probe Request from GO Negotiation peer */ 2140b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru p2p_dbg(p2p, "Found GO Negotiation peer - try to start GO negotiation from timeout"); 2141b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru eloop_cancel_timeout(p2p_go_neg_start, p2p, NULL); 2142b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru eloop_register_timeout(0, 0, p2p_go_neg_start, p2p, NULL); 2143b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return P2P_PREQ_PROCESSED; 2144b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 2145b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 2146b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if ((p2p->state == P2P_INVITE || p2p->state == P2P_INVITE_LISTEN) && 2147b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru p2p->invite_peer && 2148b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru os_memcmp(addr, p2p->invite_peer->info.p2p_device_addr, ETH_ALEN) 2149b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru == 0) { 2150b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru /* Received a Probe Request from Invite peer */ 2151b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru p2p_dbg(p2p, "Found Invite peer - try to start Invite from timeout"); 2152b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru eloop_register_timeout(0, 0, p2p_invite_start, p2p, NULL); 2153b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return P2P_PREQ_PROCESSED; 2154b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 2155b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 2156b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return res; 2157b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru} 2158b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 2159b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 2160b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Querustatic int p2p_assoc_req_ie_wlan_ap(struct p2p_data *p2p, const u8 *bssid, 2161b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru u8 *buf, size_t len, struct wpabuf *p2p_ie) 2162b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru{ 2163b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru struct wpabuf *tmp; 2164b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru u8 *lpos; 2165b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru size_t tmplen; 2166b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru int res; 2167b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru u8 group_capab; 2168b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru 2169b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (p2p_ie == NULL) 2170b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return 0; /* WLAN AP is not a P2P manager */ 2171b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 2172b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru /* 2173b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * (Re)Association Request - P2P IE 2174b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * P2P Capability attribute (shall be present) 2175b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * P2P Interface attribute (present if concurrent device and 2176b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * P2P Management is enabled) 2177b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru */ 2178b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru tmp = wpabuf_alloc(200); 2179b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (tmp == NULL) 2180b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return -1; 2181b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru 2182b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru lpos = p2p_buf_add_ie_hdr(tmp); 2183b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru group_capab = 0; 2184b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru if (p2p->num_groups > 0) { 2185b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru group_capab |= P2P_GROUP_CAPAB_GROUP_OWNER; 2186b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if ((p2p->dev_capab & P2P_DEV_CAPAB_CONCURRENT_OPER) && 2187b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru (p2p->dev_capab & P2P_DEV_CAPAB_INFRA_MANAGED) && 2188b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru p2p->cross_connect) 2189b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru group_capab |= P2P_GROUP_CAPAB_CROSS_CONN; 2190b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 2191b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru p2p_buf_add_capability(tmp, p2p->dev_capab, group_capab); 2192b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if ((p2p->dev_capab & P2P_DEV_CAPAB_CONCURRENT_OPER) && 2193b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru (p2p->dev_capab & P2P_DEV_CAPAB_INFRA_MANAGED)) 2194b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru p2p_buf_add_p2p_interface(tmp, p2p); 2195b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru p2p_buf_update_ie_hdr(tmp, lpos); 2196b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 2197b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru tmplen = wpabuf_len(tmp); 2198b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (tmplen > len) 2199b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru res = -1; 2200b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru else { 2201b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru os_memcpy(buf, wpabuf_head(tmp), tmplen); 2202b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru res = tmplen; 2203b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru } 2204b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru wpabuf_free(tmp); 2205b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru 2206b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru return res; 2207b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru} 2208b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru 2209b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru 2210b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queruint p2p_assoc_req_ie(struct p2p_data *p2p, const u8 *bssid, u8 *buf, 2211b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru size_t len, int p2p_group, struct wpabuf *p2p_ie) 22128393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius{ 22138393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius struct wpabuf *tmp; 22148393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius u8 *lpos; 2215b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru struct p2p_device *peer; 2216b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru size_t tmplen; 22178393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius int res; 2218b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru size_t extra = 0; 2219b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru 2220b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru if (!p2p_group) 2221b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru return p2p_assoc_req_ie_wlan_ap(p2p, bssid, buf, len, p2p_ie); 2222b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru 22238393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius#ifdef CONFIG_WIFI_DISPLAY 22248393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius if (p2p->wfd_ie_assoc_req) 222559d709d503bab6e2b61931737e662dd293b40578ccornelius extra = wpabuf_len(p2p->wfd_ie_assoc_req); 222659d709d503bab6e2b61931737e662dd293b40578ccornelius#endif /* CONFIG_WIFI_DISPLAY */ 222759d709d503bab6e2b61931737e662dd293b40578ccornelius 222859d709d503bab6e2b61931737e662dd293b40578ccornelius /* 222959d709d503bab6e2b61931737e662dd293b40578ccornelius * (Re)Association Request - P2P IE 223059d709d503bab6e2b61931737e662dd293b40578ccornelius * P2P Capability attribute (shall be present) 223159d709d503bab6e2b61931737e662dd293b40578ccornelius * Extended Listen Timing (may be present) 223259d709d503bab6e2b61931737e662dd293b40578ccornelius * P2P Device Info attribute (shall be present) 22338393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius */ 223459d709d503bab6e2b61931737e662dd293b40578ccornelius tmp = wpabuf_alloc(200 + extra); 223559d709d503bab6e2b61931737e662dd293b40578ccornelius if (tmp == NULL) 223659d709d503bab6e2b61931737e662dd293b40578ccornelius return -1; 223759d709d503bab6e2b61931737e662dd293b40578ccornelius 223859d709d503bab6e2b61931737e662dd293b40578ccornelius#ifdef CONFIG_WIFI_DISPLAY 223959d709d503bab6e2b61931737e662dd293b40578ccornelius if (p2p->wfd_ie_assoc_req) 224059d709d503bab6e2b61931737e662dd293b40578ccornelius wpabuf_put_buf(tmp, p2p->wfd_ie_assoc_req); 224159d709d503bab6e2b61931737e662dd293b40578ccornelius#endif /* CONFIG_WIFI_DISPLAY */ 224259d709d503bab6e2b61931737e662dd293b40578ccornelius 224359d709d503bab6e2b61931737e662dd293b40578ccornelius peer = bssid ? p2p_get_device(p2p, bssid) : NULL; 224459d709d503bab6e2b61931737e662dd293b40578ccornelius 224559d709d503bab6e2b61931737e662dd293b40578ccornelius lpos = p2p_buf_add_ie_hdr(tmp); 224659d709d503bab6e2b61931737e662dd293b40578ccornelius p2p_buf_add_capability(tmp, p2p->dev_capab, 0); 224759d709d503bab6e2b61931737e662dd293b40578ccornelius if (p2p->ext_listen_interval) 224859d709d503bab6e2b61931737e662dd293b40578ccornelius p2p_buf_add_ext_listen_timing(tmp, p2p->ext_listen_period, 224959d709d503bab6e2b61931737e662dd293b40578ccornelius p2p->ext_listen_interval); 225059d709d503bab6e2b61931737e662dd293b40578ccornelius p2p_buf_add_device_info(tmp, p2p, peer); 225159d709d503bab6e2b61931737e662dd293b40578ccornelius p2p_buf_update_ie_hdr(tmp, lpos); 225259d709d503bab6e2b61931737e662dd293b40578ccornelius 225359d709d503bab6e2b61931737e662dd293b40578ccornelius tmplen = wpabuf_len(tmp); 225459d709d503bab6e2b61931737e662dd293b40578ccornelius if (tmplen > len) 225559d709d503bab6e2b61931737e662dd293b40578ccornelius res = -1; 225659d709d503bab6e2b61931737e662dd293b40578ccornelius else { 225759d709d503bab6e2b61931737e662dd293b40578ccornelius os_memcpy(buf, wpabuf_head(tmp), tmplen); 2258b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru res = tmplen; 2259b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru } 2260b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru wpabuf_free(tmp); 226159d709d503bab6e2b61931737e662dd293b40578ccornelius 226259d709d503bab6e2b61931737e662dd293b40578ccornelius return res; 2263b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru} 226459d709d503bab6e2b61931737e662dd293b40578ccornelius 2265b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru 226659d709d503bab6e2b61931737e662dd293b40578ccorneliusint p2p_scan_result_text(const u8 *ies, size_t ies_len, char *buf, char *end) 226759d709d503bab6e2b61931737e662dd293b40578ccornelius{ 226859d709d503bab6e2b61931737e662dd293b40578ccornelius struct wpabuf *p2p_ie; 226959d709d503bab6e2b61931737e662dd293b40578ccornelius int ret; 227059d709d503bab6e2b61931737e662dd293b40578ccornelius 227159d709d503bab6e2b61931737e662dd293b40578ccornelius p2p_ie = ieee802_11_vendor_ie_concat(ies, ies_len, P2P_IE_VENDOR_TYPE); 227259d709d503bab6e2b61931737e662dd293b40578ccornelius if (p2p_ie == NULL) 227359d709d503bab6e2b61931737e662dd293b40578ccornelius return 0; 227459d709d503bab6e2b61931737e662dd293b40578ccornelius 227559d709d503bab6e2b61931737e662dd293b40578ccornelius ret = p2p_attr_text(p2p_ie, buf, end); 227659d709d503bab6e2b61931737e662dd293b40578ccornelius wpabuf_free(p2p_ie); 227759d709d503bab6e2b61931737e662dd293b40578ccornelius return ret; 227859d709d503bab6e2b61931737e662dd293b40578ccornelius} 227959d709d503bab6e2b61931737e662dd293b40578ccornelius 228059d709d503bab6e2b61931737e662dd293b40578ccornelius 228159d709d503bab6e2b61931737e662dd293b40578ccorneliusint p2p_parse_dev_addr_in_p2p_ie(struct wpabuf *p2p_ie, u8 *dev_addr) 2282b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru{ 2283b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru struct p2p_message msg; 2284b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru 2285b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru os_memset(&msg, 0, sizeof(msg)); 2286b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (p2p_parse_p2p_ie(p2p_ie, &msg)) 2287b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return -1; 2288b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 2289b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (msg.p2p_device_addr) { 2290b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru os_memcpy(dev_addr, msg.p2p_device_addr, ETH_ALEN); 2291b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return 0; 2292b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } else if (msg.device_id) { 2293b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru os_memcpy(dev_addr, msg.device_id, ETH_ALEN); 2294b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru return 0; 2295b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 2296b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return -1; 2297b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru} 2298b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 2299b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 2300b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queruint p2p_parse_dev_addr(const u8 *ies, size_t ies_len, u8 *dev_addr) 2301b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru{ 2302b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru struct wpabuf *p2p_ie; 2303b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru int ret; 2304b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 2305b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru p2p_ie = ieee802_11_vendor_ie_concat(ies, ies_len, 2306b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru P2P_IE_VENDOR_TYPE); 2307b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (p2p_ie == NULL) 2308b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return -1; 2309b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru ret = p2p_parse_dev_addr_in_p2p_ie(p2p_ie, dev_addr); 2310b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru wpabuf_free(p2p_ie); 2311b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return ret; 2312b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru} 2313b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 2314b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 2315b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Querustatic void p2p_clear_go_neg(struct p2p_data *p2p) 2316b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru{ 2317b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru p2p->go_neg_peer = NULL; 2318b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru p2p_clear_timeout(p2p); 2319b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru p2p_set_state(p2p, P2P_IDLE); 2320b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru} 2321b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 2322b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 2323b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queruvoid p2p_wps_success_cb(struct p2p_data *p2p, const u8 *mac_addr) 2324b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru{ 2325b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (p2p->go_neg_peer == NULL) { 2326b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru p2p_dbg(p2p, "No pending Group Formation - ignore WPS registration success notification"); 2327b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return; /* No pending Group Formation */ 2328b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 2329b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 2330b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (os_memcmp(mac_addr, p2p->go_neg_peer->intended_addr, ETH_ALEN) != 2331b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 0) { 2332b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru p2p_dbg(p2p, "Ignore WPS registration success notification for " 2333b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru MACSTR " (GO Negotiation peer " MACSTR ")", 2334b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru MAC2STR(mac_addr), 2335b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru MAC2STR(p2p->go_neg_peer->intended_addr)); 2336b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return; /* Ignore unexpected peer address */ 2337b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 2338b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 2339b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru p2p_dbg(p2p, "Group Formation completed successfully with " MACSTR, 2340b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru MAC2STR(mac_addr)); 2341b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 2342b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru p2p_clear_go_neg(p2p); 2343b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru} 2344b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 2345b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 2346b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queruvoid p2p_group_formation_failed(struct p2p_data *p2p) 2347b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru{ 2348b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (p2p->go_neg_peer == NULL) { 2349b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru p2p_dbg(p2p, "No pending Group Formation - ignore group formation failure notification"); 2350b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return; /* No pending Group Formation */ 2351b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 2352b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 2353b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru p2p_dbg(p2p, "Group Formation failed with " MACSTR, 2354b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru MAC2STR(p2p->go_neg_peer->intended_addr)); 2355b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 2356b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru p2p_clear_go_neg(p2p); 2357b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru} 2358b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 2359b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 2360b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Querustruct p2p_data * p2p_init(const struct p2p_config *cfg) 2361b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru{ 2362b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru struct p2p_data *p2p; 2363b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 2364b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (cfg->max_peers < 1) 2365b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return NULL; 2366b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 2367b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru p2p = os_zalloc(sizeof(*p2p) + sizeof(*cfg)); 2368b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (p2p == NULL) 2369b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return NULL; 2370b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru p2p->cfg = (struct p2p_config *) (p2p + 1); 2371b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru os_memcpy(p2p->cfg, cfg, sizeof(*cfg)); 2372b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (cfg->dev_name) 2373b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru p2p->cfg->dev_name = os_strdup(cfg->dev_name); 2374b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (cfg->manufacturer) 2375b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru p2p->cfg->manufacturer = os_strdup(cfg->manufacturer); 2376b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (cfg->model_name) 2377b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru p2p->cfg->model_name = os_strdup(cfg->model_name); 2378b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (cfg->model_number) 2379b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru p2p->cfg->model_number = os_strdup(cfg->model_number); 2380b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (cfg->serial_number) 2381b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru p2p->cfg->serial_number = os_strdup(cfg->serial_number); 2382b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (cfg->pref_chan) { 2383b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru p2p->cfg->pref_chan = os_malloc(cfg->num_pref_chan * 2384b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru sizeof(struct p2p_channel)); 2385b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (p2p->cfg->pref_chan) { 2386b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru os_memcpy(p2p->cfg->pref_chan, cfg->pref_chan, 2387b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru cfg->num_pref_chan * 2388b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru sizeof(struct p2p_channel)); 2389b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } else 2390b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru p2p->cfg->num_pref_chan = 0; 2391b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 2392b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 2393b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#ifdef ANDROID_P2P 2394b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru /* 100ms listen time is too less to receive the response frames in some scenarios 2395b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru * increasing min listen time to 200ms. 2396b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru */ 2397b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru p2p->min_disc_int = 2; 2398b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru#else 2399b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru p2p->min_disc_int = 1; 2400b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru#endif 2401b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru p2p->max_disc_int = 3; 240259d709d503bab6e2b61931737e662dd293b40578ccornelius p2p->max_disc_tu = -1; 240359d709d503bab6e2b61931737e662dd293b40578ccornelius 240459d709d503bab6e2b61931737e662dd293b40578ccornelius os_get_random(&p2p->next_tie_breaker, 1); 240559d709d503bab6e2b61931737e662dd293b40578ccornelius p2p->next_tie_breaker &= 0x01; 240659d709d503bab6e2b61931737e662dd293b40578ccornelius if (cfg->sd_request) 240759d709d503bab6e2b61931737e662dd293b40578ccornelius p2p->dev_capab |= P2P_DEV_CAPAB_SERVICE_DISCOVERY; 2408b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru p2p->dev_capab |= P2P_DEV_CAPAB_INVITATION_PROCEDURE; 2409b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru if (cfg->concurrent_operations) 241050294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho p2p->dev_capab |= P2P_DEV_CAPAB_CONCURRENT_OPER; 2411b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru p2p->dev_capab |= P2P_DEV_CAPAB_CLIENT_DISCOVERABILITY; 2412b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru 2413b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru dl_list_init(&p2p->devices); 2414b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 2415b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru eloop_register_timeout(P2P_PEER_EXPIRATION_INTERVAL, 0, 2416b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru p2p_expiration_timeout, p2p, NULL); 2417b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 2418b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru p2p->go_timeout = 100; 2419b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru p2p->client_timeout = 20; 2420b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 2421b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru p2p_dbg(p2p, "initialized"); 2422b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru p2p_channels_dump(p2p, "channels", &p2p->cfg->channels); 2423b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru p2p_channels_dump(p2p, "cli_channels", &p2p->cfg->cli_channels); 2424b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 2425b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return p2p; 2426b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru} 2427b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 2428b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 2429b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queruvoid p2p_deinit(struct p2p_data *p2p) 2430b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru{ 2431b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#ifdef CONFIG_WIFI_DISPLAY 2432b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru wpabuf_free(p2p->wfd_ie_beacon); 2433b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru wpabuf_free(p2p->wfd_ie_probe_req); 2434b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru wpabuf_free(p2p->wfd_ie_probe_resp); 2435b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru wpabuf_free(p2p->wfd_ie_assoc_req); 2436b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru wpabuf_free(p2p->wfd_ie_invitation); 2437b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru wpabuf_free(p2p->wfd_ie_prov_disc_req); 2438b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru wpabuf_free(p2p->wfd_ie_prov_disc_resp); 2439b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru wpabuf_free(p2p->wfd_ie_go_neg); 2440b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru wpabuf_free(p2p->wfd_dev_info); 2441b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru wpabuf_free(p2p->wfd_assoc_bssid); 2442b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru wpabuf_free(p2p->wfd_coupled_sink_info); 2443b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru#endif /* CONFIG_WIFI_DISPLAY */ 2444b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru 2445b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru eloop_cancel_timeout(p2p_expiration_timeout, p2p, NULL); 2446b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru eloop_cancel_timeout(p2p_ext_listen_timeout, p2p, NULL); 2447b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru eloop_cancel_timeout(p2p_scan_timeout, p2p, NULL); 2448b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru eloop_cancel_timeout(p2p_go_neg_start, p2p, NULL); 2449b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru p2p_flush(p2p); 2450b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru p2p_free_req_dev_types(p2p); 2451b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru os_free(p2p->cfg->dev_name); 2452b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru os_free(p2p->cfg->manufacturer); 2453b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru os_free(p2p->cfg->model_name); 2454b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru os_free(p2p->cfg->model_number); 2455b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru os_free(p2p->cfg->serial_number); 2456b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru os_free(p2p->cfg->pref_chan); 2457b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru os_free(p2p->groups); 2458b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru wpabuf_free(p2p->sd_resp); 2459b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru os_free(p2p->after_scan_tx); 2460b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru p2p_remove_wps_vendor_extensions(p2p); 2461b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru os_free(p2p->no_go_freq.range); 2462b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru os_free(p2p); 2463b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru} 2464b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 2465b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 2466b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queruvoid p2p_flush(struct p2p_data *p2p) 2467b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru{ 2468b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru struct p2p_device *dev, *prev; 2469b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru p2p_stop_find(p2p); 2470b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru dl_list_for_each_safe(dev, prev, &p2p->devices, struct p2p_device, 2471b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru list) { 2472b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru dl_list_del(&dev->list); 2473b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru p2p_device_free(p2p, dev); 2474b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 2475b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru p2p_free_sd_queries(p2p); 2476b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru os_free(p2p->after_scan_tx); 2477b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru p2p->after_scan_tx = NULL; 2478b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru} 2479b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 2480b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 2481b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queruint p2p_unauthorize(struct p2p_data *p2p, const u8 *addr) 2482b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru{ 2483b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru struct p2p_device *dev; 2484b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 2485b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru dev = p2p_get_device(p2p, addr); 2486b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (dev == NULL) 2487b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return -1; 2488b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 2489b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru p2p_dbg(p2p, "Unauthorizing " MACSTR, MAC2STR(addr)); 2490b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 2491b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (p2p->go_neg_peer == dev) 2492b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru p2p->go_neg_peer = NULL; 2493b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 2494b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru dev->wps_method = WPS_NOT_READY; 2495b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru dev->flags &= ~P2P_DEV_WAIT_GO_NEG_RESPONSE; 2496b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru dev->flags &= ~P2P_DEV_WAIT_GO_NEG_CONFIRM; 2497b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 2498b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru /* Check if after_scan_tx is for this peer. If so free it */ 2499b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (p2p->after_scan_tx && 2500b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru os_memcmp(addr, p2p->after_scan_tx->dst, ETH_ALEN) == 0) { 2501b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru os_free(p2p->after_scan_tx); 2502b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru p2p->after_scan_tx = NULL; 2503b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 2504b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 2505b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return 0; 2506b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru} 2507b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 2508b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 2509b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queruint p2p_set_dev_name(struct p2p_data *p2p, const char *dev_name) 2510b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru{ 2511b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru os_free(p2p->cfg->dev_name); 2512b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (dev_name) { 2513b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru p2p->cfg->dev_name = os_strdup(dev_name); 2514b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (p2p->cfg->dev_name == NULL) 2515b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return -1; 2516b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } else 2517b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru p2p->cfg->dev_name = NULL; 2518b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return 0; 2519b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru} 2520b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 2521b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 2522b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queruint p2p_set_manufacturer(struct p2p_data *p2p, const char *manufacturer) 2523b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru{ 2524b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru os_free(p2p->cfg->manufacturer); 2525b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru p2p->cfg->manufacturer = NULL; 2526b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (manufacturer) { 2527b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru p2p->cfg->manufacturer = os_strdup(manufacturer); 2528b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (p2p->cfg->manufacturer == NULL) 2529b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return -1; 2530b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 2531b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 2532b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return 0; 2533b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru} 2534b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 2535b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 2536b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queruint p2p_set_model_name(struct p2p_data *p2p, const char *model_name) 2537b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru{ 2538b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru os_free(p2p->cfg->model_name); 2539b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru p2p->cfg->model_name = NULL; 2540b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru if (model_name) { 2541b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru p2p->cfg->model_name = os_strdup(model_name); 2542b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (p2p->cfg->model_name == NULL) 2543b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru return -1; 2544b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 2545b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 2546b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return 0; 2547b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru} 2548b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 2549b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 2550b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queruint p2p_set_model_number(struct p2p_data *p2p, const char *model_number) 2551b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru{ 2552b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru os_free(p2p->cfg->model_number); 2553b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru p2p->cfg->model_number = NULL; 2554b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (model_number) { 2555b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru p2p->cfg->model_number = os_strdup(model_number); 2556b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (p2p->cfg->model_number == NULL) 2557b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return -1; 2558b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 2559b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 2560b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return 0; 2561b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru} 2562b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 2563b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 2564b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queruint p2p_set_serial_number(struct p2p_data *p2p, const char *serial_number) 2565b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru{ 2566b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru os_free(p2p->cfg->serial_number); 2567b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru p2p->cfg->serial_number = NULL; 2568b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru if (serial_number) { 2569b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru p2p->cfg->serial_number = os_strdup(serial_number); 2570b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru if (p2p->cfg->serial_number == NULL) 2571b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return -1; 2572b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 2573b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru 2574b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru return 0; 2575b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru} 2576b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 2577b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 2578b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queruvoid p2p_set_config_methods(struct p2p_data *p2p, u16 config_methods) 2579b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru{ 2580b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru p2p->cfg->config_methods = config_methods; 2581b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru} 2582b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 2583b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 2584b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queruvoid p2p_set_uuid(struct p2p_data *p2p, const u8 *uuid) 2585b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru{ 2586b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru os_memcpy(p2p->cfg->uuid, uuid, 16); 2587b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru} 2588b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 2589b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 2590b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queruint p2p_set_pri_dev_type(struct p2p_data *p2p, const u8 *pri_dev_type) 2591b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru{ 2592b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru os_memcpy(p2p->cfg->pri_dev_type, pri_dev_type, 8); 2593b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return 0; 2594b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru} 2595b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 2596b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 2597b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queruint p2p_set_sec_dev_types(struct p2p_data *p2p, const u8 dev_types[][8], 2598b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru size_t num_dev_types) 2599b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru{ 2600b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (num_dev_types > P2P_SEC_DEVICE_TYPES) 2601b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru num_dev_types = P2P_SEC_DEVICE_TYPES; 2602b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru p2p->cfg->num_sec_dev_types = num_dev_types; 2603b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru os_memcpy(p2p->cfg->sec_dev_type, dev_types, num_dev_types * 8); 2604b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return 0; 2605b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru} 2606b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 2607b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 2608b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queruvoid p2p_remove_wps_vendor_extensions(struct p2p_data *p2p) 2609b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru{ 2610b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru int i; 2611b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 2612b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru for (i = 0; i < P2P_MAX_WPS_VENDOR_EXT; i++) { 2613b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru wpabuf_free(p2p->wps_vendor_ext[i]); 2614b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru p2p->wps_vendor_ext[i] = NULL; 2615b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 2616b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru} 2617b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 2618b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 2619b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queruint p2p_add_wps_vendor_extension(struct p2p_data *p2p, 2620b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru const struct wpabuf *vendor_ext) 2621b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru{ 2622b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru int i; 2623b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 2624b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (vendor_ext == NULL) 2625b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru return -1; 2626b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 2627b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru for (i = 0; i < P2P_MAX_WPS_VENDOR_EXT; i++) { 2628b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (p2p->wps_vendor_ext[i] == NULL) 2629b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru break; 2630b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 2631b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (i >= P2P_MAX_WPS_VENDOR_EXT) 2632b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return -1; 2633b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 2634b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru p2p->wps_vendor_ext[i] = wpabuf_dup(vendor_ext); 2635b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (p2p->wps_vendor_ext[i] == NULL) 2636b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return -1; 2637b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 2638b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return 0; 2639b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru} 2640b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 2641b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 2642b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queruint p2p_set_country(struct p2p_data *p2p, const char *country) 2643b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru{ 2644b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru os_memcpy(p2p->cfg->country, country, 3); 2645b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return 0; 2646b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru} 2647b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 2648b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 2649b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queruvoid p2p_continue_find(struct p2p_data *p2p) 2650b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru{ 2651b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru struct p2p_device *dev; 2652b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru p2p_set_state(p2p, P2P_SEARCH); 2653b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru dl_list_for_each(dev, &p2p->devices, struct p2p_device, list) { 2654b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (dev->flags & P2P_DEV_SD_SCHEDULE) { 2655b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (p2p_start_sd(p2p, dev) == 0) 2656b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return; 2657b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru else 2658b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru break; 2659b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } else if (dev->req_config_methods && 2660b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru !(dev->flags & P2P_DEV_PD_FOR_JOIN)) { 2661b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru p2p_dbg(p2p, "Send pending Provision Discovery Request to " 2662b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru MACSTR " (config methods 0x%x)", 2663b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru MAC2STR(dev->info.p2p_device_addr), 2664b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru dev->req_config_methods); 2665b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (p2p_send_prov_disc_req(p2p, dev, 0, 0) == 0) 2666b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return; 2667b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 2668b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 2669b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 2670b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru p2p_listen_in_find(p2p, 1); 2671b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru} 2672b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 2673b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 2674b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Querustatic void p2p_sd_cb(struct p2p_data *p2p, int success) 2675b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru{ 2676b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru p2p_dbg(p2p, "Service Discovery Query TX callback: success=%d", 2677b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru success); 2678b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru p2p->pending_action_state = P2P_NO_PENDING_ACTION; 2679b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 2680b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (!success) { 2681b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (p2p->sd_peer) { 2682b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru p2p->sd_peer->flags &= ~P2P_DEV_SD_SCHEDULE; 2683b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru p2p->sd_peer = NULL; 2684b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 2685b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru p2p_continue_find(p2p); 2686b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return; 2687b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 2688b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 2689b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (p2p->sd_peer == NULL) { 2690b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru p2p_dbg(p2p, "No SD peer entry known"); 2691b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru p2p_continue_find(p2p); 2692b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return; 2693b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 2694b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 2695b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru /* Wait for response from the peer */ 2696b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru p2p_set_state(p2p, P2P_SD_DURING_FIND); 2697b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru p2p_set_timeout(p2p, 0, 200000); 2698b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru} 2699b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 2700b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 2701b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru/** 2702b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * p2p_retry_pd - Retry any pending provision disc requests in IDLE state 2703b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * @p2p: P2P module context from p2p_init() 2704b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru */ 2705b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Querustatic void p2p_retry_pd(struct p2p_data *p2p) 2706b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru{ 2707b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru struct p2p_device *dev; 2708b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 2709b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (p2p->state != P2P_IDLE) 2710b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return; 2711b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 2712b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru /* 2713b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * Retry the prov disc req attempt only for the peer that the user had 2714b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * requested. 2715b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru */ 2716b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 2717b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru dl_list_for_each(dev, &p2p->devices, struct p2p_device, list) { 2718b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (os_memcmp(p2p->pending_pd_devaddr, 2719b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru dev->info.p2p_device_addr, ETH_ALEN) != 0) 2720b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru continue; 2721b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (!dev->req_config_methods) 2722b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru continue; 2723b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 2724b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru p2p_dbg(p2p, "Send pending Provision Discovery Request to " 2725b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru MACSTR " (config methods 0x%x)", 2726b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru MAC2STR(dev->info.p2p_device_addr), 2727b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru dev->req_config_methods); 2728b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru p2p_send_prov_disc_req(p2p, dev, 2729b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru dev->flags & P2P_DEV_PD_FOR_JOIN, 2730b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru p2p->pd_force_freq); 2731b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return; 2732b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 2733b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru} 2734b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 2735b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 2736b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Querustatic void p2p_prov_disc_cb(struct p2p_data *p2p, int success) 2737b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru{ 2738b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru p2p_dbg(p2p, "Provision Discovery Request TX callback: success=%d", 2739b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru success); 2740b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 2741b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru /* 2742b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * Postpone resetting the pending action state till after we actually 2743b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * time out. This allows us to take some action like notifying any 2744b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * interested parties about no response to the request. 2745b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * 2746b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * When the timer (below) goes off we check in IDLE, SEARCH, or 2747b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * LISTEN_ONLY state, which are the only allowed states to issue a PD 2748b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * requests in, if this was still pending and then raise notification. 2749b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru */ 2750b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 2751b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (!success) { 2752b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru p2p->pending_action_state = P2P_NO_PENDING_ACTION; 2753b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 2754b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (p2p->user_initiated_pd && 2755b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru (p2p->state == P2P_SEARCH || p2p->state == P2P_LISTEN_ONLY)) 2756b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru { 2757b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru /* Retry request from timeout to avoid busy loops */ 2758b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru p2p->pending_action_state = P2P_PENDING_PD; 2759b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru p2p_set_timeout(p2p, 0, 50000); 2760b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru } else if (p2p->state != P2P_IDLE) 2761b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru p2p_continue_find(p2p); 2762b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru else if (p2p->user_initiated_pd) { 2763b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru p2p->pending_action_state = P2P_PENDING_PD; 2764b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru p2p_set_timeout(p2p, 0, 300000); 2765b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 2766b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return; 2767b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 2768b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 2769b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru /* 2770b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * This postponing, of resetting pending_action_state, needs to be 2771b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * done only for user initiated PD requests and not internal ones. 2772b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru */ 2773b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (p2p->user_initiated_pd) 2774b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru p2p->pending_action_state = P2P_PENDING_PD; 2775b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru else 2776b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru p2p->pending_action_state = P2P_NO_PENDING_ACTION; 2777b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 2778b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru /* Wait for response from the peer */ 2779b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (p2p->state == P2P_SEARCH) 2780b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru p2p_set_state(p2p, P2P_PD_DURING_FIND); 2781b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru p2p_set_timeout(p2p, 0, 200000); 2782b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru} 2783b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 2784b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 2785b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queruint p2p_scan_res_handler(struct p2p_data *p2p, const u8 *bssid, int freq, 2786b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru struct os_reltime *rx_time, int level, const u8 *ies, 2787b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru size_t ies_len) 2788b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru{ 2789b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (os_reltime_before(rx_time, &p2p->find_start)) { 2790b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru /* 2791b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * The driver may have cached (e.g., in cfg80211 BSS table) the 2792b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * scan results for relatively long time. To avoid reporting 2793b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * stale information, update P2P peers only based on results 2794b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * that have based on frames received after the last p2p_find 2795b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * operation was started. 2796b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru */ 2797b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru p2p_dbg(p2p, "Ignore old scan result for " MACSTR 2798b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru " (rx_time=%u.%06u)", 2799b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru MAC2STR(bssid), (unsigned int) rx_time->sec, 2800b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru (unsigned int) rx_time->usec); 2801b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return 0; 2802b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 2803b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 2804b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru p2p_add_device(p2p, bssid, freq, rx_time, level, ies, ies_len, 1); 2805b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 2806b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return 0; 2807b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru} 2808b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 2809b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 2810b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queruvoid p2p_scan_res_handled(struct p2p_data *p2p) 2811b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru{ 2812b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (!p2p->p2p_scan_running) { 2813b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru p2p_dbg(p2p, "p2p_scan was not running, but scan results received"); 2814b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 2815b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru p2p->p2p_scan_running = 0; 2816b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru eloop_cancel_timeout(p2p_scan_timeout, p2p, NULL); 2817b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 2818b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (p2p_run_after_scan(p2p)) 2819b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return; 2820b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (p2p->state == P2P_SEARCH) 2821b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru p2p_continue_find(p2p); 2822b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru} 2823b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 2824b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 2825b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queruvoid p2p_scan_ie(struct p2p_data *p2p, struct wpabuf *ies, const u8 *dev_id) 2826b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru{ 2827b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru u8 *len; 2828b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 2829b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#ifdef CONFIG_WIFI_DISPLAY 2830b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (p2p->wfd_ie_probe_req) 2831b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru wpabuf_put_buf(ies, p2p->wfd_ie_probe_req); 2832b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#endif /* CONFIG_WIFI_DISPLAY */ 2833b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 2834b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru len = p2p_buf_add_ie_hdr(ies); 2835b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru p2p_buf_add_capability(ies, p2p->dev_capab & 2836b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru ~P2P_DEV_CAPAB_CLIENT_DISCOVERABILITY, 0); 2837b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (dev_id) 2838b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru p2p_buf_add_device_id(ies, dev_id); 2839b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (p2p->cfg->reg_class && p2p->cfg->channel) 2840b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru p2p_buf_add_listen_channel(ies, p2p->cfg->country, 2841b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru p2p->cfg->reg_class, 2842b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru p2p->cfg->channel); 2843b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (p2p->ext_listen_interval) 2844b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru p2p_buf_add_ext_listen_timing(ies, p2p->ext_listen_period, 2845b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru p2p->ext_listen_interval); 2846b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru /* TODO: p2p_buf_add_operating_channel() if GO */ 2847b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru p2p_buf_update_ie_hdr(ies, len); 2848b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru} 2849b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 2850b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 2851b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Querusize_t p2p_scan_ie_buf_len(struct p2p_data *p2p) 2852b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru{ 2853b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru size_t len = 100; 2854b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 2855b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#ifdef CONFIG_WIFI_DISPLAY 2856b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (p2p && p2p->wfd_ie_probe_req) 2857b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru len += wpabuf_len(p2p->wfd_ie_probe_req); 2858b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#endif /* CONFIG_WIFI_DISPLAY */ 2859b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 2860b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return len; 2861b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru} 2862b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 2863b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 2864b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queruint p2p_ie_text(struct wpabuf *p2p_ie, char *buf, char *end) 2865b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru{ 2866b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return p2p_attr_text(p2p_ie, buf, end); 2867b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru} 2868b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 2869b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 2870b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Querustatic void p2p_go_neg_req_cb(struct p2p_data *p2p, int success) 2871b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru{ 2872b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru struct p2p_device *dev = p2p->go_neg_peer; 2873b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru int timeout; 2874b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 2875b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru p2p_dbg(p2p, "GO Negotiation Request TX callback: success=%d", success); 2876b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 2877b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (dev == NULL) { 2878b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru p2p_dbg(p2p, "No pending GO Negotiation"); 2879b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return; 2880b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 2881b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 2882b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (success) { 2883b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (dev->flags & P2P_DEV_USER_REJECTED) { 2884b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru p2p_set_state(p2p, P2P_IDLE); 2885b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return; 2886b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 2887b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } else if (dev->go_neg_req_sent) { 2888b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru /* Cancel the increment from p2p_connect_send() on failure */ 2889b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru dev->go_neg_req_sent--; 2890b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 2891b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 2892b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (!success && 2893b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru (dev->info.dev_capab & P2P_DEV_CAPAB_CLIENT_DISCOVERABILITY) && 2894b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru !is_zero_ether_addr(dev->member_in_go_dev)) { 2895b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru p2p_dbg(p2p, "Peer " MACSTR " did not acknowledge request - try to use device discoverability through its GO", 2896b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru MAC2STR(dev->info.p2p_device_addr)); 2897b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru p2p->cfg->send_action_done(p2p->cfg->cb_ctx); 2898b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru p2p_send_dev_disc_req(p2p, dev); 2899b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return; 2900b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 2901b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 2902b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru /* 2903b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * Use P2P find, if needed, to find the other device from its listen 2904b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * channel. 2905b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru */ 2906b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru p2p_set_state(p2p, P2P_CONNECT); 2907b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru timeout = success ? 500000 : 100000; 2908b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (!success && p2p->go_neg_peer && 2909b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru (p2p->go_neg_peer->flags & P2P_DEV_PEER_WAITING_RESPONSE)) { 2910b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru unsigned int r; 2911b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru /* 2912b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * Peer is expected to wait our response and we will skip the 2913b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * listen phase. Add some randomness to the wait time here to 2914b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * make it less likely to hit cases where we could end up in 2915b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * sync with peer not listening. 2916b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru */ 2917b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru os_get_random((u8 *) &r, sizeof(r)); 2918b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru timeout += r % 100000; 2919b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 2920b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru p2p_set_timeout(p2p, 0, timeout); 2921b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru} 2922b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 2923b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 2924b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Querustatic void p2p_go_neg_resp_cb(struct p2p_data *p2p, int success) 2925b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru{ 2926b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru p2p_dbg(p2p, "GO Negotiation Response TX callback: success=%d", 2927b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru success); 2928b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (!p2p->go_neg_peer && p2p->state == P2P_PROVISIONING) { 2929b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru p2p_dbg(p2p, "Ignore TX callback event - GO Negotiation is not running anymore"); 2930b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return; 2931b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 2932b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru p2p_set_state(p2p, P2P_CONNECT); 2933b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru p2p_set_timeout(p2p, 0, 500000); 2934b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru} 2935b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 2936b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 2937b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Querustatic void p2p_go_neg_resp_failure_cb(struct p2p_data *p2p, int success, 2938b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru const u8 *addr) 2939b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru{ 2940b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru p2p_dbg(p2p, "GO Negotiation Response (failure) TX callback: success=%d", success); 2941b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (p2p->go_neg_peer && p2p->go_neg_peer->status != P2P_SC_SUCCESS) { 2942b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru p2p_go_neg_failed(p2p, p2p->go_neg_peer, 2943b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru p2p->go_neg_peer->status); 2944b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } else if (success) { 2945b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru struct p2p_device *dev; 2946b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru dev = p2p_get_device(p2p, addr); 2947b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (dev && 2948b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru dev->status == P2P_SC_FAIL_INFO_CURRENTLY_UNAVAILABLE) 2949b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru dev->flags |= P2P_DEV_PEER_WAITING_RESPONSE; 2950b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 2951b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru} 2952b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 2953b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 2954b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Querustatic void p2p_go_neg_conf_cb(struct p2p_data *p2p, 2955b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru enum p2p_send_action_result result) 2956b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru{ 2957b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru struct p2p_device *dev; 2958b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 2959b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru p2p_dbg(p2p, "GO Negotiation Confirm TX callback: result=%d", result); 2960b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru p2p->cfg->send_action_done(p2p->cfg->cb_ctx); 2961b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (result == P2P_SEND_ACTION_FAILED) { 2962b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru p2p_go_neg_failed(p2p, p2p->go_neg_peer, -1); 2963b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return; 2964b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 2965b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (result == P2P_SEND_ACTION_NO_ACK) { 2966b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru /* 2967b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * It looks like the TX status for GO Negotiation Confirm is 2968b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * often showing failure even when the peer has actually 2969b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * received the frame. Since the peer may change channels 2970b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * immediately after having received the frame, we may not see 2971b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * an Ack for retries, so just dropping a single frame may 2972b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * trigger this. To allow the group formation to succeed if the 2973b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * peer did indeed receive the frame, continue regardless of 2974b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * the TX status. 2975b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru */ 2976b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru p2p_dbg(p2p, "Assume GO Negotiation Confirm TX was actually received by the peer even though Ack was not reported"); 2977b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 2978b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 2979b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru dev = p2p->go_neg_peer; 2980b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (dev == NULL) 2981b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return; 2982b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 2983b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru p2p_go_complete(p2p, dev); 2984b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru} 2985b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 2986b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 2987b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queruvoid p2p_send_action_cb(struct p2p_data *p2p, unsigned int freq, const u8 *dst, 2988b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru const u8 *src, const u8 *bssid, 2989b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru enum p2p_send_action_result result) 2990b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru{ 2991b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru enum p2p_pending_action_state state; 2992b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru int success; 2993b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 2994b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru p2p_dbg(p2p, "Action frame TX callback (state=%d freq=%u dst=" MACSTR 2995b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru " src=" MACSTR " bssid=" MACSTR " result=%d", 2996b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru p2p->pending_action_state, freq, MAC2STR(dst), MAC2STR(src), 2997b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru MAC2STR(bssid), result); 2998b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru success = result == P2P_SEND_ACTION_SUCCESS; 2999b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru state = p2p->pending_action_state; 3000b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru p2p->pending_action_state = P2P_NO_PENDING_ACTION; 3001b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru switch (state) { 3002b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru case P2P_NO_PENDING_ACTION: 3003b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (p2p->after_scan_tx_in_progress) { 3004b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru p2p->after_scan_tx_in_progress = 0; 3005b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (p2p->start_after_scan != P2P_AFTER_SCAN_NOTHING && 3006b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru p2p_run_after_scan(p2p)) 3007b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru break; 3008b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (p2p->state == P2P_SEARCH) { 3009b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru p2p_dbg(p2p, "Continue find after after_scan_tx completion"); 3010b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru p2p_continue_find(p2p); 3011b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 3012 } 3013 break; 3014 case P2P_PENDING_GO_NEG_REQUEST: 3015 p2p_go_neg_req_cb(p2p, success); 3016 break; 3017 case P2P_PENDING_GO_NEG_RESPONSE: 3018 p2p_go_neg_resp_cb(p2p, success); 3019 break; 3020 case P2P_PENDING_GO_NEG_RESPONSE_FAILURE: 3021 p2p_go_neg_resp_failure_cb(p2p, success, dst); 3022 break; 3023 case P2P_PENDING_GO_NEG_CONFIRM: 3024 p2p_go_neg_conf_cb(p2p, result); 3025 break; 3026 case P2P_PENDING_SD: 3027 p2p_sd_cb(p2p, success); 3028 break; 3029 case P2P_PENDING_PD: 3030 p2p_prov_disc_cb(p2p, success); 3031 break; 3032 case P2P_PENDING_INVITATION_REQUEST: 3033 p2p_invitation_req_cb(p2p, success); 3034 break; 3035 case P2P_PENDING_INVITATION_RESPONSE: 3036 p2p_invitation_resp_cb(p2p, success); 3037 break; 3038 case P2P_PENDING_DEV_DISC_REQUEST: 3039 p2p_dev_disc_req_cb(p2p, success); 3040 break; 3041 case P2P_PENDING_DEV_DISC_RESPONSE: 3042 p2p_dev_disc_resp_cb(p2p, success); 3043 break; 3044 case P2P_PENDING_GO_DISC_REQ: 3045 p2p_go_disc_req_cb(p2p, success); 3046 break; 3047 } 3048 3049 p2p->after_scan_tx_in_progress = 0; 3050} 3051 3052 3053void p2p_listen_cb(struct p2p_data *p2p, unsigned int freq, 3054 unsigned int duration) 3055{ 3056 if (freq == p2p->pending_client_disc_freq) { 3057 p2p_dbg(p2p, "Client discoverability remain-awake completed"); 3058 p2p->pending_client_disc_freq = 0; 3059 return; 3060 } 3061 3062 if (freq != p2p->pending_listen_freq) { 3063 p2p_dbg(p2p, "Unexpected listen callback for freq=%u duration=%u (pending_listen_freq=%u)", 3064 freq, duration, p2p->pending_listen_freq); 3065 return; 3066 } 3067 3068 p2p_dbg(p2p, "Starting Listen timeout(%u,%u) on freq=%u based on callback", 3069 p2p->pending_listen_sec, p2p->pending_listen_usec, 3070 p2p->pending_listen_freq); 3071 p2p->in_listen = 1; 3072 p2p->drv_in_listen = freq; 3073 if (p2p->pending_listen_sec || p2p->pending_listen_usec) { 3074 /* 3075 * Add 20 msec extra wait to avoid race condition with driver 3076 * remain-on-channel end event, i.e., give driver more time to 3077 * complete the operation before our timeout expires. 3078 */ 3079 p2p_set_timeout(p2p, p2p->pending_listen_sec, 3080 p2p->pending_listen_usec + 20000); 3081 } 3082 3083 p2p->pending_listen_freq = 0; 3084} 3085 3086 3087int p2p_listen_end(struct p2p_data *p2p, unsigned int freq) 3088{ 3089 p2p_dbg(p2p, "Driver ended Listen state (freq=%u)", freq); 3090 p2p->drv_in_listen = 0; 3091 if (p2p->in_listen) 3092 return 0; /* Internal timeout will trigger the next step */ 3093 3094 if (p2p->state == P2P_CONNECT_LISTEN && p2p->go_neg_peer) { 3095 if (p2p->go_neg_peer->connect_reqs >= 120) { 3096 p2p_dbg(p2p, "Timeout on sending GO Negotiation Request without getting response"); 3097 p2p_go_neg_failed(p2p, p2p->go_neg_peer, -1); 3098 return 0; 3099 } 3100 3101 p2p_set_state(p2p, P2P_CONNECT); 3102 p2p_connect_send(p2p, p2p->go_neg_peer); 3103 return 1; 3104 } else if (p2p->state == P2P_SEARCH) { 3105 if (p2p->p2p_scan_running) { 3106 /* 3107 * Search is already in progress. This can happen if 3108 * an Action frame RX is reported immediately after 3109 * the end of a remain-on-channel operation and the 3110 * response frame to that is sent using an offchannel 3111 * operation while in p2p_find. Avoid an attempt to 3112 * restart a scan here. 3113 */ 3114 p2p_dbg(p2p, "p2p_scan already in progress - do not try to start a new one"); 3115 return 1; 3116 } 3117 if (p2p->pending_listen_freq) { 3118 /* 3119 * Better wait a bit if the driver is unable to start 3120 * offchannel operation for some reason. p2p_search() 3121 * will be started from internal timeout. 3122 */ 3123 p2p_dbg(p2p, "Listen operation did not seem to start - delay search phase to avoid busy loop"); 3124 p2p_set_timeout(p2p, 0, 100000); 3125 return 1; 3126 } 3127 if (p2p->search_delay) { 3128 p2p_dbg(p2p, "Delay search operation by %u ms", 3129 p2p->search_delay); 3130 p2p_set_timeout(p2p, p2p->search_delay / 1000, 3131 (p2p->search_delay % 1000) * 1000); 3132 return 1; 3133 } 3134 p2p_search(p2p); 3135 return 1; 3136 } 3137 3138 return 0; 3139} 3140 3141 3142static void p2p_timeout_connect(struct p2p_data *p2p) 3143{ 3144 p2p->cfg->send_action_done(p2p->cfg->cb_ctx); 3145 if (p2p->go_neg_peer && 3146 (p2p->go_neg_peer->flags & P2P_DEV_WAIT_GO_NEG_CONFIRM)) { 3147 p2p_dbg(p2p, "Wait for GO Negotiation Confirm timed out - assume GO Negotiation failed"); 3148 p2p_go_neg_failed(p2p, p2p->go_neg_peer, -1); 3149 return; 3150 } 3151 if (p2p->go_neg_peer && 3152 (p2p->go_neg_peer->flags & P2P_DEV_PEER_WAITING_RESPONSE) && 3153 p2p->go_neg_peer->connect_reqs < 120) { 3154 p2p_dbg(p2p, "Peer expected to wait our response - skip listen"); 3155 p2p_connect_send(p2p, p2p->go_neg_peer); 3156 return; 3157 } 3158 3159 p2p_set_state(p2p, P2P_CONNECT_LISTEN); 3160 p2p_listen_in_find(p2p, 0); 3161} 3162 3163 3164static void p2p_timeout_connect_listen(struct p2p_data *p2p) 3165{ 3166 if (p2p->go_neg_peer) { 3167 if (p2p->drv_in_listen) { 3168 p2p_dbg(p2p, "Driver is still in Listen state; wait for it to complete"); 3169 return; 3170 } 3171 3172 if (p2p->go_neg_peer->connect_reqs >= 120) { 3173 p2p_dbg(p2p, "Timeout on sending GO Negotiation Request without getting response"); 3174 p2p_go_neg_failed(p2p, p2p->go_neg_peer, -1); 3175 return; 3176 } 3177 3178 p2p_set_state(p2p, P2P_CONNECT); 3179 p2p_connect_send(p2p, p2p->go_neg_peer); 3180 } else 3181 p2p_set_state(p2p, P2P_IDLE); 3182} 3183 3184 3185static void p2p_timeout_wait_peer_connect(struct p2p_data *p2p) 3186{ 3187 /* 3188 * TODO: could remain constantly in Listen state for some time if there 3189 * are no other concurrent uses for the radio. For now, go to listen 3190 * state once per second to give other uses a chance to use the radio. 3191 */ 3192 p2p_set_state(p2p, P2P_WAIT_PEER_IDLE); 3193 p2p_set_timeout(p2p, 0, 500000); 3194} 3195 3196 3197static void p2p_timeout_wait_peer_idle(struct p2p_data *p2p) 3198{ 3199 struct p2p_device *dev = p2p->go_neg_peer; 3200 3201 if (dev == NULL) { 3202 p2p_dbg(p2p, "Unknown GO Neg peer - stop GO Neg wait"); 3203 return; 3204 } 3205 3206 dev->wait_count++; 3207 if (dev->wait_count >= 120) { 3208 p2p_dbg(p2p, "Timeout on waiting peer to become ready for GO Negotiation"); 3209 p2p_go_neg_failed(p2p, dev, -1); 3210 return; 3211 } 3212 3213 p2p_dbg(p2p, "Go to Listen state while waiting for the peer to become ready for GO Negotiation"); 3214 p2p_set_state(p2p, P2P_WAIT_PEER_CONNECT); 3215 p2p_listen_in_find(p2p, 0); 3216} 3217 3218 3219static void p2p_timeout_sd_during_find(struct p2p_data *p2p) 3220{ 3221 p2p_dbg(p2p, "Service Discovery Query timeout"); 3222 if (p2p->sd_peer) { 3223 p2p->cfg->send_action_done(p2p->cfg->cb_ctx); 3224 p2p->sd_peer->flags &= ~P2P_DEV_SD_SCHEDULE; 3225 p2p->sd_peer = NULL; 3226 } 3227 p2p_continue_find(p2p); 3228} 3229 3230 3231static void p2p_timeout_prov_disc_during_find(struct p2p_data *p2p) 3232{ 3233 p2p_dbg(p2p, "Provision Discovery Request timeout"); 3234 p2p->cfg->send_action_done(p2p->cfg->cb_ctx); 3235 p2p_continue_find(p2p); 3236} 3237 3238 3239static void p2p_timeout_prov_disc_req(struct p2p_data *p2p) 3240{ 3241 p2p->pending_action_state = P2P_NO_PENDING_ACTION; 3242 3243 /* 3244 * For user initiated PD requests that we have not gotten any responses 3245 * for while in IDLE state, we retry them a couple of times before 3246 * giving up. 3247 */ 3248 if (!p2p->user_initiated_pd) 3249 return; 3250 3251 p2p_dbg(p2p, "User initiated Provision Discovery Request timeout"); 3252 3253 if (p2p->pd_retries) { 3254 p2p->pd_retries--; 3255 p2p_retry_pd(p2p); 3256 } else { 3257 struct p2p_device *dev; 3258 int for_join = 0; 3259 3260 dl_list_for_each(dev, &p2p->devices, struct p2p_device, list) { 3261 if (os_memcmp(p2p->pending_pd_devaddr, 3262 dev->info.p2p_device_addr, ETH_ALEN) != 0) 3263 continue; 3264 if (dev->req_config_methods && 3265 (dev->flags & P2P_DEV_PD_FOR_JOIN)) 3266 for_join = 1; 3267 } 3268 3269 if (p2p->cfg->prov_disc_fail) 3270 p2p->cfg->prov_disc_fail(p2p->cfg->cb_ctx, 3271 p2p->pending_pd_devaddr, 3272 for_join ? 3273 P2P_PROV_DISC_TIMEOUT_JOIN : 3274 P2P_PROV_DISC_TIMEOUT); 3275 p2p_reset_pending_pd(p2p); 3276 } 3277} 3278 3279 3280static void p2p_timeout_invite(struct p2p_data *p2p) 3281{ 3282 p2p->cfg->send_action_done(p2p->cfg->cb_ctx); 3283 p2p_set_state(p2p, P2P_INVITE_LISTEN); 3284 if (p2p->inv_role == P2P_INVITE_ROLE_ACTIVE_GO) { 3285 /* 3286 * Better remain on operating channel instead of listen channel 3287 * when running a group. 3288 */ 3289 p2p_dbg(p2p, "Inviting in active GO role - wait on operating channel"); 3290 p2p_set_timeout(p2p, 0, 100000); 3291 return; 3292 } 3293 p2p_listen_in_find(p2p, 0); 3294} 3295 3296 3297static void p2p_timeout_invite_listen(struct p2p_data *p2p) 3298{ 3299 if (p2p->invite_peer && p2p->invite_peer->invitation_reqs < 100) { 3300 p2p_set_state(p2p, P2P_INVITE); 3301 p2p_invite_send(p2p, p2p->invite_peer, 3302 p2p->invite_go_dev_addr); 3303 } else { 3304 if (p2p->invite_peer) { 3305 p2p_dbg(p2p, "Invitation Request retry limit reached"); 3306 if (p2p->cfg->invitation_result) 3307 p2p->cfg->invitation_result( 3308 p2p->cfg->cb_ctx, -1, NULL, NULL, 3309 p2p->invite_peer->info.p2p_device_addr, 3310 0); 3311 } 3312 p2p_set_state(p2p, P2P_IDLE); 3313 } 3314} 3315 3316 3317static void p2p_state_timeout(void *eloop_ctx, void *timeout_ctx) 3318{ 3319 struct p2p_data *p2p = eloop_ctx; 3320 3321 p2p_dbg(p2p, "Timeout (state=%s)", p2p_state_txt(p2p->state)); 3322 3323 p2p->in_listen = 0; 3324 3325 switch (p2p->state) { 3326 case P2P_IDLE: 3327 /* Check if we timed out waiting for PD req */ 3328 if (p2p->pending_action_state == P2P_PENDING_PD) 3329 p2p_timeout_prov_disc_req(p2p); 3330 break; 3331 case P2P_SEARCH: 3332 /* Check if we timed out waiting for PD req */ 3333 if (p2p->pending_action_state == P2P_PENDING_PD) 3334 p2p_timeout_prov_disc_req(p2p); 3335 if (p2p->search_delay && !p2p->in_search_delay) { 3336 p2p_dbg(p2p, "Delay search operation by %u ms", 3337 p2p->search_delay); 3338 p2p->in_search_delay = 1; 3339 p2p_set_timeout(p2p, p2p->search_delay / 1000, 3340 (p2p->search_delay % 1000) * 1000); 3341 break; 3342 } 3343 p2p->in_search_delay = 0; 3344 p2p_search(p2p); 3345 break; 3346 case P2P_CONNECT: 3347 p2p_timeout_connect(p2p); 3348 break; 3349 case P2P_CONNECT_LISTEN: 3350 p2p_timeout_connect_listen(p2p); 3351 break; 3352 case P2P_GO_NEG: 3353 break; 3354 case P2P_LISTEN_ONLY: 3355 /* Check if we timed out waiting for PD req */ 3356 if (p2p->pending_action_state == P2P_PENDING_PD) 3357 p2p_timeout_prov_disc_req(p2p); 3358 3359 if (p2p->ext_listen_only) { 3360 p2p_dbg(p2p, "Extended Listen Timing - Listen State completed"); 3361 p2p->ext_listen_only = 0; 3362 p2p_set_state(p2p, P2P_IDLE); 3363 } 3364 break; 3365 case P2P_WAIT_PEER_CONNECT: 3366 p2p_timeout_wait_peer_connect(p2p); 3367 break; 3368 case P2P_WAIT_PEER_IDLE: 3369 p2p_timeout_wait_peer_idle(p2p); 3370 break; 3371 case P2P_SD_DURING_FIND: 3372 p2p_timeout_sd_during_find(p2p); 3373 break; 3374 case P2P_PROVISIONING: 3375 break; 3376 case P2P_PD_DURING_FIND: 3377 p2p_timeout_prov_disc_during_find(p2p); 3378 break; 3379 case P2P_INVITE: 3380 p2p_timeout_invite(p2p); 3381 break; 3382 case P2P_INVITE_LISTEN: 3383 p2p_timeout_invite_listen(p2p); 3384 break; 3385 } 3386} 3387 3388 3389int p2p_reject(struct p2p_data *p2p, const u8 *peer_addr) 3390{ 3391 struct p2p_device *dev; 3392 3393 dev = p2p_get_device(p2p, peer_addr); 3394 p2p_dbg(p2p, "Local request to reject connection attempts by peer " 3395 MACSTR, MAC2STR(peer_addr)); 3396 if (dev == NULL) { 3397 p2p_dbg(p2p, "Peer " MACSTR " unknown", MAC2STR(peer_addr)); 3398 return -1; 3399 } 3400 dev->status = P2P_SC_FAIL_REJECTED_BY_USER; 3401 dev->flags |= P2P_DEV_USER_REJECTED; 3402 return 0; 3403} 3404 3405 3406const char * p2p_wps_method_text(enum p2p_wps_method method) 3407{ 3408 switch (method) { 3409 case WPS_NOT_READY: 3410 return "not-ready"; 3411 case WPS_PIN_DISPLAY: 3412 return "Display"; 3413 case WPS_PIN_KEYPAD: 3414 return "Keypad"; 3415 case WPS_PBC: 3416 return "PBC"; 3417 } 3418 3419 return "??"; 3420} 3421 3422 3423static const char * p2p_go_state_text(enum p2p_go_state go_state) 3424{ 3425 switch (go_state) { 3426 case UNKNOWN_GO: 3427 return "unknown"; 3428 case LOCAL_GO: 3429 return "local"; 3430 case REMOTE_GO: 3431 return "remote"; 3432 } 3433 3434 return "??"; 3435} 3436 3437 3438const struct p2p_peer_info * p2p_get_peer_info(struct p2p_data *p2p, 3439 const u8 *addr, int next) 3440{ 3441 struct p2p_device *dev; 3442 3443 if (addr) 3444 dev = p2p_get_device(p2p, addr); 3445 else 3446 dev = dl_list_first(&p2p->devices, struct p2p_device, list); 3447 3448 if (dev && next) { 3449 dev = dl_list_first(&dev->list, struct p2p_device, list); 3450 if (&dev->list == &p2p->devices) 3451 dev = NULL; 3452 } 3453 3454 if (dev == NULL) 3455 return NULL; 3456 3457 return &dev->info; 3458} 3459 3460 3461int p2p_get_peer_info_txt(const struct p2p_peer_info *info, 3462 char *buf, size_t buflen) 3463{ 3464 struct p2p_device *dev; 3465 int res; 3466 char *pos, *end; 3467 struct os_reltime now; 3468 3469 if (info == NULL) 3470 return -1; 3471 3472 dev = (struct p2p_device *) (((u8 *) info) - 3473 offsetof(struct p2p_device, info)); 3474 3475 pos = buf; 3476 end = buf + buflen; 3477 3478 os_get_reltime(&now); 3479 res = os_snprintf(pos, end - pos, 3480 "age=%d\n" 3481 "listen_freq=%d\n" 3482 "wps_method=%s\n" 3483 "interface_addr=" MACSTR "\n" 3484 "member_in_go_dev=" MACSTR "\n" 3485 "member_in_go_iface=" MACSTR "\n" 3486 "go_neg_req_sent=%d\n" 3487 "go_state=%s\n" 3488 "dialog_token=%u\n" 3489 "intended_addr=" MACSTR "\n" 3490 "country=%c%c\n" 3491 "oper_freq=%d\n" 3492 "req_config_methods=0x%x\n" 3493 "flags=%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s\n" 3494 "status=%d\n" 3495 "wait_count=%u\n" 3496 "invitation_reqs=%u\n", 3497 (int) (now.sec - dev->last_seen.sec), 3498 dev->listen_freq, 3499 p2p_wps_method_text(dev->wps_method), 3500 MAC2STR(dev->interface_addr), 3501 MAC2STR(dev->member_in_go_dev), 3502 MAC2STR(dev->member_in_go_iface), 3503 dev->go_neg_req_sent, 3504 p2p_go_state_text(dev->go_state), 3505 dev->dialog_token, 3506 MAC2STR(dev->intended_addr), 3507 dev->country[0] ? dev->country[0] : '_', 3508 dev->country[1] ? dev->country[1] : '_', 3509 dev->oper_freq, 3510 dev->req_config_methods, 3511 dev->flags & P2P_DEV_PROBE_REQ_ONLY ? 3512 "[PROBE_REQ_ONLY]" : "", 3513 dev->flags & P2P_DEV_REPORTED ? "[REPORTED]" : "", 3514 dev->flags & P2P_DEV_NOT_YET_READY ? 3515 "[NOT_YET_READY]" : "", 3516 dev->flags & P2P_DEV_SD_INFO ? "[SD_INFO]" : "", 3517 dev->flags & P2P_DEV_SD_SCHEDULE ? "[SD_SCHEDULE]" : 3518 "", 3519 dev->flags & P2P_DEV_PD_PEER_DISPLAY ? 3520 "[PD_PEER_DISPLAY]" : "", 3521 dev->flags & P2P_DEV_PD_PEER_KEYPAD ? 3522 "[PD_PEER_KEYPAD]" : "", 3523 dev->flags & P2P_DEV_USER_REJECTED ? 3524 "[USER_REJECTED]" : "", 3525 dev->flags & P2P_DEV_PEER_WAITING_RESPONSE ? 3526 "[PEER_WAITING_RESPONSE]" : "", 3527 dev->flags & P2P_DEV_PREFER_PERSISTENT_GROUP ? 3528 "[PREFER_PERSISTENT_GROUP]" : "", 3529 dev->flags & P2P_DEV_WAIT_GO_NEG_RESPONSE ? 3530 "[WAIT_GO_NEG_RESPONSE]" : "", 3531 dev->flags & P2P_DEV_WAIT_GO_NEG_CONFIRM ? 3532 "[WAIT_GO_NEG_CONFIRM]" : "", 3533 dev->flags & P2P_DEV_GROUP_CLIENT_ONLY ? 3534 "[GROUP_CLIENT_ONLY]" : "", 3535 dev->flags & P2P_DEV_FORCE_FREQ ? 3536 "[FORCE_FREQ]" : "", 3537 dev->flags & P2P_DEV_PD_FOR_JOIN ? 3538 "[PD_FOR_JOIN]" : "", 3539 dev->status, 3540 dev->wait_count, 3541 dev->invitation_reqs); 3542 if (res < 0 || res >= end - pos) 3543 return pos - buf; 3544 pos += res; 3545 3546 if (dev->ext_listen_period) { 3547 res = os_snprintf(pos, end - pos, 3548 "ext_listen_period=%u\n" 3549 "ext_listen_interval=%u\n", 3550 dev->ext_listen_period, 3551 dev->ext_listen_interval); 3552 if (res < 0 || res >= end - pos) 3553 return pos - buf; 3554 pos += res; 3555 } 3556 3557 if (dev->oper_ssid_len) { 3558 res = os_snprintf(pos, end - pos, 3559 "oper_ssid=%s\n", 3560 wpa_ssid_txt(dev->oper_ssid, 3561 dev->oper_ssid_len)); 3562 if (res < 0 || res >= end - pos) 3563 return pos - buf; 3564 pos += res; 3565 } 3566 3567#ifdef CONFIG_WIFI_DISPLAY 3568 if (dev->info.wfd_subelems) { 3569 res = os_snprintf(pos, end - pos, "wfd_subelems="); 3570 if (res < 0 || res >= end - pos) 3571 return pos - buf; 3572 pos += res; 3573 3574 pos += wpa_snprintf_hex(pos, end - pos, 3575 wpabuf_head(dev->info.wfd_subelems), 3576 wpabuf_len(dev->info.wfd_subelems)); 3577 3578 res = os_snprintf(pos, end - pos, "\n"); 3579 if (res < 0 || res >= end - pos) 3580 return pos - buf; 3581 pos += res; 3582 } 3583#endif /* CONFIG_WIFI_DISPLAY */ 3584 3585 return pos - buf; 3586} 3587 3588 3589int p2p_peer_known(struct p2p_data *p2p, const u8 *addr) 3590{ 3591 return p2p_get_device(p2p, addr) != NULL; 3592} 3593 3594 3595void p2p_set_client_discoverability(struct p2p_data *p2p, int enabled) 3596{ 3597 if (enabled) { 3598 p2p_dbg(p2p, "Client discoverability enabled"); 3599 p2p->dev_capab |= P2P_DEV_CAPAB_CLIENT_DISCOVERABILITY; 3600 } else { 3601 p2p_dbg(p2p, "Client discoverability disabled"); 3602 p2p->dev_capab &= ~P2P_DEV_CAPAB_CLIENT_DISCOVERABILITY; 3603 } 3604} 3605 3606 3607static struct wpabuf * p2p_build_presence_req(u32 duration1, u32 interval1, 3608 u32 duration2, u32 interval2) 3609{ 3610 struct wpabuf *req; 3611 struct p2p_noa_desc desc1, desc2, *ptr1 = NULL, *ptr2 = NULL; 3612 u8 *len; 3613 3614 req = wpabuf_alloc(100); 3615 if (req == NULL) 3616 return NULL; 3617 3618 if (duration1 || interval1) { 3619 os_memset(&desc1, 0, sizeof(desc1)); 3620 desc1.count_type = 1; 3621 desc1.duration = duration1; 3622 desc1.interval = interval1; 3623 ptr1 = &desc1; 3624 3625 if (duration2 || interval2) { 3626 os_memset(&desc2, 0, sizeof(desc2)); 3627 desc2.count_type = 2; 3628 desc2.duration = duration2; 3629 desc2.interval = interval2; 3630 ptr2 = &desc2; 3631 } 3632 } 3633 3634 p2p_buf_add_action_hdr(req, P2P_PRESENCE_REQ, 1); 3635 len = p2p_buf_add_ie_hdr(req); 3636 p2p_buf_add_noa(req, 0, 0, 0, ptr1, ptr2); 3637 p2p_buf_update_ie_hdr(req, len); 3638 3639 return req; 3640} 3641 3642 3643int p2p_presence_req(struct p2p_data *p2p, const u8 *go_interface_addr, 3644 const u8 *own_interface_addr, unsigned int freq, 3645 u32 duration1, u32 interval1, u32 duration2, 3646 u32 interval2) 3647{ 3648 struct wpabuf *req; 3649 3650 p2p_dbg(p2p, "Send Presence Request to GO " MACSTR 3651 " (own interface " MACSTR ") freq=%u dur1=%u int1=%u " 3652 "dur2=%u int2=%u", 3653 MAC2STR(go_interface_addr), MAC2STR(own_interface_addr), 3654 freq, duration1, interval1, duration2, interval2); 3655 3656 req = p2p_build_presence_req(duration1, interval1, duration2, 3657 interval2); 3658 if (req == NULL) 3659 return -1; 3660 3661 p2p->pending_action_state = P2P_NO_PENDING_ACTION; 3662 if (p2p_send_action(p2p, freq, go_interface_addr, own_interface_addr, 3663 go_interface_addr, 3664 wpabuf_head(req), wpabuf_len(req), 200) < 0) { 3665 p2p_dbg(p2p, "Failed to send Action frame"); 3666 } 3667 wpabuf_free(req); 3668 3669 return 0; 3670} 3671 3672 3673static struct wpabuf * p2p_build_presence_resp(u8 status, const u8 *noa, 3674 size_t noa_len, u8 dialog_token) 3675{ 3676 struct wpabuf *resp; 3677 u8 *len; 3678 3679 resp = wpabuf_alloc(100 + noa_len); 3680 if (resp == NULL) 3681 return NULL; 3682 3683 p2p_buf_add_action_hdr(resp, P2P_PRESENCE_RESP, dialog_token); 3684 len = p2p_buf_add_ie_hdr(resp); 3685 p2p_buf_add_status(resp, status); 3686 if (noa) { 3687 wpabuf_put_u8(resp, P2P_ATTR_NOTICE_OF_ABSENCE); 3688 wpabuf_put_le16(resp, noa_len); 3689 wpabuf_put_data(resp, noa, noa_len); 3690 } else 3691 p2p_buf_add_noa(resp, 0, 0, 0, NULL, NULL); 3692 p2p_buf_update_ie_hdr(resp, len); 3693 3694 return resp; 3695} 3696 3697 3698static void p2p_process_presence_req(struct p2p_data *p2p, const u8 *da, 3699 const u8 *sa, const u8 *data, size_t len, 3700 int rx_freq) 3701{ 3702 struct p2p_message msg; 3703 u8 status; 3704 struct wpabuf *resp; 3705 size_t g; 3706 struct p2p_group *group = NULL; 3707 int parsed = 0; 3708 u8 noa[50]; 3709 int noa_len; 3710 3711 p2p_dbg(p2p, "Received P2P Action - P2P Presence Request"); 3712 3713 for (g = 0; g < p2p->num_groups; g++) { 3714 if (os_memcmp(da, p2p_group_get_interface_addr(p2p->groups[g]), 3715 ETH_ALEN) == 0) { 3716 group = p2p->groups[g]; 3717 break; 3718 } 3719 } 3720 if (group == NULL) { 3721 p2p_dbg(p2p, "Ignore P2P Presence Request for unknown group " 3722 MACSTR, MAC2STR(da)); 3723 return; 3724 } 3725 3726 if (p2p_parse(data, len, &msg) < 0) { 3727 p2p_dbg(p2p, "Failed to parse P2P Presence Request"); 3728 status = P2P_SC_FAIL_INVALID_PARAMS; 3729 goto fail; 3730 } 3731 parsed = 1; 3732 3733 if (msg.noa == NULL) { 3734 p2p_dbg(p2p, "No NoA attribute in P2P Presence Request"); 3735 status = P2P_SC_FAIL_INVALID_PARAMS; 3736 goto fail; 3737 } 3738 3739 status = p2p_group_presence_req(group, sa, msg.noa, msg.noa_len); 3740 3741fail: 3742 if (p2p->cfg->get_noa) 3743 noa_len = p2p->cfg->get_noa(p2p->cfg->cb_ctx, da, noa, 3744 sizeof(noa)); 3745 else 3746 noa_len = -1; 3747 resp = p2p_build_presence_resp(status, noa_len > 0 ? noa : NULL, 3748 noa_len > 0 ? noa_len : 0, 3749 msg.dialog_token); 3750 if (parsed) 3751 p2p_parse_free(&msg); 3752 if (resp == NULL) 3753 return; 3754 3755 p2p->pending_action_state = P2P_NO_PENDING_ACTION; 3756 if (p2p_send_action(p2p, rx_freq, sa, da, da, 3757 wpabuf_head(resp), wpabuf_len(resp), 200) < 0) { 3758 p2p_dbg(p2p, "Failed to send Action frame"); 3759 } 3760 wpabuf_free(resp); 3761} 3762 3763 3764static void p2p_process_presence_resp(struct p2p_data *p2p, const u8 *da, 3765 const u8 *sa, const u8 *data, size_t len) 3766{ 3767 struct p2p_message msg; 3768 3769 p2p_dbg(p2p, "Received P2P Action - P2P Presence Response"); 3770 3771 if (p2p_parse(data, len, &msg) < 0) { 3772 p2p_dbg(p2p, "Failed to parse P2P Presence Response"); 3773 return; 3774 } 3775 3776 if (msg.status == NULL || msg.noa == NULL) { 3777 p2p_dbg(p2p, "No Status or NoA attribute in P2P Presence Response"); 3778 p2p_parse_free(&msg); 3779 return; 3780 } 3781 3782 if (p2p->cfg->presence_resp) { 3783 p2p->cfg->presence_resp(p2p->cfg->cb_ctx, sa, *msg.status, 3784 msg.noa, msg.noa_len); 3785 } 3786 3787 if (*msg.status) { 3788 p2p_dbg(p2p, "P2P Presence Request was rejected: status %u", 3789 *msg.status); 3790 p2p_parse_free(&msg); 3791 return; 3792 } 3793 3794 p2p_dbg(p2p, "P2P Presence Request was accepted"); 3795 wpa_hexdump(MSG_DEBUG, "P2P: P2P Presence Response - NoA", 3796 msg.noa, msg.noa_len); 3797 /* TODO: process NoA */ 3798 p2p_parse_free(&msg); 3799} 3800 3801 3802static void p2p_ext_listen_timeout(void *eloop_ctx, void *timeout_ctx) 3803{ 3804 struct p2p_data *p2p = eloop_ctx; 3805 3806 if (p2p->ext_listen_interval) { 3807 /* Schedule next extended listen timeout */ 3808 eloop_register_timeout(p2p->ext_listen_interval_sec, 3809 p2p->ext_listen_interval_usec, 3810 p2p_ext_listen_timeout, p2p, NULL); 3811 } 3812 3813 if (p2p->state == P2P_LISTEN_ONLY && p2p->ext_listen_only) { 3814 /* 3815 * This should not really happen, but it looks like the Listen 3816 * command may fail is something else (e.g., a scan) was 3817 * running at an inconvenient time. As a workaround, allow new 3818 * Extended Listen operation to be started. 3819 */ 3820 p2p_dbg(p2p, "Previous Extended Listen operation had not been completed - try again"); 3821 p2p->ext_listen_only = 0; 3822 p2p_set_state(p2p, P2P_IDLE); 3823 } 3824 3825 if (p2p->state != P2P_IDLE) { 3826 p2p_dbg(p2p, "Skip Extended Listen timeout in active state (%s)", p2p_state_txt(p2p->state)); 3827 return; 3828 } 3829 3830 p2p_dbg(p2p, "Extended Listen timeout"); 3831 p2p->ext_listen_only = 1; 3832 if (p2p_listen(p2p, p2p->ext_listen_period) < 0) { 3833 p2p_dbg(p2p, "Failed to start Listen state for Extended Listen Timing"); 3834 p2p->ext_listen_only = 0; 3835 } 3836} 3837 3838 3839int p2p_ext_listen(struct p2p_data *p2p, unsigned int period, 3840 unsigned int interval) 3841{ 3842 if (period > 65535 || interval > 65535 || period > interval || 3843 (period == 0 && interval > 0) || (period > 0 && interval == 0)) { 3844 p2p_dbg(p2p, "Invalid Extended Listen Timing request: period=%u interval=%u", 3845 period, interval); 3846 return -1; 3847 } 3848 3849 eloop_cancel_timeout(p2p_ext_listen_timeout, p2p, NULL); 3850 3851 if (interval == 0) { 3852 p2p_dbg(p2p, "Disabling Extended Listen Timing"); 3853 p2p->ext_listen_period = 0; 3854 p2p->ext_listen_interval = 0; 3855 return 0; 3856 } 3857 3858 p2p_dbg(p2p, "Enabling Extended Listen Timing: period %u msec, interval %u msec", 3859 period, interval); 3860 p2p->ext_listen_period = period; 3861 p2p->ext_listen_interval = interval; 3862 p2p->ext_listen_interval_sec = interval / 1000; 3863 p2p->ext_listen_interval_usec = (interval % 1000) * 1000; 3864 3865 eloop_register_timeout(p2p->ext_listen_interval_sec, 3866 p2p->ext_listen_interval_usec, 3867 p2p_ext_listen_timeout, p2p, NULL); 3868 3869 return 0; 3870} 3871 3872 3873void p2p_deauth_notif(struct p2p_data *p2p, const u8 *bssid, u16 reason_code, 3874 const u8 *ie, size_t ie_len) 3875{ 3876 struct p2p_message msg; 3877 3878 if (bssid == NULL || ie == NULL) 3879 return; 3880 3881 os_memset(&msg, 0, sizeof(msg)); 3882 if (p2p_parse_ies(ie, ie_len, &msg)) 3883 return; 3884 if (msg.minor_reason_code == NULL) 3885 return; 3886 3887 p2p_dbg(p2p, "Deauthentication notification BSSID " MACSTR 3888 " reason_code=%u minor_reason_code=%u", 3889 MAC2STR(bssid), reason_code, *msg.minor_reason_code); 3890 3891 p2p_parse_free(&msg); 3892} 3893 3894 3895void p2p_disassoc_notif(struct p2p_data *p2p, const u8 *bssid, u16 reason_code, 3896 const u8 *ie, size_t ie_len) 3897{ 3898 struct p2p_message msg; 3899 3900 if (bssid == NULL || ie == NULL) 3901 return; 3902 3903 os_memset(&msg, 0, sizeof(msg)); 3904 if (p2p_parse_ies(ie, ie_len, &msg)) 3905 return; 3906 if (msg.minor_reason_code == NULL) 3907 return; 3908 3909 p2p_dbg(p2p, "Disassociation notification BSSID " MACSTR 3910 " reason_code=%u minor_reason_code=%u", 3911 MAC2STR(bssid), reason_code, *msg.minor_reason_code); 3912 3913 p2p_parse_free(&msg); 3914} 3915 3916 3917void p2p_set_managed_oper(struct p2p_data *p2p, int enabled) 3918{ 3919 if (enabled) { 3920 p2p_dbg(p2p, "Managed P2P Device operations enabled"); 3921 p2p->dev_capab |= P2P_DEV_CAPAB_INFRA_MANAGED; 3922 } else { 3923 p2p_dbg(p2p, "Managed P2P Device operations disabled"); 3924 p2p->dev_capab &= ~P2P_DEV_CAPAB_INFRA_MANAGED; 3925 } 3926} 3927 3928 3929int p2p_set_listen_channel(struct p2p_data *p2p, u8 reg_class, u8 channel) 3930{ 3931 if (p2p_channel_to_freq(reg_class, channel) < 0) 3932 return -1; 3933 3934 p2p_dbg(p2p, "Set Listen channel: reg_class %u channel %u", 3935 reg_class, channel); 3936 p2p->cfg->reg_class = reg_class; 3937 p2p->cfg->channel = channel; 3938 3939 return 0; 3940} 3941 3942 3943int p2p_set_ssid_postfix(struct p2p_data *p2p, const u8 *postfix, size_t len) 3944{ 3945 p2p_dbg(p2p, "New SSID postfix: %s", wpa_ssid_txt(postfix, len)); 3946 if (postfix == NULL) { 3947 p2p->cfg->ssid_postfix_len = 0; 3948 return 0; 3949 } 3950 if (len > sizeof(p2p->cfg->ssid_postfix)) 3951 return -1; 3952 os_memcpy(p2p->cfg->ssid_postfix, postfix, len); 3953 p2p->cfg->ssid_postfix_len = len; 3954 return 0; 3955} 3956 3957 3958int p2p_set_oper_channel(struct p2p_data *p2p, u8 op_reg_class, u8 op_channel, 3959 int cfg_op_channel) 3960{ 3961 if (p2p_channel_to_freq(op_reg_class, op_channel) < 0) 3962 return -1; 3963 3964 p2p_dbg(p2p, "Set Operating channel: reg_class %u channel %u", 3965 op_reg_class, op_channel); 3966 p2p->cfg->op_reg_class = op_reg_class; 3967 p2p->cfg->op_channel = op_channel; 3968 p2p->cfg->cfg_op_channel = cfg_op_channel; 3969 return 0; 3970} 3971 3972 3973int p2p_set_pref_chan(struct p2p_data *p2p, unsigned int num_pref_chan, 3974 const struct p2p_channel *pref_chan) 3975{ 3976 struct p2p_channel *n; 3977 3978 if (pref_chan) { 3979 n = os_malloc(num_pref_chan * sizeof(struct p2p_channel)); 3980 if (n == NULL) 3981 return -1; 3982 os_memcpy(n, pref_chan, 3983 num_pref_chan * sizeof(struct p2p_channel)); 3984 } else 3985 n = NULL; 3986 3987 os_free(p2p->cfg->pref_chan); 3988 p2p->cfg->pref_chan = n; 3989 p2p->cfg->num_pref_chan = num_pref_chan; 3990 3991 return 0; 3992} 3993 3994 3995int p2p_set_no_go_freq(struct p2p_data *p2p, 3996 const struct wpa_freq_range_list *list) 3997{ 3998 struct wpa_freq_range *tmp; 3999 4000 if (list == NULL || list->num == 0) { 4001 os_free(p2p->no_go_freq.range); 4002 p2p->no_go_freq.range = NULL; 4003 p2p->no_go_freq.num = 0; 4004 return 0; 4005 } 4006 4007 tmp = os_calloc(list->num, sizeof(struct wpa_freq_range)); 4008 if (tmp == NULL) 4009 return -1; 4010 os_memcpy(tmp, list->range, list->num * sizeof(struct wpa_freq_range)); 4011 os_free(p2p->no_go_freq.range); 4012 p2p->no_go_freq.range = tmp; 4013 p2p->no_go_freq.num = list->num; 4014 p2p_dbg(p2p, "Updated no GO chan list"); 4015 4016 return 0; 4017} 4018 4019 4020int p2p_get_interface_addr(struct p2p_data *p2p, const u8 *dev_addr, 4021 u8 *iface_addr) 4022{ 4023 struct p2p_device *dev = p2p_get_device(p2p, dev_addr); 4024 if (dev == NULL || is_zero_ether_addr(dev->interface_addr)) 4025 return -1; 4026 os_memcpy(iface_addr, dev->interface_addr, ETH_ALEN); 4027 return 0; 4028} 4029 4030 4031int p2p_get_dev_addr(struct p2p_data *p2p, const u8 *iface_addr, 4032 u8 *dev_addr) 4033{ 4034 struct p2p_device *dev = p2p_get_device_interface(p2p, iface_addr); 4035 if (dev == NULL) 4036 return -1; 4037 os_memcpy(dev_addr, dev->info.p2p_device_addr, ETH_ALEN); 4038 return 0; 4039} 4040 4041 4042void p2p_set_peer_filter(struct p2p_data *p2p, const u8 *addr) 4043{ 4044 os_memcpy(p2p->peer_filter, addr, ETH_ALEN); 4045 if (is_zero_ether_addr(p2p->peer_filter)) 4046 p2p_dbg(p2p, "Disable peer filter"); 4047 else 4048 p2p_dbg(p2p, "Enable peer filter for " MACSTR, 4049 MAC2STR(p2p->peer_filter)); 4050} 4051 4052 4053void p2p_set_cross_connect(struct p2p_data *p2p, int enabled) 4054{ 4055 p2p_dbg(p2p, "Cross connection %s", enabled ? "enabled" : "disabled"); 4056 if (p2p->cross_connect == enabled) 4057 return; 4058 p2p->cross_connect = enabled; 4059 /* TODO: may need to tear down any action group where we are GO(?) */ 4060} 4061 4062 4063int p2p_get_oper_freq(struct p2p_data *p2p, const u8 *iface_addr) 4064{ 4065 struct p2p_device *dev = p2p_get_device_interface(p2p, iface_addr); 4066 if (dev == NULL) 4067 return -1; 4068 if (dev->oper_freq <= 0) 4069 return -1; 4070 return dev->oper_freq; 4071} 4072 4073 4074void p2p_set_intra_bss_dist(struct p2p_data *p2p, int enabled) 4075{ 4076 p2p_dbg(p2p, "Intra BSS distribution %s", 4077 enabled ? "enabled" : "disabled"); 4078 p2p->cfg->p2p_intra_bss = enabled; 4079} 4080 4081 4082void p2p_update_channel_list(struct p2p_data *p2p, 4083 const struct p2p_channels *chan, 4084 const struct p2p_channels *cli_chan) 4085{ 4086 p2p_dbg(p2p, "Update channel list"); 4087 os_memcpy(&p2p->cfg->channels, chan, sizeof(struct p2p_channels)); 4088 p2p_channels_dump(p2p, "channels", &p2p->cfg->channels); 4089 os_memcpy(&p2p->cfg->cli_channels, cli_chan, 4090 sizeof(struct p2p_channels)); 4091 p2p_channels_dump(p2p, "cli_channels", &p2p->cfg->cli_channels); 4092} 4093 4094 4095int p2p_send_action(struct p2p_data *p2p, unsigned int freq, const u8 *dst, 4096 const u8 *src, const u8 *bssid, const u8 *buf, 4097 size_t len, unsigned int wait_time) 4098{ 4099 if (p2p->p2p_scan_running) { 4100 p2p_dbg(p2p, "Delay Action frame TX until p2p_scan completes"); 4101 if (p2p->after_scan_tx) { 4102 p2p_dbg(p2p, "Dropped previous pending Action frame TX"); 4103 os_free(p2p->after_scan_tx); 4104 } 4105 p2p->after_scan_tx = os_malloc(sizeof(*p2p->after_scan_tx) + 4106 len); 4107 if (p2p->after_scan_tx == NULL) 4108 return -1; 4109 p2p->after_scan_tx->freq = freq; 4110 os_memcpy(p2p->after_scan_tx->dst, dst, ETH_ALEN); 4111 os_memcpy(p2p->after_scan_tx->src, src, ETH_ALEN); 4112 os_memcpy(p2p->after_scan_tx->bssid, bssid, ETH_ALEN); 4113 p2p->after_scan_tx->len = len; 4114 p2p->after_scan_tx->wait_time = wait_time; 4115 os_memcpy(p2p->after_scan_tx + 1, buf, len); 4116 return 0; 4117 } 4118 4119 return p2p->cfg->send_action(p2p->cfg->cb_ctx, freq, dst, src, bssid, 4120 buf, len, wait_time); 4121} 4122 4123 4124void p2p_set_best_channels(struct p2p_data *p2p, int freq_24, int freq_5, 4125 int freq_overall) 4126{ 4127 p2p_dbg(p2p, "Best channel: 2.4 GHz: %d, 5 GHz: %d, overall: %d", 4128 freq_24, freq_5, freq_overall); 4129 p2p->best_freq_24 = freq_24; 4130 p2p->best_freq_5 = freq_5; 4131 p2p->best_freq_overall = freq_overall; 4132} 4133 4134 4135void p2p_set_own_freq_preference(struct p2p_data *p2p, int freq) 4136{ 4137 p2p_dbg(p2p, "Own frequency preference: %d MHz", freq); 4138 p2p->own_freq_preference = freq; 4139} 4140 4141 4142const u8 * p2p_get_go_neg_peer(struct p2p_data *p2p) 4143{ 4144 if (p2p == NULL || p2p->go_neg_peer == NULL) 4145 return NULL; 4146 return p2p->go_neg_peer->info.p2p_device_addr; 4147} 4148 4149 4150const struct p2p_peer_info * 4151p2p_get_peer_found(struct p2p_data *p2p, const u8 *addr, int next) 4152{ 4153 struct p2p_device *dev; 4154 4155 if (addr) { 4156 dev = p2p_get_device(p2p, addr); 4157 if (!dev) 4158 return NULL; 4159 4160 if (!next) { 4161 if (dev->flags & P2P_DEV_PROBE_REQ_ONLY) 4162 return NULL; 4163 4164 return &dev->info; 4165 } else { 4166 do { 4167 dev = dl_list_first(&dev->list, 4168 struct p2p_device, 4169 list); 4170 if (&dev->list == &p2p->devices) 4171 return NULL; 4172 } while (dev->flags & P2P_DEV_PROBE_REQ_ONLY); 4173 } 4174 } else { 4175 dev = dl_list_first(&p2p->devices, struct p2p_device, list); 4176 if (!dev) 4177 return NULL; 4178 while (dev->flags & P2P_DEV_PROBE_REQ_ONLY) { 4179 dev = dl_list_first(&dev->list, 4180 struct p2p_device, 4181 list); 4182 if (&dev->list == &p2p->devices) 4183 return NULL; 4184 } 4185 } 4186 4187 return &dev->info; 4188} 4189 4190 4191int p2p_in_progress(struct p2p_data *p2p) 4192{ 4193 if (p2p == NULL) 4194 return 0; 4195 if (p2p->state == P2P_SEARCH) 4196 return 2; 4197 return p2p->state != P2P_IDLE && p2p->state != P2P_PROVISIONING; 4198} 4199 4200 4201void p2p_set_config_timeout(struct p2p_data *p2p, u8 go_timeout, 4202 u8 client_timeout) 4203{ 4204 if (p2p) { 4205 p2p->go_timeout = go_timeout; 4206 p2p->client_timeout = client_timeout; 4207 } 4208} 4209 4210 4211#ifdef CONFIG_WIFI_DISPLAY 4212 4213static void p2p_update_wfd_ie_groups(struct p2p_data *p2p) 4214{ 4215 size_t g; 4216 struct p2p_group *group; 4217 4218 for (g = 0; g < p2p->num_groups; g++) { 4219 group = p2p->groups[g]; 4220 p2p_group_force_beacon_update_ies(group); 4221 } 4222} 4223 4224 4225int p2p_set_wfd_ie_beacon(struct p2p_data *p2p, struct wpabuf *ie) 4226{ 4227 wpabuf_free(p2p->wfd_ie_beacon); 4228 p2p->wfd_ie_beacon = ie; 4229 p2p_update_wfd_ie_groups(p2p); 4230 return 0; 4231} 4232 4233 4234int p2p_set_wfd_ie_probe_req(struct p2p_data *p2p, struct wpabuf *ie) 4235{ 4236 wpabuf_free(p2p->wfd_ie_probe_req); 4237 p2p->wfd_ie_probe_req = ie; 4238 return 0; 4239} 4240 4241 4242int p2p_set_wfd_ie_probe_resp(struct p2p_data *p2p, struct wpabuf *ie) 4243{ 4244 wpabuf_free(p2p->wfd_ie_probe_resp); 4245 p2p->wfd_ie_probe_resp = ie; 4246 p2p_update_wfd_ie_groups(p2p); 4247 return 0; 4248} 4249 4250 4251int p2p_set_wfd_ie_assoc_req(struct p2p_data *p2p, struct wpabuf *ie) 4252{ 4253 wpabuf_free(p2p->wfd_ie_assoc_req); 4254 p2p->wfd_ie_assoc_req = ie; 4255 return 0; 4256} 4257 4258 4259int p2p_set_wfd_ie_invitation(struct p2p_data *p2p, struct wpabuf *ie) 4260{ 4261 wpabuf_free(p2p->wfd_ie_invitation); 4262 p2p->wfd_ie_invitation = ie; 4263 return 0; 4264} 4265 4266 4267int p2p_set_wfd_ie_prov_disc_req(struct p2p_data *p2p, struct wpabuf *ie) 4268{ 4269 wpabuf_free(p2p->wfd_ie_prov_disc_req); 4270 p2p->wfd_ie_prov_disc_req = ie; 4271 return 0; 4272} 4273 4274 4275int p2p_set_wfd_ie_prov_disc_resp(struct p2p_data *p2p, struct wpabuf *ie) 4276{ 4277 wpabuf_free(p2p->wfd_ie_prov_disc_resp); 4278 p2p->wfd_ie_prov_disc_resp = ie; 4279 return 0; 4280} 4281 4282 4283int p2p_set_wfd_ie_go_neg(struct p2p_data *p2p, struct wpabuf *ie) 4284{ 4285 wpabuf_free(p2p->wfd_ie_go_neg); 4286 p2p->wfd_ie_go_neg = ie; 4287 return 0; 4288} 4289 4290 4291int p2p_set_wfd_dev_info(struct p2p_data *p2p, const struct wpabuf *elem) 4292{ 4293 wpabuf_free(p2p->wfd_dev_info); 4294 if (elem) { 4295 p2p->wfd_dev_info = wpabuf_dup(elem); 4296 if (p2p->wfd_dev_info == NULL) 4297 return -1; 4298 } else 4299 p2p->wfd_dev_info = NULL; 4300 4301 return 0; 4302} 4303 4304 4305int p2p_set_wfd_assoc_bssid(struct p2p_data *p2p, const struct wpabuf *elem) 4306{ 4307 wpabuf_free(p2p->wfd_assoc_bssid); 4308 if (elem) { 4309 p2p->wfd_assoc_bssid = wpabuf_dup(elem); 4310 if (p2p->wfd_assoc_bssid == NULL) 4311 return -1; 4312 } else 4313 p2p->wfd_assoc_bssid = NULL; 4314 4315 return 0; 4316} 4317 4318 4319int p2p_set_wfd_coupled_sink_info(struct p2p_data *p2p, 4320 const struct wpabuf *elem) 4321{ 4322 wpabuf_free(p2p->wfd_coupled_sink_info); 4323 if (elem) { 4324 p2p->wfd_coupled_sink_info = wpabuf_dup(elem); 4325 if (p2p->wfd_coupled_sink_info == NULL) 4326 return -1; 4327 } else 4328 p2p->wfd_coupled_sink_info = NULL; 4329 4330 return 0; 4331} 4332 4333#endif /* CONFIG_WIFI_DISPLAY */ 4334 4335 4336int p2p_set_disc_int(struct p2p_data *p2p, int min_disc_int, int max_disc_int, 4337 int max_disc_tu) 4338{ 4339 if (min_disc_int > max_disc_int || min_disc_int < 0 || max_disc_int < 0) 4340 return -1; 4341 4342 p2p->min_disc_int = min_disc_int; 4343 p2p->max_disc_int = max_disc_int; 4344 p2p->max_disc_tu = max_disc_tu; 4345 p2p_dbg(p2p, "Set discoverable interval: min=%d max=%d max_tu=%d", 4346 min_disc_int, max_disc_int, max_disc_tu); 4347 4348 return 0; 4349} 4350 4351 4352void p2p_dbg(struct p2p_data *p2p, const char *fmt, ...) 4353{ 4354 va_list ap; 4355 char buf[500]; 4356 4357 if (!p2p->cfg->debug_print) 4358 return; 4359 4360 va_start(ap, fmt); 4361 vsnprintf(buf, sizeof(buf), fmt, ap); 4362 buf[sizeof(buf) - 1] = '\0'; 4363 va_end(ap); 4364 p2p->cfg->debug_print(p2p->cfg->cb_ctx, MSG_DEBUG, buf); 4365} 4366 4367 4368void p2p_info(struct p2p_data *p2p, const char *fmt, ...) 4369{ 4370 va_list ap; 4371 char buf[500]; 4372 4373 if (!p2p->cfg->debug_print) 4374 return; 4375 4376 va_start(ap, fmt); 4377 vsnprintf(buf, sizeof(buf), fmt, ap); 4378 buf[sizeof(buf) - 1] = '\0'; 4379 va_end(ap); 4380 p2p->cfg->debug_print(p2p->cfg->cb_ctx, MSG_INFO, buf); 4381} 4382 4383 4384void p2p_err(struct p2p_data *p2p, const char *fmt, ...) 4385{ 4386 va_list ap; 4387 char buf[500]; 4388 4389 if (!p2p->cfg->debug_print) 4390 return; 4391 4392 va_start(ap, fmt); 4393 vsnprintf(buf, sizeof(buf), fmt, ap); 4394 buf[sizeof(buf) - 1] = '\0'; 4395 va_end(ap); 4396 p2p->cfg->debug_print(p2p->cfg->cb_ctx, MSG_ERROR, buf); 4397} 4398